@itwin/core-electron 3.4.0-dev.9 → 3.5.0-dev.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +23 -1
- package/lib/cjs/backend/ElectronHost.d.ts +2 -1
- package/lib/cjs/backend/ElectronHost.d.ts.map +1 -1
- package/lib/cjs/backend/ElectronHost.js +11 -3
- package/lib/cjs/backend/ElectronHost.js.map +1 -1
- package/lib/cjs/common/ElectronIpcTransport.d.ts +2 -0
- package/lib/cjs/common/ElectronIpcTransport.d.ts.map +1 -1
- package/lib/cjs/common/ElectronIpcTransport.js +12 -2
- package/lib/cjs/common/ElectronIpcTransport.js.map +1 -1
- package/lib/cjs/common/ElectronRpcManager.d.ts +3 -0
- package/lib/cjs/common/ElectronRpcManager.d.ts.map +1 -1
- package/lib/cjs/common/ElectronRpcManager.js +10 -0
- package/lib/cjs/common/ElectronRpcManager.js.map +1 -1
- package/lib/cjs/common/ElectronRpcRequest.d.ts.map +1 -1
- package/lib/cjs/common/ElectronRpcRequest.js +3 -1
- package/lib/cjs/common/ElectronRpcRequest.js.map +1 -1
- package/lib/cjs/frontend/ElectronApp.d.ts +0 -1
- package/lib/cjs/frontend/ElectronApp.d.ts.map +1 -1
- package/lib/cjs/frontend/ElectronApp.js +1 -0
- package/lib/cjs/frontend/ElectronApp.js.map +1 -1
- package/package.json +21 -16
package/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,28 @@
|
|
|
1
1
|
# Change Log - @itwin/core-electron
|
|
2
2
|
|
|
3
|
-
This log was last generated on
|
|
3
|
+
This log was last generated on Thu, 01 Sep 2022 14:37:22 GMT and should not be manually modified.
|
|
4
|
+
|
|
5
|
+
## 3.3.2
|
|
6
|
+
Thu, 01 Sep 2022 14:37:22 GMT
|
|
7
|
+
|
|
8
|
+
_Version update only_
|
|
9
|
+
|
|
10
|
+
## 3.3.1
|
|
11
|
+
Fri, 26 Aug 2022 15:40:02 GMT
|
|
12
|
+
|
|
13
|
+
_Version update only_
|
|
14
|
+
|
|
15
|
+
## 3.3.0
|
|
16
|
+
Thu, 18 Aug 2022 19:08:02 GMT
|
|
17
|
+
|
|
18
|
+
### Updates
|
|
19
|
+
|
|
20
|
+
- White-list APIs from dialog module.
|
|
21
|
+
|
|
22
|
+
## 3.2.9
|
|
23
|
+
Fri, 26 Aug 2022 14:21:40 GMT
|
|
24
|
+
|
|
25
|
+
_Version update only_
|
|
4
26
|
|
|
5
27
|
## 3.2.8
|
|
6
28
|
Tue, 09 Aug 2022 15:52:41 GMT
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { BrowserWindow, BrowserWindowConstructorOptions } from "electron";
|
|
2
2
|
import { IpcHandler, NativeHostOpts } from "@itwin/core-backend";
|
|
3
3
|
import { RpcConfiguration, RpcInterfaceDefinition } from "@itwin/core-common";
|
|
4
|
+
import * as ElectronModuleExports from "electron";
|
|
4
5
|
/**
|
|
5
6
|
* Options for [[ElectronHost.startup]]
|
|
6
7
|
* @beta
|
|
@@ -56,7 +57,7 @@ export declare class ElectronHost {
|
|
|
56
57
|
static rpcConfig: RpcConfiguration;
|
|
57
58
|
static get ipcMain(): Electron.IpcMain;
|
|
58
59
|
static get app(): Electron.App;
|
|
59
|
-
static get electron(): typeof
|
|
60
|
+
static get electron(): typeof ElectronModuleExports;
|
|
60
61
|
private constructor();
|
|
61
62
|
/**
|
|
62
63
|
* Converts an "electron://frontend/" URL to an absolute file path.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ElectronHost.d.ts","sourceRoot":"","sources":["../../../src/backend/ElectronHost.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,aAAa,EAAE,+BAA+B,EAAE,MAAM,UAAU,CAAC;AAI/E,OAAO,EAAE,UAAU,EAAuB,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACtF,OAAO,EAA8D,gBAAgB,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"ElectronHost.d.ts","sourceRoot":"","sources":["../../../src/backend/ElectronHost.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,aAAa,EAAE,+BAA+B,EAAE,MAAM,UAAU,CAAC;AAI/E,OAAO,EAAE,UAAU,EAAuB,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACtF,OAAO,EAA8D,gBAAgB,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAC;AAM1I,OAAO,KAAK,qBAAqB,MAAM,UAAU,CAAC;AAuBlD;;;GAGG;AACH,MAAM,WAAW,mBAAmB;IAClC,sCAAsC;IACtC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,oEAAoE;IACpE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,qCAAqC;IACrC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,2IAA2I;IAC3I,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,0DAA0D;IAC1D,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,oDAAoD;IACpD,aAAa,CAAC,EAAE,sBAAsB,EAAE,CAAC;IACzC,wDAAwD;IACxD,WAAW,CAAC,EAAE,CAAC,OAAO,UAAU,CAAC,EAAE,CAAC;CACrC;AAED,YAAY;AACZ,MAAM,WAAW,gBAAiB,SAAQ,cAAc;IACtD,YAAY,CAAC,EAAE,mBAAmB,CAAC;CACpC;AAED,YAAY;AACZ,MAAM,WAAW,yBAA0B,SAAQ,+BAA+B;IAChF,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,2DAA2D;IAC3D,aAAa,CAAC,EAAE,CAAC,SAAS,GAAG,QAAQ,GAAG,aAAa,GAAG,sBAAsB,CAAC,CAAC;CACjF;AAED;;GAEG;AACH,MAAM,WAAW,0BAA0B;IACzC,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;CACX;AAED;;;GAGG;AACH,qBAAa,YAAY;IACvB,OAAO,CAAC,MAAM,CAAC,IAAI,CAAc;IACjC,OAAO,CAAC,MAAM,CAAC,kBAAkB,CAAU;IAC3C,OAAO,CAAC,MAAM,CAAC,SAAS,CAA+B;IACvD,OAAO,CAAC,MAAM,CAAC,iBAAiB,CAA0B;IAC1D,OAAO,CAAC,MAAM,CAAC,WAAW,CAAC,CAAgB;IAC3C,OAAc,gBAAgB,EAAE,MAAM,CAAC;IACvC,OAAc,WAAW,EAAE,MAAM,CAAC;IAClC,OAAc,WAAW,EAAE,MAAM,CAAC;IAClC,OAAc,SAAS,EAAE,gBAAgB,CAAC;IAC1C,WAAkB,OAAO,qBAAsC;IAC/D,WAAkB,GAAG,iBAAkC;IACvD,WAAkB,QAAQ,iCAA6B;IAEvD,OAAO;IAEP;;;;;;OAMG;IACH,OAAO,CAAC,MAAM,CAAC,gBAAgB;IAmB/B,OAAO,CAAC,MAAM,CAAC,WAAW;IAuD1B,qDAAqD;IACrD,WAAkB,UAAU,8BAA+B;IAE3D,0FAA0F;WAC5E,oBAAoB,CAAC,UAAU,EAAE,MAAM,GAAG,0BAA0B,GAAG,SAAS;IAK9F,wFAAwF;WAC1E,yBAAyB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,GAAG,SAAS;IAIhF;;;OAGG;WACiB,cAAc,CAAC,aAAa,CAAC,EAAE,yBAAyB,GAAG,OAAO,CAAC,IAAI,CAAC;IAsC5F,WAAkB,OAAO,YAAsC;IAE/D;;;;;;OAMG;WACiB,OAAO,CAAC,IAAI,CAAC,EAAE,gBAAgB;CAmCpD"}
|
|
@@ -37,8 +37,8 @@ class ElectronIpc {
|
|
|
37
37
|
*/
|
|
38
38
|
class ElectronHost {
|
|
39
39
|
constructor() { }
|
|
40
|
-
static get ipcMain() { return this._electron.ipcMain; }
|
|
41
|
-
static get app() { return this._electron.app; }
|
|
40
|
+
static get ipcMain() { var _a; return (_a = this._electron) === null || _a === void 0 ? void 0 : _a.ipcMain; }
|
|
41
|
+
static get app() { var _a; return (_a = this._electron) === null || _a === void 0 ? void 0 : _a.app; }
|
|
42
42
|
static get electron() { return this._electron; }
|
|
43
43
|
/**
|
|
44
44
|
* Converts an "electron://frontend/" URL to an absolute file path.
|
|
@@ -112,6 +112,7 @@ class ElectronHost {
|
|
|
112
112
|
mainWindow.on("moved", () => saveWindowPosition());
|
|
113
113
|
mainWindow.on("maximize", () => saveMaximized(true));
|
|
114
114
|
mainWindow.on("unmaximize", () => saveMaximized(false));
|
|
115
|
+
saveMaximized(mainWindow.isMaximized());
|
|
115
116
|
}
|
|
116
117
|
}
|
|
117
118
|
/** The "main" BrowserWindow for this application. */
|
|
@@ -178,7 +179,14 @@ class ElectronHost {
|
|
|
178
179
|
this._ipc = new ElectronIpc();
|
|
179
180
|
const app = this.app;
|
|
180
181
|
if (!app.isReady())
|
|
181
|
-
this.electron.protocol.registerSchemesAsPrivileged([{
|
|
182
|
+
this.electron.protocol.registerSchemesAsPrivileged([{
|
|
183
|
+
scheme: "electron",
|
|
184
|
+
privileges: {
|
|
185
|
+
standard: true,
|
|
186
|
+
secure: true,
|
|
187
|
+
supportFetchAPI: true,
|
|
188
|
+
},
|
|
189
|
+
}]);
|
|
182
190
|
const eopt = opts === null || opts === void 0 ? void 0 : opts.electronHost;
|
|
183
191
|
this._developmentServer = (_a = eopt === null || eopt === void 0 ? void 0 : eopt.developmentServer) !== null && _a !== void 0 ? _a : false;
|
|
184
192
|
const frontendPort = (_b = eopt === null || eopt === void 0 ? void 0 : eopt.frontendPort) !== null && _b !== void 0 ? _b : 3000;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ElectronHost.js","sourceRoot":"","sources":["../../../src/backend/ElectronHost.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\r\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\r\n* See LICENSE.md in the project root for license terms and full copyright notice.\r\n*--------------------------------------------------------------------------------------------*/\r\n\r\n// Note: only import types! Does not create a `require(\"electron\")` in JavaScript after transpiling. That's important so this file can\r\n// be imported by apps that sometimes use Electron and sometimes not. Call to `ElectronBackend.initialize`\r\n// will do the necessary `require(\"electron\")`\r\n// IMPORTANT: Do not call or construct any of these imports. Otherwise, a require(\"electron\") call will be emitted at top level.\r\n// Instead, use `ElectronHost.electron.<type>`\r\n\r\nimport type { BrowserWindow, BrowserWindowConstructorOptions } from \"electron\";\r\nimport * as fs from \"fs\";\r\nimport * as path from \"path\";\r\nimport { BeDuration, IModelStatus, ProcessDetector } from \"@itwin/core-bentley\";\r\nimport { IpcHandler, IpcHost, NativeHost, NativeHostOpts } from \"@itwin/core-backend\";\r\nimport { IModelError, IpcListener, IpcSocketBackend, RemoveFunction, RpcConfiguration, RpcInterfaceDefinition } from \"@itwin/core-common\";\r\nimport { ElectronRpcConfiguration, ElectronRpcManager } from \"../common/ElectronRpcManager\";\r\nimport { DialogModuleMethod } from \"../common/ElectronIpcInterface\";\r\n\r\n// cSpell:ignore signin devserver webcontents copyfile unmaximize eopt\r\n\r\nclass ElectronIpc implements IpcSocketBackend {\r\n public addListener(channel: string, listener: IpcListener): RemoveFunction {\r\n ElectronHost.ipcMain.addListener(channel, listener);\r\n return () => ElectronHost.ipcMain.removeListener(channel, listener);\r\n }\r\n public removeListener(channel: string, listener: IpcListener) {\r\n ElectronHost.ipcMain.removeListener(channel, listener);\r\n }\r\n public send(channel: string, ...args: any[]): void {\r\n const window = ElectronHost.mainWindow ?? ElectronHost.electron.BrowserWindow.getAllWindows()[0];\r\n window?.webContents.send(channel, ...args);\r\n }\r\n public handle(channel: string, listener: (evt: any, ...args: any[]) => Promise<any>): RemoveFunction {\r\n ElectronHost.ipcMain.removeHandler(channel); // make sure there's not already a handler registered\r\n ElectronHost.ipcMain.handle(channel, listener);\r\n return () => ElectronHost.ipcMain.removeHandler(channel);\r\n }\r\n}\r\n\r\n/**\r\n * Options for [[ElectronHost.startup]]\r\n * @beta\r\n */\r\nexport interface ElectronHostOptions {\r\n /** the path to find web resources */\r\n webResourcesPath?: string;\r\n /** filename for the app's icon, relative to [[webResourcesPath]] */\r\n iconName?: string;\r\n /** name of frontend url to open. */\r\n frontendURL?: string;\r\n /** use a development server rather than the \"electron\" protocol for loading frontend (see https://www.electronjs.org/docs/api/protocol) */\r\n developmentServer?: boolean;\r\n /** port number for development server. Default is 3000 */\r\n frontendPort?: number;\r\n /** list of RPC interface definitions to register */\r\n rpcInterfaces?: RpcInterfaceDefinition[];\r\n /** list of [IpcHandler]($common) classes to register */\r\n ipcHandlers?: (typeof IpcHandler)[];\r\n}\r\n\r\n/** @beta */\r\nexport interface ElectronHostOpts extends NativeHostOpts {\r\n electronHost?: ElectronHostOptions;\r\n}\r\n\r\n/** @beta */\r\nexport interface ElectronHostWindowOptions extends BrowserWindowConstructorOptions {\r\n storeWindowName?: string;\r\n /** The style of window title bar. Default is `default`. */\r\n titleBarStyle?: (\"default\" | \"hidden\" | \"hiddenInset\" | \"customButtonsOnHover\");\r\n}\r\n\r\n/** the size and position of a window as stored in the settings file.\r\n * @beta\r\n */\r\nexport interface WindowSizeAndPositionProps {\r\n width: number;\r\n height: number;\r\n x: number;\r\n y: number;\r\n}\r\n\r\n/**\r\n * The backend for Electron-based desktop applications\r\n * @beta\r\n */\r\nexport class ElectronHost {\r\n private static _ipc: ElectronIpc;\r\n private static _developmentServer: boolean;\r\n private static _electron: typeof Electron;\r\n private static _electronFrontend = \"electron://frontend/\";\r\n private static _mainWindow?: BrowserWindow;\r\n public static webResourcesPath: string;\r\n public static appIconPath: string;\r\n public static frontendURL: string;\r\n public static rpcConfig: RpcConfiguration;\r\n public static get ipcMain() { return this._electron.ipcMain; }\r\n public static get app() { return this._electron.app; }\r\n public static get electron() { return this._electron; }\r\n\r\n private constructor() { }\r\n\r\n /**\r\n * Converts an \"electron://frontend/\" URL to an absolute file path.\r\n *\r\n * We use this protocol in production builds because our frontend must be built with absolute URLs,\r\n * however, since we're loading everything directly from the install directory, we cannot know the\r\n * absolute path at build time.\r\n */\r\n private static parseElectronUrl(requestedUrl: string): string {\r\n // Note that the \"frontend/\" path is arbitrary - this is just so we can handle *some* relative URLs...\r\n let assetPath = requestedUrl.substr(this._electronFrontend.length);\r\n if (assetPath.length === 0)\r\n assetPath = \"index.html\";\r\n assetPath = path.normalize(`${this.webResourcesPath}/${assetPath}`);\r\n // File protocols don't follow symlinks, so we need to resolve this to a real path.\r\n // However, if the file doesn't exist, it's fine to return an invalid path here - the request will just fail with net::ERR_FILE_NOT_FOUND\r\n try {\r\n assetPath = fs.realpathSync(assetPath);\r\n } catch (error) {\r\n // eslint-disable-next-line no-console\r\n // console.warn(`WARNING: Frontend requested \"${requestedUrl}\", but ${assetPath} does not exist`);\r\n }\r\n if (!assetPath.startsWith(this.webResourcesPath))\r\n throw new Error(`Access to files outside installation directory (${this.webResourcesPath}) is prohibited`);\r\n return assetPath;\r\n }\r\n\r\n private static _openWindow(options?: ElectronHostWindowOptions) {\r\n const opts: BrowserWindowConstructorOptions = {\r\n ...options,\r\n autoHideMenuBar: true,\r\n icon: this.appIconPath,\r\n webPreferences: {\r\n ...options?.webPreferences,\r\n\r\n // These web preference variables should not be overriden by the ElectronHostWindowOptions\r\n preload: require.resolve(/* webpack: copyfile */\"./ElectronPreload.js\"),\r\n experimentalFeatures: false,\r\n nodeIntegration: false,\r\n contextIsolation: true,\r\n sandbox: true,\r\n nativeWindowOpen: true,\r\n nodeIntegrationInWorker: false,\r\n nodeIntegrationInSubFrames: false,\r\n },\r\n };\r\n\r\n this._mainWindow = new (this.electron.BrowserWindow)(opts);\r\n ElectronRpcConfiguration.targetWindowId = this._mainWindow.id;\r\n this._mainWindow.on(\"closed\", () => this._mainWindow = undefined);\r\n this._mainWindow.loadURL(this.frontendURL); // eslint-disable-line @typescript-eslint/no-floating-promises\r\n\r\n /** Monitors and saves main window size, position and maximized state */\r\n if (options?.storeWindowName) {\r\n const mainWindow = this._mainWindow;\r\n const name = options.storeWindowName;\r\n const saveWindowPosition = () => {\r\n const resolution = mainWindow.getSize();\r\n const position = mainWindow.getPosition();\r\n const pos: WindowSizeAndPositionProps = {\r\n width: resolution[0],\r\n height: resolution[1],\r\n x: position[0],\r\n y: position[1],\r\n };\r\n NativeHost.settingsStore.setData(`windowPos-${name}`, JSON.stringify(pos));\r\n };\r\n const saveMaximized = (maximized: boolean) => {\r\n if (!maximized)\r\n saveWindowPosition();\r\n NativeHost.settingsStore.setData(`windowMaximized-${name}`, maximized);\r\n };\r\n\r\n mainWindow.on(\"resized\", () => saveWindowPosition());\r\n mainWindow.on(\"moved\", () => saveWindowPosition());\r\n mainWindow.on(\"maximize\", () => saveMaximized(true));\r\n mainWindow.on(\"unmaximize\", () => saveMaximized(false));\r\n }\r\n }\r\n\r\n /** The \"main\" BrowserWindow for this application. */\r\n public static get mainWindow() { return this._mainWindow; }\r\n\r\n /** Gets window size and position for a window, by name, from settings file, if present */\r\n public static getWindowSizeSetting(windowName: string): WindowSizeAndPositionProps | undefined {\r\n const saved = NativeHost.settingsStore.getString(`windowPos-${windowName}`);\r\n return saved ? JSON.parse(saved) as WindowSizeAndPositionProps : undefined;\r\n }\r\n\r\n /** Gets \"window maximized\" flag for a window, by name, from settings file if present */\r\n public static getWindowMaximizedSetting(windowName: string): boolean | undefined {\r\n return NativeHost.settingsStore.getBoolean(`windowMaximized-${windowName}`);\r\n }\r\n\r\n /**\r\n * Open the main Window when the app is ready.\r\n * @param windowOptions Options for constructing the main BrowserWindow. See: https://electronjs.org/docs/api/browser-window#new-browserwindowoptions\r\n */\r\n public static async openMainWindow(windowOptions?: ElectronHostWindowOptions): Promise<void> {\r\n const app = this.app;\r\n // quit the application when all windows are closed (unless we're running on MacOS)\r\n app.on(\"window-all-closed\", () => {\r\n if (process.platform !== \"darwin\")\r\n app.quit();\r\n });\r\n\r\n // re-open the main window if it was closed and the app is re-activated (this is the normal MacOS behavior)\r\n app.on(\"activate\", () => {\r\n if (!this._mainWindow)\r\n this._openWindow(windowOptions);\r\n });\r\n\r\n if (this._developmentServer) {\r\n // Occasionally, the electron backend may start before the webpack devserver has even started.\r\n // If this happens, we'll just retry and keep reloading the page.\r\n app.on(\"web-contents-created\", (_e, webcontents) => {\r\n webcontents.on(\"did-fail-load\", async (_event, errorCode, _errorDescription, _validatedURL, isMainFrame) => {\r\n // errorCode -102 is CONNECTION_REFUSED - see https://cs.chromium.org/chromium/src/net/base/net_error_list.h\r\n if (isMainFrame && errorCode === -102) {\r\n await BeDuration.wait(100);\r\n webcontents.reload();\r\n }\r\n });\r\n });\r\n }\r\n\r\n await app.whenReady();\r\n\r\n if (!this._developmentServer) {\r\n // handle any \"electron://\" requests and redirect them to \"file://\" URLs\r\n this.electron.protocol.registerFileProtocol(\"electron\", (request, callback) => callback(this.parseElectronUrl(request.url))); // eslint-disable-line @typescript-eslint/no-var-requires\r\n }\r\n\r\n this._openWindow(windowOptions);\r\n }\r\n\r\n public static get isValid() { return this._ipc !== undefined; }\r\n\r\n /**\r\n * Initialize the backend of an Electron app.\r\n * This method configures the backend for all of the inter-process communication (RPC and IPC) for an\r\n * Electron app. It should be called from your Electron main function.\r\n * @param opts Options that control aspects of your backend.\r\n * @note This method must only be called from the backend of an Electron app (i.e. when [ProcessDetector.isElectronAppBackend]($bentley) is `true`).\r\n */\r\n public static async startup(opts?: ElectronHostOpts) {\r\n if (!ProcessDetector.isElectronAppBackend)\r\n throw new Error(\"Not running under Electron\");\r\n\r\n if (!this.isValid) {\r\n this._electron = require(\"electron\");\r\n this._ipc = new ElectronIpc();\r\n const app = this.app;\r\n if (!app.isReady())\r\n this.electron.protocol.registerSchemesAsPrivileged([{ scheme: \"electron\", privileges: { standard: true, secure: true } }]);\r\n const eopt = opts?.electronHost;\r\n this._developmentServer = eopt?.developmentServer ?? false;\r\n const frontendPort = eopt?.frontendPort ?? 3000;\r\n this.webResourcesPath = eopt?.webResourcesPath ?? \"\";\r\n this.frontendURL = eopt?.frontendURL ?? (this._developmentServer ? `http://localhost:${frontendPort}` : `${this._electronFrontend}index.html`);\r\n this.appIconPath = path.join(this.webResourcesPath, eopt?.iconName ?? \"appicon.ico\");\r\n this.rpcConfig = ElectronRpcManager.initializeBackend(this._ipc, eopt?.rpcInterfaces);\r\n }\r\n\r\n opts = opts ?? {};\r\n opts.ipcHost = opts.ipcHost ?? {};\r\n opts.ipcHost.socket = this._ipc;\r\n await NativeHost.startup(opts);\r\n if (IpcHost.isValid) {\r\n ElectronAppHandler.register();\r\n opts.electronHost?.ipcHandlers?.forEach((ipc) => ipc.register());\r\n }\r\n }\r\n}\r\n\r\nclass ElectronAppHandler extends IpcHandler {\r\n public get channelName() { return \"electron-safe\"; }\r\n public async callElectron(member: string, method: string, ...args: any) {\r\n let allowedMethods: readonly string[] = [];\r\n if (member === \"dialog\") {\r\n const methods: DialogModuleMethod[] = [\"showMessageBox\", \"showOpenDialog\", \"showSaveDialog\"];\r\n allowedMethods = methods;\r\n }\r\n\r\n if (allowedMethods.indexOf(method) >= 0) {\r\n const electronMember = (ElectronHost.electron as any)[member];\r\n const func = electronMember[method];\r\n if (typeof func === \"function\") {\r\n return func.call(electronMember, ...args);\r\n }\r\n }\r\n\r\n throw new IModelError(IModelStatus.FunctionNotFound, `Method ${method} not found electron.${member}`);\r\n }\r\n}\r\n"]}
|
|
1
|
+
{"version":3,"file":"ElectronHost.js","sourceRoot":"","sources":["../../../src/backend/ElectronHost.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\r\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\r\n* See LICENSE.md in the project root for license terms and full copyright notice.\r\n*--------------------------------------------------------------------------------------------*/\r\n\r\n// Note: only import types! Does not create a `require(\"electron\")` in JavaScript after transpiling. That's important so this file can\r\n// be imported by apps that sometimes use Electron and sometimes not. Call to `ElectronBackend.initialize`\r\n// will do the necessary `require(\"electron\")`\r\n// IMPORTANT: Do not call or construct any of these imports. Otherwise, a require(\"electron\") call will be emitted at top level.\r\n// Instead, use `ElectronHost.electron.<type>`\r\n\r\nimport type { BrowserWindow, BrowserWindowConstructorOptions } from \"electron\";\r\nimport * as fs from \"fs\";\r\nimport * as path from \"path\";\r\nimport { BeDuration, IModelStatus, ProcessDetector } from \"@itwin/core-bentley\";\r\nimport { IpcHandler, IpcHost, NativeHost, NativeHostOpts } from \"@itwin/core-backend\";\r\nimport { IModelError, IpcListener, IpcSocketBackend, RemoveFunction, RpcConfiguration, RpcInterfaceDefinition } from \"@itwin/core-common\";\r\nimport { ElectronRpcConfiguration, ElectronRpcManager } from \"../common/ElectronRpcManager\";\r\nimport { DialogModuleMethod } from \"../common/ElectronIpcInterface\";\r\n\r\n// This will not be transpiled into JavaScript files as long as it isn't used for more than it's type definition.\r\n// See: https://www.typescriptlang.org/docs/handbook/modules.html#optional-module-loading-and-other-advanced-loading-scenarios\r\nimport * as ElectronModuleExports from \"electron\";\r\n\r\n// cSpell:ignore signin devserver webcontents copyfile unmaximize eopt\r\n\r\nclass ElectronIpc implements IpcSocketBackend {\r\n public addListener(channel: string, listener: IpcListener): RemoveFunction {\r\n ElectronHost.ipcMain.addListener(channel, listener);\r\n return () => ElectronHost.ipcMain.removeListener(channel, listener);\r\n }\r\n public removeListener(channel: string, listener: IpcListener) {\r\n ElectronHost.ipcMain.removeListener(channel, listener);\r\n }\r\n public send(channel: string, ...args: any[]): void {\r\n const window = ElectronHost.mainWindow ?? ElectronHost.electron.BrowserWindow.getAllWindows()[0];\r\n window?.webContents.send(channel, ...args);\r\n }\r\n public handle(channel: string, listener: (evt: any, ...args: any[]) => Promise<any>): RemoveFunction {\r\n ElectronHost.ipcMain.removeHandler(channel); // make sure there's not already a handler registered\r\n ElectronHost.ipcMain.handle(channel, listener);\r\n return () => ElectronHost.ipcMain.removeHandler(channel);\r\n }\r\n}\r\n\r\n/**\r\n * Options for [[ElectronHost.startup]]\r\n * @beta\r\n */\r\nexport interface ElectronHostOptions {\r\n /** the path to find web resources */\r\n webResourcesPath?: string;\r\n /** filename for the app's icon, relative to [[webResourcesPath]] */\r\n iconName?: string;\r\n /** name of frontend url to open. */\r\n frontendURL?: string;\r\n /** use a development server rather than the \"electron\" protocol for loading frontend (see https://www.electronjs.org/docs/api/protocol) */\r\n developmentServer?: boolean;\r\n /** port number for development server. Default is 3000 */\r\n frontendPort?: number;\r\n /** list of RPC interface definitions to register */\r\n rpcInterfaces?: RpcInterfaceDefinition[];\r\n /** list of [IpcHandler]($common) classes to register */\r\n ipcHandlers?: (typeof IpcHandler)[];\r\n}\r\n\r\n/** @beta */\r\nexport interface ElectronHostOpts extends NativeHostOpts {\r\n electronHost?: ElectronHostOptions;\r\n}\r\n\r\n/** @beta */\r\nexport interface ElectronHostWindowOptions extends BrowserWindowConstructorOptions {\r\n storeWindowName?: string;\r\n /** The style of window title bar. Default is `default`. */\r\n titleBarStyle?: (\"default\" | \"hidden\" | \"hiddenInset\" | \"customButtonsOnHover\");\r\n}\r\n\r\n/** the size and position of a window as stored in the settings file.\r\n * @beta\r\n */\r\nexport interface WindowSizeAndPositionProps {\r\n width: number;\r\n height: number;\r\n x: number;\r\n y: number;\r\n}\r\n\r\n/**\r\n * The backend for Electron-based desktop applications\r\n * @beta\r\n */\r\nexport class ElectronHost {\r\n private static _ipc: ElectronIpc;\r\n private static _developmentServer: boolean;\r\n private static _electron: typeof ElectronModuleExports;\r\n private static _electronFrontend = \"electron://frontend/\";\r\n private static _mainWindow?: BrowserWindow;\r\n public static webResourcesPath: string;\r\n public static appIconPath: string;\r\n public static frontendURL: string;\r\n public static rpcConfig: RpcConfiguration;\r\n public static get ipcMain() { return this._electron?.ipcMain; }\r\n public static get app() { return this._electron?.app; }\r\n public static get electron() { return this._electron; }\r\n\r\n private constructor() { }\r\n\r\n /**\r\n * Converts an \"electron://frontend/\" URL to an absolute file path.\r\n *\r\n * We use this protocol in production builds because our frontend must be built with absolute URLs,\r\n * however, since we're loading everything directly from the install directory, we cannot know the\r\n * absolute path at build time.\r\n */\r\n private static parseElectronUrl(requestedUrl: string): string {\r\n // Note that the \"frontend/\" path is arbitrary - this is just so we can handle *some* relative URLs...\r\n let assetPath = requestedUrl.substr(this._electronFrontend.length);\r\n if (assetPath.length === 0)\r\n assetPath = \"index.html\";\r\n assetPath = path.normalize(`${this.webResourcesPath}/${assetPath}`);\r\n // File protocols don't follow symlinks, so we need to resolve this to a real path.\r\n // However, if the file doesn't exist, it's fine to return an invalid path here - the request will just fail with net::ERR_FILE_NOT_FOUND\r\n try {\r\n assetPath = fs.realpathSync(assetPath);\r\n } catch (error) {\r\n // eslint-disable-next-line no-console\r\n // console.warn(`WARNING: Frontend requested \"${requestedUrl}\", but ${assetPath} does not exist`);\r\n }\r\n if (!assetPath.startsWith(this.webResourcesPath))\r\n throw new Error(`Access to files outside installation directory (${this.webResourcesPath}) is prohibited`);\r\n return assetPath;\r\n }\r\n\r\n private static _openWindow(options?: ElectronHostWindowOptions) {\r\n const opts: BrowserWindowConstructorOptions = {\r\n ...options,\r\n autoHideMenuBar: true,\r\n icon: this.appIconPath,\r\n webPreferences: {\r\n ...options?.webPreferences,\r\n\r\n // These web preference variables should not be overriden by the ElectronHostWindowOptions\r\n preload: require.resolve(/* webpack: copyfile */\"./ElectronPreload.js\"),\r\n experimentalFeatures: false,\r\n nodeIntegration: false,\r\n contextIsolation: true,\r\n sandbox: true,\r\n nativeWindowOpen: true,\r\n nodeIntegrationInWorker: false,\r\n nodeIntegrationInSubFrames: false,\r\n },\r\n };\r\n\r\n this._mainWindow = new (this.electron.BrowserWindow)(opts);\r\n ElectronRpcConfiguration.targetWindowId = this._mainWindow.id;\r\n this._mainWindow.on(\"closed\", () => this._mainWindow = undefined);\r\n this._mainWindow.loadURL(this.frontendURL); // eslint-disable-line @typescript-eslint/no-floating-promises\r\n\r\n /** Monitors and saves main window size, position and maximized state */\r\n if (options?.storeWindowName) {\r\n const mainWindow = this._mainWindow;\r\n const name = options.storeWindowName;\r\n const saveWindowPosition = () => {\r\n const resolution = mainWindow.getSize();\r\n const position = mainWindow.getPosition();\r\n const pos: WindowSizeAndPositionProps = {\r\n width: resolution[0],\r\n height: resolution[1],\r\n x: position[0],\r\n y: position[1],\r\n };\r\n NativeHost.settingsStore.setData(`windowPos-${name}`, JSON.stringify(pos));\r\n };\r\n const saveMaximized = (maximized: boolean) => {\r\n if (!maximized)\r\n saveWindowPosition();\r\n NativeHost.settingsStore.setData(`windowMaximized-${name}`, maximized);\r\n };\r\n\r\n mainWindow.on(\"resized\", () => saveWindowPosition());\r\n mainWindow.on(\"moved\", () => saveWindowPosition());\r\n mainWindow.on(\"maximize\", () => saveMaximized(true));\r\n mainWindow.on(\"unmaximize\", () => saveMaximized(false));\r\n\r\n saveMaximized(mainWindow.isMaximized());\r\n }\r\n }\r\n\r\n /** The \"main\" BrowserWindow for this application. */\r\n public static get mainWindow() { return this._mainWindow; }\r\n\r\n /** Gets window size and position for a window, by name, from settings file, if present */\r\n public static getWindowSizeSetting(windowName: string): WindowSizeAndPositionProps | undefined {\r\n const saved = NativeHost.settingsStore.getString(`windowPos-${windowName}`);\r\n return saved ? JSON.parse(saved) as WindowSizeAndPositionProps : undefined;\r\n }\r\n\r\n /** Gets \"window maximized\" flag for a window, by name, from settings file if present */\r\n public static getWindowMaximizedSetting(windowName: string): boolean | undefined {\r\n return NativeHost.settingsStore.getBoolean(`windowMaximized-${windowName}`);\r\n }\r\n\r\n /**\r\n * Open the main Window when the app is ready.\r\n * @param windowOptions Options for constructing the main BrowserWindow. See: https://electronjs.org/docs/api/browser-window#new-browserwindowoptions\r\n */\r\n public static async openMainWindow(windowOptions?: ElectronHostWindowOptions): Promise<void> {\r\n const app = this.app;\r\n // quit the application when all windows are closed (unless we're running on MacOS)\r\n app.on(\"window-all-closed\", () => {\r\n if (process.platform !== \"darwin\")\r\n app.quit();\r\n });\r\n\r\n // re-open the main window if it was closed and the app is re-activated (this is the normal MacOS behavior)\r\n app.on(\"activate\", () => {\r\n if (!this._mainWindow)\r\n this._openWindow(windowOptions);\r\n });\r\n\r\n if (this._developmentServer) {\r\n // Occasionally, the electron backend may start before the webpack devserver has even started.\r\n // If this happens, we'll just retry and keep reloading the page.\r\n app.on(\"web-contents-created\", (_e, webcontents) => {\r\n webcontents.on(\"did-fail-load\", async (_event, errorCode, _errorDescription, _validatedURL, isMainFrame) => {\r\n // errorCode -102 is CONNECTION_REFUSED - see https://cs.chromium.org/chromium/src/net/base/net_error_list.h\r\n if (isMainFrame && errorCode === -102) {\r\n await BeDuration.wait(100);\r\n webcontents.reload();\r\n }\r\n });\r\n });\r\n }\r\n\r\n await app.whenReady();\r\n\r\n if (!this._developmentServer) {\r\n // handle any \"electron://\" requests and redirect them to \"file://\" URLs\r\n this.electron.protocol.registerFileProtocol(\"electron\", (request, callback) => callback(this.parseElectronUrl(request.url))); // eslint-disable-line @typescript-eslint/no-var-requires\r\n }\r\n\r\n this._openWindow(windowOptions);\r\n }\r\n\r\n public static get isValid() { return this._ipc !== undefined; }\r\n\r\n /**\r\n * Initialize the backend of an Electron app.\r\n * This method configures the backend for all of the inter-process communication (RPC and IPC) for an\r\n * Electron app. It should be called from your Electron main function.\r\n * @param opts Options that control aspects of your backend.\r\n * @note This method must only be called from the backend of an Electron app (i.e. when [ProcessDetector.isElectronAppBackend]($bentley) is `true`).\r\n */\r\n public static async startup(opts?: ElectronHostOpts) {\r\n if (!ProcessDetector.isElectronAppBackend)\r\n throw new Error(\"Not running under Electron\");\r\n\r\n if (!this.isValid) {\r\n this._electron = require(\"electron\");\r\n this._ipc = new ElectronIpc();\r\n const app = this.app;\r\n if (!app.isReady())\r\n this.electron.protocol.registerSchemesAsPrivileged([{\r\n scheme: \"electron\",\r\n privileges: {\r\n standard: true,\r\n secure: true,\r\n supportFetchAPI: true,\r\n },\r\n }]);\r\n const eopt = opts?.electronHost;\r\n this._developmentServer = eopt?.developmentServer ?? false;\r\n const frontendPort = eopt?.frontendPort ?? 3000;\r\n this.webResourcesPath = eopt?.webResourcesPath ?? \"\";\r\n this.frontendURL = eopt?.frontendURL ?? (this._developmentServer ? `http://localhost:${frontendPort}` : `${this._electronFrontend}index.html`);\r\n this.appIconPath = path.join(this.webResourcesPath, eopt?.iconName ?? \"appicon.ico\");\r\n this.rpcConfig = ElectronRpcManager.initializeBackend(this._ipc, eopt?.rpcInterfaces);\r\n }\r\n\r\n opts = opts ?? {};\r\n opts.ipcHost = opts.ipcHost ?? {};\r\n opts.ipcHost.socket = this._ipc;\r\n await NativeHost.startup(opts);\r\n if (IpcHost.isValid) {\r\n ElectronAppHandler.register();\r\n opts.electronHost?.ipcHandlers?.forEach((ipc) => ipc.register());\r\n }\r\n }\r\n}\r\n\r\nclass ElectronAppHandler extends IpcHandler {\r\n public get channelName() { return \"electron-safe\"; }\r\n public async callElectron(member: string, method: string, ...args: any) {\r\n let allowedMethods: readonly string[] = [];\r\n if (member === \"dialog\") {\r\n const methods: DialogModuleMethod[] = [\"showMessageBox\", \"showOpenDialog\", \"showSaveDialog\"];\r\n allowedMethods = methods;\r\n }\r\n\r\n if (allowedMethods.indexOf(method) >= 0) {\r\n const electronMember = (ElectronHost.electron as any)[member];\r\n const func = electronMember[method];\r\n if (typeof func === \"function\") {\r\n return func.call(electronMember, ...args);\r\n }\r\n }\r\n\r\n throw new IModelError(IModelStatus.FunctionNotFound, `Method ${method} not found electron.${member}`);\r\n }\r\n}\r\n"]}
|
|
@@ -9,6 +9,7 @@ export interface IpcTransportMessage {
|
|
|
9
9
|
/** @internal */
|
|
10
10
|
export declare abstract class ElectronIpcTransport<TIn extends IpcTransportMessage = IpcTransportMessage, TOut extends IpcTransportMessage = IpcTransportMessage> {
|
|
11
11
|
private _partials;
|
|
12
|
+
private _removeListeners;
|
|
12
13
|
protected _protocol: ElectronRpcProtocol;
|
|
13
14
|
get protocol(): ElectronRpcProtocol;
|
|
14
15
|
sendRequest(request: SerializedRpcRequest): void;
|
|
@@ -23,6 +24,7 @@ export declare abstract class ElectronIpcTransport<TIn extends IpcTransportMessa
|
|
|
23
24
|
/** @internal */
|
|
24
25
|
sendResponse(message: TOut, evt: any): void;
|
|
25
26
|
protected loadMessage(id: string): TIn;
|
|
27
|
+
cleanup(): void;
|
|
26
28
|
}
|
|
27
29
|
/** @internal */
|
|
28
30
|
export declare class FrontendIpcTransport extends ElectronIpcTransport<RpcRequestFulfillment> {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ElectronIpcTransport.d.ts","sourceRoot":"","sources":["../../../src/common/ElectronIpcTransport.ts"],"names":[],"mappings":"AAMA,OAAO,EACyD,qBAAqB,EAAE,kBAAkB,EAAE,oBAAoB,EAC9H,MAAM,oBAAoB,CAAC;AAG5B,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAQ5D,gBAAgB;AAChB,MAAM,WAAW,mBAAmB;IAAG,EAAE,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,kBAAkB,CAAC;IAAC,MAAM,CAAC,EAAE,kBAAkB,CAAA;CAAE;AAEjH,gBAAgB;AAChB,8BAAsB,oBAAoB,CAAC,GAAG,SAAS,mBAAmB,GAAG,mBAAmB,EAAE,IAAI,SAAS,mBAAmB,GAAG,mBAAmB;IACtJ,OAAO,CAAC,SAAS,CAAqE;IACtF,SAAS,CAAC,SAAS,EAAE,mBAAmB,CAAC;IAEzC,IAAW,QAAQ,wBAA6B;IAEzC,WAAW,CAAC,OAAO,EAAE,oBAAoB;gBAK7B,QAAQ,EAAE,mBAAmB;IAQhD,SAAS,CAAC,SAAS;IAEnB,OAAO,CAAC,iBAAiB;
|
|
1
|
+
{"version":3,"file":"ElectronIpcTransport.d.ts","sourceRoot":"","sources":["../../../src/common/ElectronIpcTransport.ts"],"names":[],"mappings":"AAMA,OAAO,EACyD,qBAAqB,EAAE,kBAAkB,EAAE,oBAAoB,EAC9H,MAAM,oBAAoB,CAAC;AAG5B,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAQ5D,gBAAgB;AAChB,MAAM,WAAW,mBAAmB;IAAG,EAAE,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,kBAAkB,CAAC;IAAC,MAAM,CAAC,EAAE,kBAAkB,CAAA;CAAE;AAEjH,gBAAgB;AAChB,8BAAsB,oBAAoB,CAAC,GAAG,SAAS,mBAAmB,GAAG,mBAAmB,EAAE,IAAI,SAAS,mBAAmB,GAAG,mBAAmB;IACtJ,OAAO,CAAC,SAAS,CAAqE;IACtF,OAAO,CAAC,gBAAgB,CAAsB;IAC9C,SAAS,CAAC,SAAS,EAAE,mBAAmB,CAAC;IAEzC,IAAW,QAAQ,wBAA6B;IAEzC,WAAW,CAAC,OAAO,EAAE,oBAAoB;gBAK7B,QAAQ,EAAE,mBAAmB;IAQhD,SAAS,CAAC,SAAS;IAEnB,OAAO,CAAC,iBAAiB;IAwBzB,OAAO,CAAC,oBAAoB;IAyB5B,OAAO,CAAC,aAAa;IAYrB,OAAO,CAAC,KAAK;IAeb,SAAS,CAAC,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG;IAI7D,SAAS,CAAC,QAAQ,CAAC,cAAc,CAAC,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,GAAG,GAAG,IAAI;IAE7D,gBAAgB;IACT,YAAY,CAAC,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG;IAK3C,SAAS,CAAC,WAAW,CAAC,EAAE,EAAE,MAAM;IAUzB,OAAO;CAGf;AAED,gBAAgB;AAChB,qBAAa,oBAAqB,SAAQ,oBAAoB,CAAC,qBAAqB,CAAC;IACnF,OAAO,CAAC,cAAc,CAAC,CAAwB;cAE5B,SAAS;cAMZ,cAAc,CAAC,EAAE,EAAE,MAAM;CAW1C;AAED,gBAAgB;AAChB,qBAAa,mBAAoB,SAAQ,oBAAoB,CAAC,oBAAoB,EAAE,qBAAqB,CAAC;IACxG,OAAO,CAAC,cAAc,CAAM;cAET,SAAS;cAKZ,cAAc,CAAC,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,GAAG;cAiBhC,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG;IAWtE,OAAO,CAAC,qBAAqB;CAW9B;AAID,gBAAgB;AAChB,wBAAgB,aAAa,CAAC,QAAQ,EAAE,mBAAmB,kEAU1D"}
|
|
@@ -14,6 +14,7 @@ const DATA_CHANNEL = (0, core_common_1.iTwinChannel)("rpc.data");
|
|
|
14
14
|
/** @internal */
|
|
15
15
|
class ElectronIpcTransport {
|
|
16
16
|
constructor(protocol) {
|
|
17
|
+
this._removeListeners = [];
|
|
17
18
|
this._protocol = protocol;
|
|
18
19
|
this._partials = new Map();
|
|
19
20
|
this._setupDataChannel();
|
|
@@ -27,7 +28,7 @@ class ElectronIpcTransport {
|
|
|
27
28
|
}
|
|
28
29
|
setupPush() { }
|
|
29
30
|
_setupDataChannel() {
|
|
30
|
-
this.protocol.ipcSocket.addListener(DATA_CHANNEL, async (evt, chunk) => {
|
|
31
|
+
const removeListener = this.protocol.ipcSocket.addListener(DATA_CHANNEL, async (evt, chunk) => {
|
|
31
32
|
let pending = this._partials.get(chunk.id);
|
|
32
33
|
if (!pending) {
|
|
33
34
|
pending = [];
|
|
@@ -45,9 +46,10 @@ class ElectronIpcTransport {
|
|
|
45
46
|
}
|
|
46
47
|
}
|
|
47
48
|
});
|
|
49
|
+
this._removeListeners.push(removeListener);
|
|
48
50
|
}
|
|
49
51
|
_setupObjectsChannel() {
|
|
50
|
-
this.protocol.ipcSocket.addListener(OBJECTS_CHANNEL, async (evt, message) => {
|
|
52
|
+
const removeListener = this.protocol.ipcSocket.addListener(OBJECTS_CHANNEL, async (evt, message) => {
|
|
51
53
|
const pending = this._partials.get(message.id);
|
|
52
54
|
if (pending && !Array.isArray(pending)) {
|
|
53
55
|
throw new core_common_1.IModelError(core_bentley_1.BentleyStatus.ERROR, `Message already received for id "${message.id}".`);
|
|
@@ -65,6 +67,7 @@ class ElectronIpcTransport {
|
|
|
65
67
|
this.handleComplete(message.id, evt);
|
|
66
68
|
}
|
|
67
69
|
});
|
|
70
|
+
this._removeListeners.push(removeListener);
|
|
68
71
|
}
|
|
69
72
|
_extractValue(t) {
|
|
70
73
|
if (t.parameters) {
|
|
@@ -103,6 +106,9 @@ class ElectronIpcTransport {
|
|
|
103
106
|
this._partials.delete(id);
|
|
104
107
|
return partial.message;
|
|
105
108
|
}
|
|
109
|
+
cleanup() {
|
|
110
|
+
this._removeListeners.forEach((removeListener) => removeListener());
|
|
111
|
+
}
|
|
106
112
|
}
|
|
107
113
|
exports.ElectronIpcTransport = ElectronIpcTransport;
|
|
108
114
|
/** @internal */
|
|
@@ -169,6 +175,10 @@ exports.BackendIpcTransport = BackendIpcTransport;
|
|
|
169
175
|
let transport;
|
|
170
176
|
/** @internal */
|
|
171
177
|
function initializeIpc(protocol) {
|
|
178
|
+
if (transport && transport.protocol !== protocol) {
|
|
179
|
+
transport.cleanup();
|
|
180
|
+
transport = undefined;
|
|
181
|
+
}
|
|
172
182
|
if (undefined === transport)
|
|
173
183
|
transport = core_bentley_1.ProcessDetector.isElectronAppFrontend ? new FrontendIpcTransport(protocol) : new BackendIpcTransport(protocol);
|
|
174
184
|
return transport;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ElectronIpcTransport.js","sourceRoot":"","sources":["../../../src/common/ElectronIpcTransport.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\r\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\r\n* See LICENSE.md in the project root for license terms and full copyright notice.\r\n*--------------------------------------------------------------------------------------------*/\r\n\r\nimport { BentleyError, BentleyStatus, ProcessDetector } from \"@itwin/core-bentley\";\r\nimport {\r\n IModelError, iTwinChannel, RpcPushChannel, RpcPushConnection, RpcRequestFulfillment, RpcSerializedValue, SerializedRpcRequest,\r\n} from \"@itwin/core-common\";\r\nimport { ElectronPushConnection, ElectronPushTransport } from \"./ElectronPush\";\r\nimport { ElectronRpcConfiguration } from \"./ElectronRpcManager\";\r\nimport { ElectronRpcProtocol } from \"./ElectronRpcProtocol\";\r\nimport { ElectronRpcRequest } from \"./ElectronRpcRequest\";\r\n\r\nconst OBJECTS_CHANNEL = iTwinChannel(\"rpc.objects\");\r\nconst DATA_CHANNEL = iTwinChannel(\"rpc.data\");\r\n\r\ninterface PartialPayload { id: string, index: number, data: Uint8Array }\r\n\r\n/** @internal */\r\nexport interface IpcTransportMessage { id: string, parameters?: RpcSerializedValue, result?: RpcSerializedValue }\r\n\r\n/** @internal */\r\nexport abstract class ElectronIpcTransport<TIn extends IpcTransportMessage = IpcTransportMessage, TOut extends IpcTransportMessage = IpcTransportMessage> {\r\n private _partials: Map<string, { message: TIn, received: number } | PartialPayload[]>;\r\n protected _protocol: ElectronRpcProtocol;\r\n\r\n public get protocol() { return this._protocol; }\r\n\r\n public sendRequest(request: SerializedRpcRequest) {\r\n const value = this._extractValue(request);\r\n this._send(request, value);\r\n }\r\n\r\n public constructor(protocol: ElectronRpcProtocol) {\r\n this._protocol = protocol;\r\n this._partials = new Map();\r\n this._setupDataChannel();\r\n this._setupObjectsChannel();\r\n this.setupPush();\r\n }\r\n\r\n protected setupPush() { }\r\n\r\n private _setupDataChannel() {\r\n this.protocol.ipcSocket.addListener(DATA_CHANNEL, async (evt: any, chunk: PartialPayload) => {\r\n let pending = this._partials.get(chunk.id);\r\n if (!pending) {\r\n pending = [];\r\n this._partials.set(chunk.id, pending);\r\n }\r\n\r\n if (Array.isArray(pending)) {\r\n pending.push(chunk);\r\n } else {\r\n ++pending.received;\r\n\r\n const value = this._extractValue(pending.message);\r\n value.data[chunk.index] = chunk.data;\r\n\r\n if (pending.received === (value.chunks || 0)) {\r\n this.handleComplete(pending.message.id, evt);\r\n }\r\n }\r\n });\r\n }\r\n\r\n private _setupObjectsChannel() {\r\n this.protocol.ipcSocket.addListener(OBJECTS_CHANNEL, async (evt: any, message: TIn) => {\r\n const pending = this._partials.get(message.id);\r\n if (pending && !Array.isArray(pending)) {\r\n throw new IModelError(BentleyStatus.ERROR, `Message already received for id \"${message.id}\".`);\r\n }\r\n\r\n const partial = { message, received: 0 };\r\n this._partials.set(message.id, partial);\r\n const value = this._extractValue(partial.message);\r\n\r\n if (pending && Array.isArray(pending)) {\r\n for (const chunk of pending) {\r\n ++partial.received;\r\n value.data[chunk.index] = chunk.data;\r\n }\r\n }\r\n\r\n if (partial.received === (value.chunks || 0)) {\r\n this.handleComplete(message.id, evt);\r\n }\r\n });\r\n }\r\n\r\n private _extractValue(t: IpcTransportMessage): RpcSerializedValue {\r\n if (t.parameters) {\r\n return t.parameters;\r\n }\r\n\r\n if (t.result) {\r\n return t.result;\r\n }\r\n\r\n throw new IModelError(BentleyStatus.ERROR, \"Unknown value type.\");\r\n }\r\n\r\n private _send(message: IpcTransportMessage, value: RpcSerializedValue, evt?: any) {\r\n const chunks = value.data;\r\n if (chunks.length) {\r\n value.chunks = chunks.length;\r\n value.data = [];\r\n }\r\n\r\n this.performSend(OBJECTS_CHANNEL, message, evt);\r\n\r\n for (let index = 0; index !== chunks.length; ++index) {\r\n const chunk: PartialPayload = { id: message.id, index, data: chunks[index] };\r\n this.performSend(DATA_CHANNEL, chunk, evt);\r\n }\r\n }\r\n\r\n protected performSend(channel: string, message: any, evt: any) {\r\n (evt ? evt.sender : this.protocol.ipcSocket).send(channel, message);\r\n }\r\n\r\n protected abstract handleComplete(id: string, evt: any): void;\r\n\r\n /** @internal */\r\n public sendResponse(message: TOut, evt: any) {\r\n const value = this._extractValue(message);\r\n this._send(message, value, evt);\r\n }\r\n\r\n protected loadMessage(id: string) {\r\n const partial = this._partials.get(id);\r\n if (!partial || Array.isArray(partial)) {\r\n throw new IModelError(BentleyStatus.ERROR, `Incomplete transmission for id \"${id}\".`);\r\n }\r\n\r\n this._partials.delete(id);\r\n return partial.message;\r\n }\r\n}\r\n\r\n/** @internal */\r\nexport class FrontendIpcTransport extends ElectronIpcTransport<RpcRequestFulfillment> {\r\n private _pushTransport?: ElectronPushTransport;\r\n\r\n protected override setupPush() {\r\n const pushTransport = new ElectronPushTransport(this);\r\n this._pushTransport = pushTransport;\r\n RpcPushChannel.setup(pushTransport);\r\n }\r\n\r\n protected async handleComplete(id: string) {\r\n const message = this.loadMessage(id);\r\n\r\n if (this._pushTransport && this._pushTransport.consume(message)) {\r\n return;\r\n }\r\n\r\n const protocol = this._protocol;\r\n const request = protocol.requests.get(message.id) as ElectronRpcRequest;\r\n request.notifyResponse(message);\r\n }\r\n}\r\n\r\n/** @internal */\r\nexport class BackendIpcTransport extends ElectronIpcTransport<SerializedRpcRequest, RpcRequestFulfillment> {\r\n private _browserWindow: any;\r\n\r\n protected override setupPush() {\r\n RpcPushConnection.for = (channel, client) => new ElectronPushConnection(channel, client, this);\r\n RpcPushChannel.enabled = true;\r\n }\r\n\r\n protected async handleComplete(id: string, evt: any) {\r\n const message = this.loadMessage(id);\r\n\r\n let response: RpcRequestFulfillment;\r\n try {\r\n const protocol = this._protocol;\r\n response = await protocol.fulfill(message);\r\n } catch (err) {\r\n response = await RpcRequestFulfillment.forUnknownError(message, err);\r\n }\r\n\r\n const raw = response.rawResult;\r\n response.rawResult = undefined; // Otherwise, it will be serialized in IPC layer and large responses will then crash the app\r\n this.sendResponse(response, evt);\r\n response.rawResult = raw;\r\n }\r\n\r\n protected override performSend(channel: string, message: any, evt: any) {\r\n if (evt) {\r\n return super.performSend(channel, message, evt);\r\n }\r\n\r\n this._requireBrowserWindow();\r\n const target = ElectronRpcConfiguration.targetWindowId;\r\n const windows = target ? [this._browserWindow.fromId(target)] : this._browserWindow.getAllWindows();\r\n windows.forEach((window: any) => window.webContents.send(channel, message));\r\n }\r\n\r\n private _requireBrowserWindow() {\r\n if (this._browserWindow) {\r\n return;\r\n }\r\n\r\n try { // Wrapping require in a try/catch signals to webpack that this is only an optional dependency\r\n this._browserWindow = require(\"electron\").BrowserWindow; // eslint-disable-line @typescript-eslint/no-var-requires\r\n } catch (err) {\r\n throw new IModelError(BentleyStatus.ERROR, `Error requiring electron`, () => BentleyError.getErrorProps(err));\r\n }\r\n }\r\n}\r\n\r\nlet transport: ElectronIpcTransport | undefined;\r\n\r\n/** @internal */\r\nexport function initializeIpc(protocol: ElectronRpcProtocol) {\r\n if (undefined === transport)\r\n transport = ProcessDetector.isElectronAppFrontend ? new FrontendIpcTransport(protocol) : new BackendIpcTransport(protocol);\r\n return transport;\r\n}\r\n"]}
|
|
1
|
+
{"version":3,"file":"ElectronIpcTransport.js","sourceRoot":"","sources":["../../../src/common/ElectronIpcTransport.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\r\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\r\n* See LICENSE.md in the project root for license terms and full copyright notice.\r\n*--------------------------------------------------------------------------------------------*/\r\n\r\nimport { BentleyError, BentleyStatus, ProcessDetector } from \"@itwin/core-bentley\";\r\nimport {\r\n IModelError, iTwinChannel, RpcPushChannel, RpcPushConnection, RpcRequestFulfillment, RpcSerializedValue, SerializedRpcRequest,\r\n} from \"@itwin/core-common\";\r\nimport { ElectronPushConnection, ElectronPushTransport } from \"./ElectronPush\";\r\nimport { ElectronRpcConfiguration } from \"./ElectronRpcManager\";\r\nimport { ElectronRpcProtocol } from \"./ElectronRpcProtocol\";\r\nimport { ElectronRpcRequest } from \"./ElectronRpcRequest\";\r\n\r\nconst OBJECTS_CHANNEL = iTwinChannel(\"rpc.objects\");\r\nconst DATA_CHANNEL = iTwinChannel(\"rpc.data\");\r\n\r\ninterface PartialPayload { id: string, index: number, data: Uint8Array }\r\n\r\n/** @internal */\r\nexport interface IpcTransportMessage { id: string, parameters?: RpcSerializedValue, result?: RpcSerializedValue }\r\n\r\n/** @internal */\r\nexport abstract class ElectronIpcTransport<TIn extends IpcTransportMessage = IpcTransportMessage, TOut extends IpcTransportMessage = IpcTransportMessage> {\r\n private _partials: Map<string, { message: TIn, received: number } | PartialPayload[]>;\r\n private _removeListeners: VoidFunction[] = [];\r\n protected _protocol: ElectronRpcProtocol;\r\n\r\n public get protocol() { return this._protocol; }\r\n\r\n public sendRequest(request: SerializedRpcRequest) {\r\n const value = this._extractValue(request);\r\n this._send(request, value);\r\n }\r\n\r\n public constructor(protocol: ElectronRpcProtocol) {\r\n this._protocol = protocol;\r\n this._partials = new Map();\r\n this._setupDataChannel();\r\n this._setupObjectsChannel();\r\n this.setupPush();\r\n }\r\n\r\n protected setupPush() { }\r\n\r\n private _setupDataChannel() {\r\n const removeListener = this.protocol.ipcSocket.addListener(DATA_CHANNEL, async (evt: any, chunk: PartialPayload) => {\r\n let pending = this._partials.get(chunk.id);\r\n if (!pending) {\r\n pending = [];\r\n this._partials.set(chunk.id, pending);\r\n }\r\n\r\n if (Array.isArray(pending)) {\r\n pending.push(chunk);\r\n } else {\r\n ++pending.received;\r\n\r\n const value = this._extractValue(pending.message);\r\n value.data[chunk.index] = chunk.data;\r\n\r\n if (pending.received === (value.chunks || 0)) {\r\n this.handleComplete(pending.message.id, evt);\r\n }\r\n }\r\n });\r\n this._removeListeners.push(removeListener);\r\n }\r\n\r\n private _setupObjectsChannel() {\r\n const removeListener = this.protocol.ipcSocket.addListener(OBJECTS_CHANNEL, async (evt: any, message: TIn) => {\r\n const pending = this._partials.get(message.id);\r\n if (pending && !Array.isArray(pending)) {\r\n throw new IModelError(BentleyStatus.ERROR, `Message already received for id \"${message.id}\".`);\r\n }\r\n\r\n const partial = { message, received: 0 };\r\n this._partials.set(message.id, partial);\r\n const value = this._extractValue(partial.message);\r\n\r\n if (pending && Array.isArray(pending)) {\r\n for (const chunk of pending) {\r\n ++partial.received;\r\n value.data[chunk.index] = chunk.data;\r\n }\r\n }\r\n\r\n if (partial.received === (value.chunks || 0)) {\r\n this.handleComplete(message.id, evt);\r\n }\r\n });\r\n this._removeListeners.push(removeListener);\r\n }\r\n\r\n private _extractValue(t: IpcTransportMessage): RpcSerializedValue {\r\n if (t.parameters) {\r\n return t.parameters;\r\n }\r\n\r\n if (t.result) {\r\n return t.result;\r\n }\r\n\r\n throw new IModelError(BentleyStatus.ERROR, \"Unknown value type.\");\r\n }\r\n\r\n private _send(message: IpcTransportMessage, value: RpcSerializedValue, evt?: any) {\r\n const chunks = value.data;\r\n if (chunks.length) {\r\n value.chunks = chunks.length;\r\n value.data = [];\r\n }\r\n\r\n this.performSend(OBJECTS_CHANNEL, message, evt);\r\n\r\n for (let index = 0; index !== chunks.length; ++index) {\r\n const chunk: PartialPayload = { id: message.id, index, data: chunks[index] };\r\n this.performSend(DATA_CHANNEL, chunk, evt);\r\n }\r\n }\r\n\r\n protected performSend(channel: string, message: any, evt: any) {\r\n (evt ? evt.sender : this.protocol.ipcSocket).send(channel, message);\r\n }\r\n\r\n protected abstract handleComplete(id: string, evt: any): void;\r\n\r\n /** @internal */\r\n public sendResponse(message: TOut, evt: any) {\r\n const value = this._extractValue(message);\r\n this._send(message, value, evt);\r\n }\r\n\r\n protected loadMessage(id: string) {\r\n const partial = this._partials.get(id);\r\n if (!partial || Array.isArray(partial)) {\r\n throw new IModelError(BentleyStatus.ERROR, `Incomplete transmission for id \"${id}\".`);\r\n }\r\n\r\n this._partials.delete(id);\r\n return partial.message;\r\n }\r\n\r\n public cleanup() {\r\n this._removeListeners.forEach((removeListener) => removeListener());\r\n }\r\n}\r\n\r\n/** @internal */\r\nexport class FrontendIpcTransport extends ElectronIpcTransport<RpcRequestFulfillment> {\r\n private _pushTransport?: ElectronPushTransport;\r\n\r\n protected override setupPush() {\r\n const pushTransport = new ElectronPushTransport(this);\r\n this._pushTransport = pushTransport;\r\n RpcPushChannel.setup(pushTransport);\r\n }\r\n\r\n protected async handleComplete(id: string) {\r\n const message = this.loadMessage(id);\r\n\r\n if (this._pushTransport && this._pushTransport.consume(message)) {\r\n return;\r\n }\r\n\r\n const protocol = this._protocol;\r\n const request = protocol.requests.get(message.id) as ElectronRpcRequest;\r\n request.notifyResponse(message);\r\n }\r\n}\r\n\r\n/** @internal */\r\nexport class BackendIpcTransport extends ElectronIpcTransport<SerializedRpcRequest, RpcRequestFulfillment> {\r\n private _browserWindow: any;\r\n\r\n protected override setupPush() {\r\n RpcPushConnection.for = (channel, client) => new ElectronPushConnection(channel, client, this);\r\n RpcPushChannel.enabled = true;\r\n }\r\n\r\n protected async handleComplete(id: string, evt: any) {\r\n const message = this.loadMessage(id);\r\n\r\n let response: RpcRequestFulfillment;\r\n try {\r\n const protocol = this._protocol;\r\n response = await protocol.fulfill(message);\r\n } catch (err) {\r\n response = await RpcRequestFulfillment.forUnknownError(message, err);\r\n }\r\n\r\n const raw = response.rawResult;\r\n response.rawResult = undefined; // Otherwise, it will be serialized in IPC layer and large responses will then crash the app\r\n this.sendResponse(response, evt);\r\n response.rawResult = raw;\r\n }\r\n\r\n protected override performSend(channel: string, message: any, evt: any) {\r\n if (evt) {\r\n return super.performSend(channel, message, evt);\r\n }\r\n\r\n this._requireBrowserWindow();\r\n const target = ElectronRpcConfiguration.targetWindowId;\r\n const windows = target ? [this._browserWindow.fromId(target)] : this._browserWindow.getAllWindows();\r\n windows.forEach((window: any) => window.webContents.send(channel, message));\r\n }\r\n\r\n private _requireBrowserWindow() {\r\n if (this._browserWindow) {\r\n return;\r\n }\r\n\r\n try { // Wrapping require in a try/catch signals to webpack that this is only an optional dependency\r\n this._browserWindow = require(\"electron\").BrowserWindow; // eslint-disable-line @typescript-eslint/no-var-requires\r\n } catch (err) {\r\n throw new IModelError(BentleyStatus.ERROR, `Error requiring electron`, () => BentleyError.getErrorProps(err));\r\n }\r\n }\r\n}\r\n\r\nlet transport: ElectronIpcTransport | undefined;\r\n\r\n/** @internal */\r\nexport function initializeIpc(protocol: ElectronRpcProtocol) {\r\n if (transport && transport.protocol !== protocol) {\r\n transport.cleanup();\r\n transport = undefined;\r\n }\r\n\r\n if (undefined === transport)\r\n transport = ProcessDetector.isElectronAppFrontend ? new FrontendIpcTransport(protocol) : new BackendIpcTransport(protocol);\r\n\r\n return transport;\r\n}\r\n"]}
|
|
@@ -20,5 +20,8 @@ export declare class ElectronRpcManager extends RpcManager {
|
|
|
20
20
|
/** Initializes ElectronRpcManager for the backend of an application. */
|
|
21
21
|
static initializeBackend(ipcBackend: IpcSocketBackend, interfaces?: RpcInterfaceDefinition[]): ElectronRpcConfiguration;
|
|
22
22
|
private static performInitialization;
|
|
23
|
+
/** Terminates ElectronRpcManager for the frontend of an application. */
|
|
24
|
+
static terminateFrontend(): void;
|
|
25
|
+
private static performTermination;
|
|
23
26
|
}
|
|
24
27
|
//# sourceMappingURL=ElectronRpcManager.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ElectronRpcManager.d.ts","sourceRoot":"","sources":["../../../src/common/ElectronRpcManager.ts"],"names":[],"mappings":"AAIA;;GAEG;AAEH,OAAO,EAA6D,gBAAgB,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,sBAAsB,EAAE,UAAU,
|
|
1
|
+
{"version":3,"file":"ElectronRpcManager.d.ts","sourceRoot":"","sources":["../../../src/common/ElectronRpcManager.ts"],"names":[],"mappings":"AAIA;;GAEG;AAEH,OAAO,EAA6D,gBAAgB,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,sBAAsB,EAAE,UAAU,EAA2C,MAAM,oBAAoB,CAAC;AAEnO,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAE5D;;GAEG;AACH,8BAAsB,wBAAyB,SAAQ,gBAAgB;IAErE,OAAc,cAAc,CAAC,EAAE,MAAM,CAAC;IAEtC,yCAAyC;IACzC,SAAyB,QAAQ,EAAE,mBAAmB,CAAC;CACxD;AAED;;GAEG;AACH,qBAAa,kBAAmB,SAAQ,UAAU;IAChD,yEAAyE;WAC3D,kBAAkB,CAAC,WAAW,EAAE,iBAAiB,EAAE,UAAU,CAAC,EAAE,sBAAsB,EAAE,GAAG,wBAAwB;IAIjI,wEAAwE;WAC1D,iBAAiB,CAAC,UAAU,EAAE,gBAAgB,EAAE,UAAU,CAAC,EAAE,sBAAsB,EAAE,GAAG,wBAAwB;IAI9H,OAAO,CAAC,MAAM,CAAC,qBAAqB;IAsBpC,wEAAwE;WAC1D,iBAAiB;IAI/B,OAAO,CAAC,MAAM,CAAC,kBAAkB;CAOlC"}
|
|
@@ -50,6 +50,16 @@ class ElectronRpcManager extends core_common_1.RpcManager {
|
|
|
50
50
|
core_common_1.RpcConfiguration.initializeInterfaces(instance);
|
|
51
51
|
return instance;
|
|
52
52
|
}
|
|
53
|
+
/** Terminates ElectronRpcManager for the frontend of an application. */
|
|
54
|
+
static terminateFrontend() {
|
|
55
|
+
return ElectronRpcManager.performTermination();
|
|
56
|
+
}
|
|
57
|
+
static performTermination() {
|
|
58
|
+
const definitions = core_common_1.RpcRegistry.instance.definitionClasses;
|
|
59
|
+
for (const [, interfaceDef] of definitions) {
|
|
60
|
+
core_common_1.RpcManager.terminateInterface(interfaceDef);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
53
63
|
}
|
|
54
64
|
exports.ElectronRpcManager = ElectronRpcManager;
|
|
55
65
|
//# sourceMappingURL=ElectronRpcManager.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ElectronRpcManager.js","sourceRoot":"","sources":["../../../src/common/ElectronRpcManager.ts"],"names":[],"mappings":";AAAA;;;+FAG+F;AAC/F;;GAEG;;;AAEH,
|
|
1
|
+
{"version":3,"file":"ElectronRpcManager.js","sourceRoot":"","sources":["../../../src/common/ElectronRpcManager.ts"],"names":[],"mappings":";AAAA;;;+FAG+F;AAC/F;;GAEG;;;AAEH,oDAAmO;AACnO,oEAAsE;AACtE,+DAA4D;AAE5D;;GAEG;AACH,MAAsB,wBAAyB,SAAQ,8BAAgB;CAMtE;AAND,4DAMC;AAED;;GAEG;AACH,MAAa,kBAAmB,SAAQ,wBAAU;IAChD,yEAAyE;IAClE,MAAM,CAAC,kBAAkB,CAAC,WAA8B,EAAE,UAAqC;QACpG,OAAO,kBAAkB,CAAC,qBAAqB,CAAC,WAAW,EAAE,UAAU,CAAC,CAAC;IAC3E,CAAC;IAED,wEAAwE;IACjE,MAAM,CAAC,iBAAiB,CAAC,UAA4B,EAAE,UAAqC;QACjG,OAAO,kBAAkB,CAAC,qBAAqB,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC;IAC1E,CAAC;IAEO,MAAM,CAAC,qBAAqB,CAAC,SAAoB,EAAE,IAA+B;QACxF,MAAM,UAAU,GAAG,IAAI,aAAJ,IAAI,cAAJ,IAAI,GAAI;YACzB,oCAAsB;YACtB,oCAAsB;YACtB,wCAA0B;YAC1B,8CAAwB;SACzB,CAAC;QACF,MAAM,MAAM,GAAG,KAAM,SAAQ,wBAAwB;YAAtC;;gBACN,eAAU,GAAG,GAAG,EAAE,CAAC,UAAU,CAAC;gBAC9B,aAAQ,GAAwB,IAAI,yCAAmB,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;YAClF,CAAC;SAAA,CAAC;QAEF,KAAK,MAAM,GAAG,IAAI,UAAU,EAAE;YAC5B,8BAAgB,CAAC,MAAM,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,CAAC;SAC5C;QAED,MAAM,QAAQ,GAAG,8BAAgB,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QACjD,8BAAgB,CAAC,oBAAoB,CAAC,QAAQ,CAAC,CAAC;QAEhD,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED,wEAAwE;IACjE,MAAM,CAAC,iBAAiB;QAC7B,OAAO,kBAAkB,CAAC,kBAAkB,EAAE,CAAC;IACjD,CAAC;IAEO,MAAM,CAAC,kBAAkB;QAC/B,MAAM,WAAW,GAAG,yBAAW,CAAC,QAAQ,CAAC,iBAAiB,CAAC;QAE3D,KAAK,MAAM,CAAC,EAAE,YAAY,CAAC,IAAI,WAAW,EAAE;YAC1C,wBAAU,CAAC,kBAAkB,CAAC,YAAY,CAAC,CAAC;SAC7C;IACH,CAAC;CACF;AA7CD,gDA6CC","sourcesContent":["/*---------------------------------------------------------------------------------------------\r\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\r\n* See LICENSE.md in the project root for license terms and full copyright notice.\r\n*--------------------------------------------------------------------------------------------*/\r\n/** @packageDocumentation\r\n * @module RpcInterface\r\n */\r\n\r\nimport { IModelReadRpcInterface, IModelTileRpcInterface, IpcSocket, IpcSocketBackend, IpcSocketFrontend, RpcConfiguration, RpcInterfaceDefinition, RpcManager, RpcRegistry, SnapshotIModelRpcInterface } from \"@itwin/core-common\";\r\nimport { PresentationRpcInterface } from \"@itwin/presentation-common\";\r\nimport { ElectronRpcProtocol } from \"./ElectronRpcProtocol\";\r\n\r\n/** RPC interface configuration for an Electron-based application.\r\n * @internal\r\n */\r\nexport abstract class ElectronRpcConfiguration extends RpcConfiguration {\r\n\r\n public static targetWindowId?: number;\r\n\r\n /** The protocol of the configuration. */\r\n public abstract override protocol: ElectronRpcProtocol;\r\n}\r\n\r\n/** Coordinates usage of RPC interfaces for an Electron-based application.\r\n * @internal\r\n */\r\nexport class ElectronRpcManager extends RpcManager {\r\n /** Initializes ElectronRpcManager for the frontend of an application. */\r\n public static initializeFrontend(ipcFrontend: IpcSocketFrontend, interfaces?: RpcInterfaceDefinition[]): ElectronRpcConfiguration {\r\n return ElectronRpcManager.performInitialization(ipcFrontend, interfaces);\r\n }\r\n\r\n /** Initializes ElectronRpcManager for the backend of an application. */\r\n public static initializeBackend(ipcBackend: IpcSocketBackend, interfaces?: RpcInterfaceDefinition[]): ElectronRpcConfiguration {\r\n return ElectronRpcManager.performInitialization(ipcBackend, interfaces);\r\n }\r\n\r\n private static performInitialization(ipcSocket: IpcSocket, rpcs?: RpcInterfaceDefinition[]): ElectronRpcConfiguration {\r\n const interfaces = rpcs ?? [\r\n IModelReadRpcInterface,\r\n IModelTileRpcInterface,\r\n SnapshotIModelRpcInterface,\r\n PresentationRpcInterface,\r\n ];\r\n const config = class extends ElectronRpcConfiguration {\r\n public interfaces = () => interfaces;\r\n public protocol: ElectronRpcProtocol = new ElectronRpcProtocol(this, ipcSocket);\r\n };\r\n\r\n for (const def of interfaces) {\r\n RpcConfiguration.assign(def, () => config);\r\n }\r\n\r\n const instance = RpcConfiguration.obtain(config);\r\n RpcConfiguration.initializeInterfaces(instance);\r\n\r\n return instance;\r\n }\r\n\r\n /** Terminates ElectronRpcManager for the frontend of an application. */\r\n public static terminateFrontend() {\r\n return ElectronRpcManager.performTermination();\r\n }\r\n\r\n private static performTermination() {\r\n const definitions = RpcRegistry.instance.definitionClasses;\r\n\r\n for (const [, interfaceDef] of definitions) {\r\n RpcManager.terminateInterface(interfaceDef);\r\n }\r\n }\r\n}\r\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ElectronRpcRequest.d.ts","sourceRoot":"","sources":["../../../src/common/ElectronRpcRequest.ts"],"names":[],"mappings":"AAKA,OAAO,EAAoB,UAAU,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AACzF,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAE5D,YAAY;AACZ,qBAAa,kBAAmB,SAAQ,UAAU;IAChD,OAAO,CAAC,IAAI,CAA4C;IACxD,OAAO,CAAC,YAAY,CAAgD;IAEpE,0DAA0D;IAC1D,SAAyB,QAAQ,EAAE,mBAAmB,CAA6C;IAEnG,yBAAyB;cACT,IAAI;
|
|
1
|
+
{"version":3,"file":"ElectronRpcRequest.d.ts","sourceRoot":"","sources":["../../../src/common/ElectronRpcRequest.ts"],"names":[],"mappings":"AAKA,OAAO,EAAoB,UAAU,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AACzF,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAE5D,YAAY;AACZ,qBAAa,kBAAmB,SAAQ,UAAU;IAChD,OAAO,CAAC,IAAI,CAA4C;IACxD,OAAO,CAAC,YAAY,CAAgD;IAEpE,0DAA0D;IAC1D,SAAyB,QAAQ,EAAE,mBAAmB,CAA6C;IAEnG,yBAAyB;cACT,IAAI;IAcpB,yBAAyB;cACT,IAAI;IASpB,kCAAkC;IAClC,SAAS,CAAC,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI;IAIxD,gBAAgB;IACT,cAAc,CAAC,WAAW,EAAE,qBAAqB;IAKxD,gBAAgB;IACA,OAAO;CAIxB"}
|
|
@@ -25,7 +25,9 @@ class ElectronRpcRequest extends core_common_1.RpcRequest {
|
|
|
25
25
|
catch (e) {
|
|
26
26
|
this.protocol.events.raiseEvent(core_common_1.RpcProtocolEvent.ConnectionErrorReceived, this);
|
|
27
27
|
}
|
|
28
|
-
return new Promise((resolve) => {
|
|
28
|
+
return new Promise((resolve) => {
|
|
29
|
+
this._res = resolve;
|
|
30
|
+
});
|
|
29
31
|
}
|
|
30
32
|
/** Loads the request. */
|
|
31
33
|
async load() {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ElectronRpcRequest.js","sourceRoot":"","sources":["../../../src/common/ElectronRpcRequest.ts"],"names":[],"mappings":";AAAA;;;+FAG+F;;;AAE/F,oDAAyF;AAGzF,YAAY;AACZ,MAAa,kBAAmB,SAAQ,wBAAU;IAAlD;;QACU,SAAI,GAA4B,GAAG,EAAE,CAAC,SAAS,CAAC;QAChD,iBAAY,GAAsC,SAAS,CAAC;QAEpE,0DAA0D;QACjC,aAAQ,GAAwB,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,QAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"ElectronRpcRequest.js","sourceRoot":"","sources":["../../../src/common/ElectronRpcRequest.ts"],"names":[],"mappings":";AAAA;;;+FAG+F;;;AAE/F,oDAAyF;AAGzF,YAAY;AACZ,MAAa,kBAAmB,SAAQ,wBAAU;IAAlD;;QACU,SAAI,GAA4B,GAAG,EAAE,CAAC,SAAS,CAAC;QAChD,iBAAY,GAAsC,SAAS,CAAC;QAEpE,0DAA0D;QACjC,aAAQ,GAAwB,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,QAAe,CAAC;IA2CrG,CAAC;IAzCC,yBAAyB;IACf,KAAK,CAAC,IAAI;QAClB,IAAI;YACF,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC;YAC1C,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;YACpD,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;SAC9C;QAAC,OAAO,CAAC,EAAE;YACV,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,UAAU,CAAC,8BAAgB,CAAC,uBAAuB,EAAE,IAAI,CAAC,CAAC;SACjF;QAED,OAAO,IAAI,OAAO,CAAS,CAAC,OAAO,EAAE,EAAE;YACrC,IAAI,CAAC,IAAI,GAAG,OAAO,CAAC;QACtB,CAAC,CAAC,CAAC;IACL,CAAC;IAED,yBAAyB;IACf,KAAK,CAAC,IAAI;QAClB,MAAM,WAAW,GAAG,IAAI,CAAC,YAAY,CAAC;QACtC,IAAI,CAAC,WAAW,EAAE;YAChB,MAAM,IAAI,KAAK,CAAC,mCAAmC,CAAC,CAAC;SACtD;QAED,OAAO,WAAW,CAAC,MAAM,CAAC;IAC5B,CAAC;IAED,kCAAkC;IACxB,SAAS,CAAC,KAAa,EAAE,MAAc;QAC/C,oBAAoB;IACtB,CAAC;IAED,gBAAgB;IACT,cAAc,CAAC,WAAkC;QACtD,IAAI,CAAC,YAAY,GAAG,WAAW,CAAC;QAChC,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;IAChC,CAAC;IAED,gBAAgB;IACA,OAAO;QACrB,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACvC,KAAK,CAAC,OAAO,EAAE,CAAC;IAClB,CAAC;CACF;AAhDD,gDAgDC","sourcesContent":["/*---------------------------------------------------------------------------------------------\r\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\r\n* See LICENSE.md in the project root for license terms and full copyright notice.\r\n*--------------------------------------------------------------------------------------------*/\r\n\r\nimport { RpcProtocolEvent, RpcRequest, RpcRequestFulfillment } from \"@itwin/core-common\";\r\nimport { ElectronRpcProtocol } from \"./ElectronRpcProtocol\";\r\n\r\n/** @beta */\r\nexport class ElectronRpcRequest extends RpcRequest {\r\n private _res: (value: number) => void = () => undefined;\r\n private _fulfillment: RpcRequestFulfillment | undefined = undefined;\r\n\r\n /** Convenience access to the protocol of this request. */\r\n public override readonly protocol: ElectronRpcProtocol = this.client.configuration.protocol as any;\r\n\r\n /** Sends the request. */\r\n protected async send() {\r\n try {\r\n this.protocol.requests.set(this.id, this);\r\n const request = await this.protocol.serialize(this);\r\n this.protocol.transport.sendRequest(request);\r\n } catch (e) {\r\n this.protocol.events.raiseEvent(RpcProtocolEvent.ConnectionErrorReceived, this);\r\n }\r\n\r\n return new Promise<number>((resolve) => {\r\n this._res = resolve;\r\n });\r\n }\r\n\r\n /** Loads the request. */\r\n protected async load() {\r\n const fulfillment = this._fulfillment;\r\n if (!fulfillment) {\r\n throw new Error(\"No request fulfillment available.\");\r\n }\r\n\r\n return fulfillment.result;\r\n }\r\n\r\n /** Sets request header values. */\r\n protected setHeader(_name: string, _value: string): void {\r\n // No implementation\r\n }\r\n\r\n /** @internal */\r\n public notifyResponse(fulfillment: RpcRequestFulfillment) {\r\n this._fulfillment = fulfillment;\r\n this._res(fulfillment.status);\r\n }\r\n\r\n /** @internal */\r\n public override dispose() {\r\n this.protocol.requests.delete(this.id);\r\n super.dispose();\r\n }\r\n}\r\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ElectronApp.d.ts","sourceRoot":"","sources":["../../../src/frontend/ElectronApp.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"ElectronApp.d.ts","sourceRoot":"","sources":["../../../src/frontend/ElectronApp.ts"],"names":[],"mappings":"AAIA,OAAO,EAAmB,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAEzE,OAAO,EAAqB,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAExE,OAAO,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAC;AAEpE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAEnE,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,MAAM;QACd,OAAO,EAAE,gBAAgB,CAAC;KAC3B;CACF;AA4BD,YAAY;AACZ,oBAAY,eAAe,GAAG,aAAa,CAAC;AAE5C;;;GAGG;AACH,qBAAa,WAAW;IACtB,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,CAAc;IAClC,WAAkB,OAAO,IAAI,OAAO,CAAoC;IAExE;;;;OAIG;WACiB,OAAO,CAAC,IAAI,CAAC,EAAE,eAAe;WAU9B,QAAQ;IAM5B;;;;OAIG;WACiB,UAAU,CAAC,CAAC,SAAS,kBAAkB,EAAE,UAAU,EAAE,CAAC,EAAE,GAAG,IAAI,EAAE,UAAU,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;CAGpH"}
|
|
@@ -57,6 +57,7 @@ class ElectronApp {
|
|
|
57
57
|
static async shutdown() {
|
|
58
58
|
this._ipc = undefined;
|
|
59
59
|
await core_frontend_1.NativeApp.shutdown();
|
|
60
|
+
ElectronRpcManager_1.ElectronRpcManager.terminateFrontend();
|
|
60
61
|
}
|
|
61
62
|
/**
|
|
62
63
|
* Call an asynchronous method in the [Electron.Dialog](https://www.electronjs.org/docs/api/dialog) interface from a previously initialized ElectronFrontend.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ElectronApp.js","sourceRoot":"","sources":["../../../src/frontend/ElectronApp.ts"],"names":[],"mappings":";;;AAAA;;;+FAG+F;AAC/F,sDAAyE;AAEzE,wDAAwE;AAGxE,qEAAkE;AASlE;;GAEG;AACH,MAAM,WAAW;IAef;;QACE,sJAAsJ;QACtJ,iGAAiG;QACjG,8DAA8D;QAC9D,IAAI,CAAC,IAAI,GAAG,MAAA,MAAM,CAAC,OAAO,mCAAI,OAAO,CAAC,UAAU,CAAC,CAAC,WAAW,CAAC;IAChE,CAAC;IAlBM,WAAW,CAAC,WAAmB,EAAE,QAAqB;QAC3D,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAC;QAC7C,OAAO,GAAG,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAC;IAC/D,CAAC;IACM,cAAc,CAAC,WAAmB,EAAE,QAAqB;QAC9D,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAC;IAClD,CAAC;IACM,IAAI,CAAC,OAAe,EAAE,GAAG,IAAW;QACzC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,CAAC;IACnC,CAAC;IACM,KAAK,CAAC,MAAM,CAAC,OAAe,EAAE,GAAG,IAAW;QACjD,OAAO,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,CAAC;IAC5C,CAAC;CAOF;AAKD;;;GAGG;AACH,MAAa,WAAW;IAEf,MAAM,KAAK,OAAO,KAAc,OAAO,SAAS,KAAK,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;IAExE;;;;OAIG;IACI,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,IAAsB;;QAChD,IAAI,CAAC,8BAAe,CAAC,qBAAqB;YACxC,MAAM,IAAI,KAAK,CAAC,4BAA4B,CAAC,CAAC;QAChD,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE;YACjB,IAAI,CAAC,IAAI,GAAG,IAAI,WAAW,EAAE,CAAC;YAC9B,uCAAkB,CAAC,kBAAkB,CAAC,IAAI,CAAC,IAAI,EAAE,MAAA,IAAI,aAAJ,IAAI,uBAAJ,IAAI,CAAE,SAAS,0CAAE,aAAa,CAAC,CAAC;SAClF;QACD,MAAM,yBAAS,CAAC,OAAO,CAAC,IAAI,CAAC,IAAK,EAAE,IAAI,CAAC,CAAC;IAC5C,CAAC;IAEM,MAAM,CAAC,KAAK,CAAC,QAAQ;QAC1B,IAAI,CAAC,IAAI,GAAG,SAAS,CAAC;QACtB,MAAM,yBAAS,CAAC,QAAQ,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"ElectronApp.js","sourceRoot":"","sources":["../../../src/frontend/ElectronApp.ts"],"names":[],"mappings":";;;AAAA;;;+FAG+F;AAC/F,sDAAyE;AAEzE,wDAAwE;AAGxE,qEAAkE;AASlE;;GAEG;AACH,MAAM,WAAW;IAef;;QACE,sJAAsJ;QACtJ,iGAAiG;QACjG,8DAA8D;QAC9D,IAAI,CAAC,IAAI,GAAG,MAAA,MAAM,CAAC,OAAO,mCAAI,OAAO,CAAC,UAAU,CAAC,CAAC,WAAW,CAAC;IAChE,CAAC;IAlBM,WAAW,CAAC,WAAmB,EAAE,QAAqB;QAC3D,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAC;QAC7C,OAAO,GAAG,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAC;IAC/D,CAAC;IACM,cAAc,CAAC,WAAmB,EAAE,QAAqB;QAC9D,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAC;IAClD,CAAC;IACM,IAAI,CAAC,OAAe,EAAE,GAAG,IAAW;QACzC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,CAAC;IACnC,CAAC;IACM,KAAK,CAAC,MAAM,CAAC,OAAe,EAAE,GAAG,IAAW;QACjD,OAAO,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,CAAC;IAC5C,CAAC;CAOF;AAKD;;;GAGG;AACH,MAAa,WAAW;IAEf,MAAM,KAAK,OAAO,KAAc,OAAO,SAAS,KAAK,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;IAExE;;;;OAIG;IACI,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,IAAsB;;QAChD,IAAI,CAAC,8BAAe,CAAC,qBAAqB;YACxC,MAAM,IAAI,KAAK,CAAC,4BAA4B,CAAC,CAAC;QAChD,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE;YACjB,IAAI,CAAC,IAAI,GAAG,IAAI,WAAW,EAAE,CAAC;YAC9B,uCAAkB,CAAC,kBAAkB,CAAC,IAAI,CAAC,IAAI,EAAE,MAAA,IAAI,aAAJ,IAAI,uBAAJ,IAAI,CAAE,SAAS,0CAAE,aAAa,CAAC,CAAC;SAClF;QACD,MAAM,yBAAS,CAAC,OAAO,CAAC,IAAI,CAAC,IAAK,EAAE,IAAI,CAAC,CAAC;IAC5C,CAAC;IAEM,MAAM,CAAC,KAAK,CAAC,QAAQ;QAC1B,IAAI,CAAC,IAAI,GAAG,SAAS,CAAC;QACtB,MAAM,yBAAS,CAAC,QAAQ,EAAE,CAAC;QAC3B,uCAAkB,CAAC,iBAAiB,EAAE,CAAC;IACzC,CAAC;IAED;;;;OAIG;IACI,MAAM,CAAC,KAAK,CAAC,UAAU,CAA+B,UAAa,EAAE,GAAG,IAAoC;QACjH,OAAO,sBAAM,CAAC,cAAc,CAAC,eAAe,EAAE,cAAc,EAAE,QAAQ,EAAE,UAAU,EAAE,GAAG,IAAI,CAA0C,CAAC;IACxI,CAAC;CACF;AAjCD,kCAiCC","sourcesContent":["/*---------------------------------------------------------------------------------------------\r\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\r\n* See LICENSE.md in the project root for license terms and full copyright notice.\r\n*--------------------------------------------------------------------------------------------*/\r\nimport { ProcessDetector, PromiseReturnType } from \"@itwin/core-bentley\";\r\nimport { IpcListener, IpcSocketFrontend } from \"@itwin/core-common\";\r\nimport { IpcApp, NativeApp, NativeAppOpts } from \"@itwin/core-frontend\";\r\nimport type { IpcRenderer } from \"electron\";\r\nimport { DialogModuleMethod } from \"../common/ElectronIpcInterface\";\r\nimport { ElectronRpcManager } from \"../common/ElectronRpcManager\";\r\nimport type { ITwinElectronApi } from \"../common/ITwinElectronApi\";\r\n\r\ndeclare global {\r\n interface Window {\r\n itwinjs: ITwinElectronApi;\r\n }\r\n}\r\n\r\n/**\r\n * Frontend Ipc support for Electron apps.\r\n */\r\nclass ElectronIpc implements IpcSocketFrontend {\r\n private _api: ITwinElectronApi | IpcRenderer;\r\n public addListener(channelName: string, listener: IpcListener) {\r\n this._api.addListener(channelName, listener);\r\n return () => this._api.removeListener(channelName, listener);\r\n }\r\n public removeListener(channelName: string, listener: IpcListener) {\r\n this._api.removeListener(channelName, listener);\r\n }\r\n public send(channel: string, ...data: any[]) {\r\n this._api.send(channel, ...data);\r\n }\r\n public async invoke(channel: string, ...args: any[]) {\r\n return this._api.invoke(channel, ...args);\r\n }\r\n constructor() {\r\n // use the methods on window.itwinjs exposed by ElectronPreload.ts, or ipcRenderer directly if running with nodeIntegration=true (**only** for tests).\r\n // Note that `require(\"electron\")` doesn't work with nodeIntegration=false - that's what it stops\r\n // eslint-disable-next-line @typescript-eslint/no-var-requires\r\n this._api = window.itwinjs ?? require(\"electron\").ipcRenderer;\r\n }\r\n}\r\n\r\n/** @beta */\r\nexport type ElectronAppOpts = NativeAppOpts;\r\n\r\n/**\r\n * Frontend of an Electron App.\r\n * @beta\r\n */\r\nexport class ElectronApp {\r\n private static _ipc?: ElectronIpc;\r\n public static get isValid(): boolean { return undefined !== this._ipc; }\r\n\r\n /**\r\n * Start the frontend of an Electron application.\r\n * @param opts Options for your ElectronApp\r\n * @note This method must only be called from the frontend of an Electron app (i.e. when [ProcessDetector.isElectronAppFrontend]($bentley) is `true`).\r\n */\r\n public static async startup(opts?: ElectronAppOpts) {\r\n if (!ProcessDetector.isElectronAppFrontend)\r\n throw new Error(\"Not running under Electron\");\r\n if (!this.isValid) {\r\n this._ipc = new ElectronIpc();\r\n ElectronRpcManager.initializeFrontend(this._ipc, opts?.iModelApp?.rpcInterfaces);\r\n }\r\n await NativeApp.startup(this._ipc!, opts);\r\n }\r\n\r\n public static async shutdown() {\r\n this._ipc = undefined;\r\n await NativeApp.shutdown();\r\n ElectronRpcManager.terminateFrontend();\r\n }\r\n\r\n /**\r\n * Call an asynchronous method in the [Electron.Dialog](https://www.electronjs.org/docs/api/dialog) interface from a previously initialized ElectronFrontend.\r\n * @param methodName the name of the method to call\r\n * @param args arguments to method\r\n */\r\n public static async callDialog<T extends DialogModuleMethod>(methodName: T, ...args: Parameters<Electron.Dialog[T]>) {\r\n return IpcApp.callIpcChannel(\"electron-safe\", \"callElectron\", \"dialog\", methodName, ...args) as PromiseReturnType<Electron.Dialog[T]>;\r\n }\r\n}\r\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@itwin/core-electron",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.5.0-dev.4",
|
|
4
4
|
"description": "iTwin.js ElectronHost and ElectronApp",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"engines": {
|
|
@@ -20,24 +20,28 @@
|
|
|
20
20
|
"url": "http://www.bentley.com"
|
|
21
21
|
},
|
|
22
22
|
"peerDependencies": {
|
|
23
|
-
"@itwin/core-backend": "^3.
|
|
24
|
-
"@itwin/core-bentley": "^3.
|
|
25
|
-
"@itwin/core-common": "^3.
|
|
26
|
-
"@itwin/core-frontend": "^3.
|
|
27
|
-
"@itwin/presentation-common": "^3.
|
|
28
|
-
"electron": "
|
|
23
|
+
"@itwin/core-backend": "^3.5.0-dev.4",
|
|
24
|
+
"@itwin/core-bentley": "^3.5.0-dev.4",
|
|
25
|
+
"@itwin/core-common": "^3.5.0-dev.4",
|
|
26
|
+
"@itwin/core-frontend": "^3.5.0-dev.4",
|
|
27
|
+
"@itwin/presentation-common": "^3.5.0-dev.4",
|
|
28
|
+
"electron": ">=14.0.0 <18.0.0"
|
|
29
29
|
},
|
|
30
30
|
"devDependencies": {
|
|
31
|
-
"@itwin/build-tools": "3.
|
|
32
|
-
"@itwin/core-backend": "3.
|
|
33
|
-
"@itwin/core-bentley": "3.
|
|
34
|
-
"@itwin/core-common": "3.
|
|
35
|
-
"@itwin/core-frontend": "3.
|
|
36
|
-
"@itwin/eslint-plugin": "3.
|
|
37
|
-
"@itwin/presentation-common": "3.
|
|
38
|
-
"@types/
|
|
39
|
-
"
|
|
31
|
+
"@itwin/build-tools": "3.5.0-dev.4",
|
|
32
|
+
"@itwin/core-backend": "3.5.0-dev.4",
|
|
33
|
+
"@itwin/core-bentley": "3.5.0-dev.4",
|
|
34
|
+
"@itwin/core-common": "3.5.0-dev.4",
|
|
35
|
+
"@itwin/core-frontend": "3.5.0-dev.4",
|
|
36
|
+
"@itwin/eslint-plugin": "3.5.0-dev.4",
|
|
37
|
+
"@itwin/presentation-common": "3.5.0-dev.4",
|
|
38
|
+
"@types/chai": "4.3.1",
|
|
39
|
+
"@types/mocha": "^8.2.2",
|
|
40
|
+
"@types/node": "16.11.59",
|
|
41
|
+
"chai": "^4.1.2",
|
|
42
|
+
"electron": "^17.0.0",
|
|
40
43
|
"eslint": "^7.11.0",
|
|
44
|
+
"mocha": "^10.0.0",
|
|
41
45
|
"rimraf": "^3.0.2",
|
|
42
46
|
"typescript": "~4.4.0"
|
|
43
47
|
},
|
|
@@ -61,6 +65,7 @@
|
|
|
61
65
|
"extract-api": "betools extract-api --entry=__DOC_ONLY__",
|
|
62
66
|
"lint": "eslint -f visualstudio \"./src/**/*.ts\" 1>&2",
|
|
63
67
|
"test": "",
|
|
68
|
+
"test:integration": "mocha lib/cjs/test/backend/RunElectronBackendTests.js",
|
|
64
69
|
"cover": ""
|
|
65
70
|
},
|
|
66
71
|
"readme": "# @itwin/core-electron\r\n\r\nCopyright © Bentley Systems, Incorporated. All rights reserved. See LICENSE.md for license terms and full copyright notice.\r\n\r\n## Description\r\n\r\nThe __@itwin/core-electron__ package contains the electron utilities to write an iTwin.js application based on Electron.\r\n\r\n## Documentation\r\n\r\nSee the [iTwin.js](https://www.itwinjs.org) documentation for more information.\r\n"
|