@itwin/core-electron 5.0.0-dev.4 → 5.0.0-dev.40

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 CHANGED
@@ -1,6 +1,35 @@
1
1
  # Change Log - @itwin/core-electron
2
2
 
3
- This log was last generated on Wed, 06 Nov 2024 19:24:30 GMT and should not be manually modified.
3
+ This log was last generated on Mon, 13 Jan 2025 14:09:29 GMT and should not be manually modified.
4
+
5
+ ## 4.10.4
6
+ Mon, 13 Jan 2025 14:06:43 GMT
7
+
8
+ _Version update only_
9
+
10
+ ## 4.10.3
11
+ Mon, 06 Jan 2025 14:00:13 GMT
12
+
13
+ _Version update only_
14
+
15
+ ## 4.10.2
16
+ Thu, 21 Nov 2024 15:22:20 GMT
17
+
18
+ ### Updates
19
+
20
+ - Bumped `username` to `7.0.0`
21
+
22
+ ## 4.10.1
23
+ Thu, 14 Nov 2024 18:11:00 GMT
24
+
25
+ _Version update only_
26
+
27
+ ## 4.10.0
28
+ Wed, 13 Nov 2024 15:23:38 GMT
29
+
30
+ ### Updates
31
+
32
+ - Add support for Electron 33
4
33
 
5
34
  ## 4.9.7
6
35
  Wed, 06 Nov 2024 19:23:04 GMT
@@ -1,7 +1,7 @@
1
1
  /** @packageDocumentation
2
2
  * @module Main
3
3
  */
4
- import type { BrowserWindow, BrowserWindowConstructorOptions } from "electron";
4
+ import type { BrowserWindow, BrowserWindowConstructorOptions, WebPreferences } from "electron";
5
5
  import type * as ElectronModule from "electron";
6
6
  import { IpcHandler, NativeHostOpts } from "@itwin/core-backend";
7
7
  import { RpcConfiguration, RpcInterfaceDefinition } from "@itwin/core-common";
@@ -31,9 +31,12 @@ export interface ElectronHostOpts extends NativeHostOpts {
31
31
  }
32
32
  /** @beta */
33
33
  export interface ElectronHostWindowOptions extends BrowserWindowConstructorOptions {
34
+ /** Name used to construct key for saving window size, position and maximize status to the settings store */
34
35
  storeWindowName?: string;
35
36
  /** The style of window title bar. Default is `default`. */
36
37
  titleBarStyle?: ("default" | "hidden" | "hiddenInset" | "customButtonsOnHover");
38
+ /** Web page settings */
39
+ webPreferences?: Omit<WebPreferences, "preload" | "experimentalFeatures" | "nodeIntegration" | "contextIsolation" | "sandbox" | "nodeIntegrationInWorker" | "nodeIntegrationInSubFrames">;
37
40
  }
38
41
  /** the size and position of a window as stored in the settings file.
39
42
  * @beta
@@ -49,8 +52,6 @@ export interface WindowSizeAndPositionProps {
49
52
  * @beta
50
53
  */
51
54
  export declare class ElectronHost {
52
- private static readonly _deprecatedSizeAndPosStoreKey;
53
- private static readonly _sizeAndPosStoreKey;
54
55
  private static _ipc;
55
56
  private static _developmentServer;
56
57
  private static _electron;
@@ -65,25 +66,16 @@ export declare class ElectronHost {
65
66
  static get electron(): typeof ElectronModule;
66
67
  private constructor();
67
68
  /**
68
- * Converts an "electron://frontend/" URL to an absolute file path.
69
+ * Converts an "electron://frontend/" URL to an "file://{absolute file path}" URL.
69
70
  *
70
71
  * We use this protocol in production builds because our frontend must be built with absolute URLs,
71
72
  * however, since we're loading everything directly from the install directory, we cannot know the
72
73
  * absolute path at build time.
73
74
  */
74
- private static parseElectronUrl;
75
+ private static transformElectronUrlToFileUrl;
75
76
  private static _openWindow;
76
77
  /** The "main" BrowserWindow for this application. */
77
78
  static get mainWindow(): BrowserWindow | undefined;
78
- /**
79
- * Gets window size and position for a window, by name, from settings file, if present.
80
- * @note Size and position values in the settings file will be updated differently depending on platform.
81
- * On Linux values are only updated on window "unmaximize".
82
- * On Windows and MacOS values are also updated on window manual resize or move.
83
- * To get consistent behavior across different platforms, use [[ElectronHost.getWindowSizeAndPositionSetting]].
84
- * @deprecated in 3.6. Use [[ElectronHost.getWindowSizeAndPositionSetting]].
85
- */
86
- static getWindowSizeSetting(windowName: string): WindowSizeAndPositionProps | undefined;
87
79
  /**
88
80
  * Gets window size and position for a window, by name, from settings file, if present.
89
81
  */
@@ -1 +1 @@
1
- {"version":3,"file":"ElectronHost.d.ts","sourceRoot":"","sources":["../../../src/backend/ElectronHost.ts"],"names":[],"mappings":"AAKA;;GAEG;AAGH,OAAO,KAAK,EAAE,aAAa,EAAE,+BAA+B,EAAkB,MAAM,UAAU,CAAC;AAC/F,OAAO,KAAK,KAAK,cAAc,MAAM,UAAU,CAAC;AAKhD,OAAO,EAAE,UAAU,EAAuB,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACtF,OAAO,EAA8D,gBAAgB,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAC;AAyB1I;;;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,yDAAyD;IACzD,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,QAAQ,CAAC,6BAA6B,CAAe;IACpE,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,mBAAmB,CAAsB;IAEjE,OAAO,CAAC,MAAM,CAAC,IAAI,CAAc;IACjC,OAAO,CAAC,MAAM,CAAC,kBAAkB,CAAU;IAC3C,OAAO,CAAC,MAAM,CAAC,SAAS,CAAwB;IAChD,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,0BAA6B;IAEvD,OAAO;IAEP;;;;;;OAMG;IACH,OAAO,CAAC,MAAM,CAAC,gBAAgB;IAkB/B,OAAO,CAAC,MAAM,CAAC,WAAW;IAsD1B,qDAAqD;IACrD,WAAkB,UAAU,8BAA+B;IAE3D;;;;;;;OAOG;WACW,oBAAoB,CAAC,UAAU,EAAE,MAAM,GAAG,0BAA0B,GAAG,SAAS;IAK9F;;OAEG;WACW,+BAA+B,CAAC,UAAU,EAAE,MAAM,GAAG,0BAA0B,GAAG,SAAS;IAKzG,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"}
1
+ {"version":3,"file":"ElectronHost.d.ts","sourceRoot":"","sources":["../../../src/backend/ElectronHost.ts"],"names":[],"mappings":"AAKA;;GAEG;AAGH,OAAO,KAAK,EAAE,aAAa,EAAE,+BAA+B,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAC/F,OAAO,KAAK,KAAK,cAAc,MAAM,UAAU,CAAC;AAKhD,OAAO,EAAE,UAAU,EAAuB,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACtF,OAAO,EAA8D,gBAAgB,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAC;AAyB1I;;;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,yDAAyD;IACzD,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,4GAA4G;IAC5G,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,2DAA2D;IAC3D,aAAa,CAAC,EAAE,CAAC,SAAS,GAAG,QAAQ,GAAG,aAAa,GAAG,sBAAsB,CAAC,CAAC;IAChF,wBAAwB;IACxB,cAAc,CAAC,EAAE,IAAI,CAAC,cAAc,EAAE,SAAS,GAAG,sBAAsB,GAAG,iBAAiB,GAAG,kBAAkB,GAAG,SAAS,GAAG,yBAAyB,GAAG,4BAA4B,CAAC,CAAC;CAC3L;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,CAAwB;IAChD,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,0BAA6B;IAEvD,OAAO;IAEP;;;;;;OAMG;IACH,OAAO,CAAC,MAAM,CAAC,6BAA6B;IAkB5C,OAAO,CAAC,MAAM,CAAC,WAAW;IAiD1B,qDAAqD;IACrD,WAAkB,UAAU,8BAA+B;IAE3D;;OAEG;WACW,+BAA+B,CAAC,UAAU,EAAE,MAAM,GAAG,0BAA0B,GAAG,SAAS;IAKzG,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"}
@@ -36,18 +36,19 @@ class ElectronIpc {
36
36
  * @beta
37
37
  */
38
38
  class ElectronHost {
39
+ static { this._electronFrontend = "electron://frontend/"; }
39
40
  static get ipcMain() { return this._electron?.ipcMain; }
40
41
  static get app() { return this._electron?.app; }
41
42
  static get electron() { return this._electron; }
42
43
  constructor() { }
43
44
  /**
44
- * Converts an "electron://frontend/" URL to an absolute file path.
45
+ * Converts an "electron://frontend/" URL to an "file://{absolute file path}" URL.
45
46
  *
46
47
  * We use this protocol in production builds because our frontend must be built with absolute URLs,
47
48
  * however, since we're loading everything directly from the install directory, we cannot know the
48
49
  * absolute path at build time.
49
50
  */
50
- static parseElectronUrl(requestedUrl) {
51
+ static transformElectronUrlToFileUrl(requestedUrl) {
51
52
  // Note that the "frontend/" path is arbitrary - this is just so we can handle *some* relative URLs...
52
53
  let assetPath = requestedUrl.substring(this._electronFrontend.length);
53
54
  if (assetPath.length === 0)
@@ -63,7 +64,7 @@ class ElectronHost {
63
64
  }
64
65
  if (!assetPath.startsWith(this.webResourcesPath))
65
66
  throw new Error(`Access to files outside installation directory (${this.webResourcesPath}) is prohibited`);
66
- return assetPath;
67
+ return `file://${assetPath}`;
67
68
  }
68
69
  static _openWindow(options) {
69
70
  const webPreferences = {
@@ -90,46 +91,30 @@ class ElectronHost {
90
91
  /** Monitors and saves main window size, position and maximized state */
91
92
  if (options?.storeWindowName) {
92
93
  const mainWindow = this._mainWindow;
93
- const name = options.storeWindowName;
94
- const saveWindowPosition = (key) => {
94
+ const windowName = options.storeWindowName;
95
+ const saveWindowPosition = () => {
95
96
  const bounds = mainWindow.getBounds();
96
- core_backend_1.NativeHost.settingsStore.setData(`${key}-${name}`, JSON.stringify(bounds));
97
+ core_backend_1.NativeHost.settingsStore.setData(`windowSizeAndPos-${windowName}`, JSON.stringify(bounds));
97
98
  };
98
99
  const saveMaximized = (maximized) => {
99
- if (!maximized)
100
- saveWindowPosition(this._deprecatedSizeAndPosStoreKey);
101
- core_backend_1.NativeHost.settingsStore.setData(`windowMaximized-${name}`, maximized);
100
+ core_backend_1.NativeHost.settingsStore.setData(`windowMaximized-${windowName}`, maximized);
102
101
  };
103
102
  mainWindow.on("maximize", () => saveMaximized(true));
104
103
  mainWindow.on("unmaximize", () => saveMaximized(false));
105
104
  saveMaximized(mainWindow.isMaximized());
106
- mainWindow.on("resized", () => saveWindowPosition(this._deprecatedSizeAndPosStoreKey));
107
- mainWindow.on("moved", () => saveWindowPosition(this._deprecatedSizeAndPosStoreKey));
108
- const debouncedSaveWindowSizeAndPos = debounce(() => saveWindowPosition(this._sizeAndPosStoreKey));
105
+ const debouncedSaveWindowSizeAndPos = debounce(() => saveWindowPosition());
109
106
  mainWindow.on("resize", () => debouncedSaveWindowSizeAndPos());
110
107
  mainWindow.on("move", () => debouncedSaveWindowSizeAndPos());
111
- saveWindowPosition(this._sizeAndPosStoreKey);
108
+ saveWindowPosition();
112
109
  }
113
110
  }
114
111
  /** The "main" BrowserWindow for this application. */
115
112
  static get mainWindow() { return this._mainWindow; }
116
- /**
117
- * Gets window size and position for a window, by name, from settings file, if present.
118
- * @note Size and position values in the settings file will be updated differently depending on platform.
119
- * On Linux values are only updated on window "unmaximize".
120
- * On Windows and MacOS values are also updated on window manual resize or move.
121
- * To get consistent behavior across different platforms, use [[ElectronHost.getWindowSizeAndPositionSetting]].
122
- * @deprecated in 3.6. Use [[ElectronHost.getWindowSizeAndPositionSetting]].
123
- */
124
- static getWindowSizeSetting(windowName) {
125
- const saved = core_backend_1.NativeHost.settingsStore.getString(`${this._deprecatedSizeAndPosStoreKey}-${windowName}`);
126
- return saved ? JSON.parse(saved) : undefined;
127
- }
128
113
  /**
129
114
  * Gets window size and position for a window, by name, from settings file, if present.
130
115
  */
131
116
  static getWindowSizeAndPositionSetting(windowName) {
132
- const saved = core_backend_1.NativeHost.settingsStore.getString(`${this._sizeAndPosStoreKey}-${windowName}`);
117
+ const saved = core_backend_1.NativeHost.settingsStore.getString(`windowSizeAndPos-${windowName}`);
133
118
  return saved ? JSON.parse(saved) : undefined;
134
119
  }
135
120
  /** Gets "window maximized" flag for a window, by name, from settings file if present */
@@ -168,7 +153,7 @@ class ElectronHost {
168
153
  await app.whenReady();
169
154
  if (!this._developmentServer) {
170
155
  // handle any "electron://" requests and redirect them to "file://" URLs
171
- this.electron.protocol.registerFileProtocol("electron", (request, callback) => callback(this.parseElectronUrl(request.url))); // eslint-disable-line @typescript-eslint/no-deprecated
156
+ this.electron.protocol.handle("electron", async (request) => ElectronHost.electron.net.fetch(this.transformElectronUrlToFileUrl(request.url)));
172
157
  }
173
158
  this._openWindow(windowOptions);
174
159
  }
@@ -215,9 +200,6 @@ class ElectronHost {
215
200
  }
216
201
  }
217
202
  exports.ElectronHost = ElectronHost;
218
- ElectronHost._deprecatedSizeAndPosStoreKey = "windowPos";
219
- ElectronHost._sizeAndPosStoreKey = "windowSizeAndPos";
220
- ElectronHost._electronFrontend = "electron://frontend/";
221
203
  class ElectronDialogHandler extends core_backend_1.IpcHandler {
222
204
  get channelName() { return ElectronIpcInterface_1.electronIpcStrings.dialogChannel; }
223
205
  async callDialog(method, ...args) {
@@ -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/** @packageDocumentation\r\n * @module Main\r\n */\r\n\r\n// Note: only import *types* from electron so this file can be imported by apps that sometimes use Electron and sometimes not.\r\nimport type { BrowserWindow, BrowserWindowConstructorOptions, WebPreferences } from \"electron\";\r\nimport type * as ElectronModule from \"electron\";\r\n\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, electronIpcStrings } 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]($backend) 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 readonly _deprecatedSizeAndPosStoreKey = \"windowPos\";\r\n private static readonly _sizeAndPosStoreKey = \"windowSizeAndPos\";\r\n\r\n private static _ipc: ElectronIpc;\r\n private static _developmentServer: boolean;\r\n private static _electron: typeof ElectronModule;\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.substring(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 {\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 webPreferences: 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 nodeIntegrationInWorker: false,\r\n nodeIntegrationInSubFrames: false,\r\n };\r\n\r\n const opts: BrowserWindowConstructorOptions = {\r\n ...options,\r\n autoHideMenuBar: true,\r\n icon: this.appIconPath,\r\n webPreferences,\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 = (key: string) => {\r\n const bounds: WindowSizeAndPositionProps = mainWindow.getBounds();\r\n NativeHost.settingsStore.setData(`${key}-${name}`, JSON.stringify(bounds));\r\n };\r\n const saveMaximized = (maximized: boolean) => {\r\n if (!maximized)\r\n saveWindowPosition(this._deprecatedSizeAndPosStoreKey);\r\n NativeHost.settingsStore.setData(`windowMaximized-${name}`, maximized);\r\n };\r\n\r\n mainWindow.on(\"maximize\", () => saveMaximized(true));\r\n mainWindow.on(\"unmaximize\", () => saveMaximized(false));\r\n saveMaximized(mainWindow.isMaximized());\r\n\r\n mainWindow.on(\"resized\", () => saveWindowPosition(this._deprecatedSizeAndPosStoreKey));\r\n mainWindow.on(\"moved\", () => saveWindowPosition(this._deprecatedSizeAndPosStoreKey));\r\n\r\n const debouncedSaveWindowSizeAndPos = debounce(() => saveWindowPosition(this._sizeAndPosStoreKey));\r\n mainWindow.on(\"resize\", () => debouncedSaveWindowSizeAndPos());\r\n mainWindow.on(\"move\", () => debouncedSaveWindowSizeAndPos());\r\n saveWindowPosition(this._sizeAndPosStoreKey);\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 /**\r\n * Gets window size and position for a window, by name, from settings file, if present.\r\n * @note Size and position values in the settings file will be updated differently depending on platform.\r\n * On Linux values are only updated on window \"unmaximize\".\r\n * On Windows and MacOS values are also updated on window manual resize or move.\r\n * To get consistent behavior across different platforms, use [[ElectronHost.getWindowSizeAndPositionSetting]].\r\n * @deprecated in 3.6. Use [[ElectronHost.getWindowSizeAndPositionSetting]].\r\n */\r\n public static getWindowSizeSetting(windowName: string): WindowSizeAndPositionProps | undefined {\r\n const saved = NativeHost.settingsStore.getString(`${this._deprecatedSizeAndPosStoreKey}-${windowName}`);\r\n return saved ? JSON.parse(saved) as WindowSizeAndPositionProps : undefined;\r\n }\r\n\r\n /**\r\n * Gets window size and position for a window, by name, from settings file, if present.\r\n */\r\n public static getWindowSizeAndPositionSetting(windowName: string): WindowSizeAndPositionProps | undefined {\r\n const saved = NativeHost.settingsStore.getString(`${this._sizeAndPosStoreKey}-${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-deprecated\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\"); // eslint-disable-line @typescript-eslint/no-require-imports\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 ElectronDialogHandler.register();\r\n opts.electronHost?.ipcHandlers?.forEach((ipc) => ipc.register());\r\n }\r\n }\r\n}\r\n\r\nclass ElectronDialogHandler extends IpcHandler {\r\n public get channelName() { return electronIpcStrings.dialogChannel; }\r\n public async callDialog(method: DialogModuleMethod, ...args: any) {\r\n const dialog = ElectronHost.electron.dialog;\r\n const dialogMethod = dialog[method] as (...args: any[]) => any;\r\n if (typeof dialogMethod !== \"function\")\r\n throw new IModelError(IModelStatus.FunctionNotFound, `illegal electron dialog method`);\r\n\r\n return dialogMethod.call(dialog, ...args);\r\n }\r\n}\r\n\r\nfunction debounce(func: (...args: any[]) => any, ms: number = 200) {\r\n let timeout: NodeJS.Timeout;\r\n return function (this: any, ...args: any[]) {\r\n clearTimeout(timeout);\r\n timeout = setTimeout(() => {\r\n func.apply(this, args);\r\n }, ms);\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/** @packageDocumentation\r\n * @module Main\r\n */\r\n\r\n// Note: only import *types* from electron so this file can be imported by apps that sometimes use Electron and sometimes not.\r\nimport type { BrowserWindow, BrowserWindowConstructorOptions, WebPreferences } from \"electron\";\r\nimport type * as ElectronModule from \"electron\";\r\n\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, electronIpcStrings } 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]($backend) 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 /** Name used to construct key for saving window size, position and maximize status to the settings store */\r\n storeWindowName?: string;\r\n /** The style of window title bar. Default is `default`. */\r\n titleBarStyle?: (\"default\" | \"hidden\" | \"hiddenInset\" | \"customButtonsOnHover\");\r\n /** Web page settings */\r\n webPreferences?: Omit<WebPreferences, \"preload\" | \"experimentalFeatures\" | \"nodeIntegration\" | \"contextIsolation\" | \"sandbox\" | \"nodeIntegrationInWorker\" | \"nodeIntegrationInSubFrames\">;\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 ElectronModule;\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 \"file://{absolute file path}\" URL.\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 transformElectronUrlToFileUrl(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.substring(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 {\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 `file://${assetPath}`;\r\n }\r\n\r\n private static _openWindow(options?: ElectronHostWindowOptions) {\r\n const webPreferences: 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 nodeIntegrationInWorker: false,\r\n nodeIntegrationInSubFrames: false,\r\n };\r\n\r\n const opts: BrowserWindowConstructorOptions = {\r\n ...options,\r\n autoHideMenuBar: true,\r\n icon: this.appIconPath,\r\n webPreferences,\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 windowName = options.storeWindowName;\r\n const saveWindowPosition = () => {\r\n const bounds: WindowSizeAndPositionProps = mainWindow.getBounds();\r\n NativeHost.settingsStore.setData(`windowSizeAndPos-${windowName}`, JSON.stringify(bounds));\r\n };\r\n const saveMaximized = (maximized: boolean) => {\r\n NativeHost.settingsStore.setData(`windowMaximized-${windowName}`, maximized);\r\n };\r\n\r\n mainWindow.on(\"maximize\", () => saveMaximized(true));\r\n mainWindow.on(\"unmaximize\", () => saveMaximized(false));\r\n saveMaximized(mainWindow.isMaximized());\r\n\r\n const debouncedSaveWindowSizeAndPos = debounce(() => saveWindowPosition());\r\n mainWindow.on(\"resize\", () => debouncedSaveWindowSizeAndPos());\r\n mainWindow.on(\"move\", () => debouncedSaveWindowSizeAndPos());\r\n saveWindowPosition();\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 /**\r\n * Gets window size and position for a window, by name, from settings file, if present.\r\n */\r\n public static getWindowSizeAndPositionSetting(windowName: string): WindowSizeAndPositionProps | undefined {\r\n const saved = NativeHost.settingsStore.getString(`windowSizeAndPos-${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.handle(\"electron\", async (request) => ElectronHost.electron.net.fetch(this.transformElectronUrlToFileUrl(request.url)));\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\"); // eslint-disable-line @typescript-eslint/no-require-imports\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 ElectronDialogHandler.register();\r\n opts.electronHost?.ipcHandlers?.forEach((ipc) => ipc.register());\r\n }\r\n }\r\n}\r\n\r\nclass ElectronDialogHandler extends IpcHandler {\r\n public get channelName() { return electronIpcStrings.dialogChannel; }\r\n public async callDialog(method: DialogModuleMethod, ...args: any) {\r\n const dialog = ElectronHost.electron.dialog;\r\n const dialogMethod = dialog[method] as (...args: any[]) => any;\r\n if (typeof dialogMethod !== \"function\")\r\n throw new IModelError(IModelStatus.FunctionNotFound, `illegal electron dialog method`);\r\n\r\n return dialogMethod.call(dialog, ...args);\r\n }\r\n}\r\n\r\nfunction debounce(func: (...args: any[]) => any, ms: number = 200) {\r\n let timeout: NodeJS.Timeout;\r\n return function (this: any, ...args: any[]) {\r\n clearTimeout(timeout);\r\n timeout = setTimeout(() => {\r\n func.apply(this, args);\r\n }, ms);\r\n };\r\n}\r\n"]}
@@ -16,6 +16,7 @@ const ElectronRpcRequest_1 = require("./ElectronRpcRequest");
16
16
  * @internal
17
17
  */
18
18
  class ElectronRpcProtocol extends core_common_1.RpcProtocol {
19
+ static { this.instances = new Map(); }
19
20
  /** Constructs an Electron protocol. */
20
21
  constructor(configuration, ipcSocket) {
21
22
  super(configuration);
@@ -54,5 +55,4 @@ class ElectronRpcProtocol extends core_common_1.RpcProtocol {
54
55
  }
55
56
  }
56
57
  exports.ElectronRpcProtocol = ElectronRpcProtocol;
57
- ElectronRpcProtocol.instances = new Map();
58
58
  //# sourceMappingURL=ElectronRpcProtocol.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ElectronRpcProtocol.js","sourceRoot":"","sources":["../../../src/common/ElectronRpcProtocol.ts"],"names":[],"mappings":";AAAA;;;+FAG+F;AAC/F;;GAEG;;;AAEH,sDAAoD;AACpD,oDAA+G;AAC/G,iEAAkG;AAElG,6DAA0D;AAE1D;;GAEG;AACH,MAAa,mBAAoB,SAAQ,yBAAW;IAgBlD,uCAAuC;IACvC,YAAmB,aAAuC,EAAE,SAAoB;QAC9E,KAAK,CAAC,aAAa,CAAC,CAAC;QAdvB,+CAA+C;QAC/B,gBAAW,GAAG,uCAAkB,CAAC;QAEjD,8DAA8D;QAC9C,2BAAsB,GAAG,EAAE,GAAG,IAAI,GAAG,IAAI,CAAC;QAE1D,gBAAgB;QACT,aAAQ,GAAoC,IAAI,GAAG,EAAE,CAAC;QAQ3D,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;QAC3B,IAAI,CAAC,SAAS,GAAG,IAAA,oCAAa,EAAC,IAAI,CAAC,CAAC;IACvC,CAAC;IAED,gBAAgB;IACA,sBAAsB,CAAC,UAAkC,EAAE,OAAqB;QAC9F,IAAI,CAAC,iBAAiB,CAAC,UAAU,CAAC,CAAC;IACrC,CAAC;IAED,gBAAgB;IACA,oBAAoB,CAAC,UAAkC,EAAE,KAAmB;QAC1F,IAAI,CAAC,iBAAiB,CAAC,UAAU,CAAC,CAAC;IACrC,CAAC;IAED,gBAAgB;IACA,qBAAqB,CAAC,UAAkC,EAAE,OAAqB;QAC7F,IAAI,CAAC,cAAc,CAAC,UAAU,CAAC,CAAC;IAClC,CAAC;IAED,gBAAgB;IACA,mBAAmB,CAAC,UAAkC,EAAE,KAAmB;QACzF,IAAI,CAAC,cAAc,CAAC,UAAU,CAAC,CAAC;IAClC,CAAC;IAEO,iBAAiB,CAAC,UAAkC;QAC1D,IAAI,mBAAmB,CAAC,SAAS,CAAC,GAAG,CAAC,UAAU,CAAC,aAAa,CAAC;YAC7D,MAAM,IAAI,yBAAW,CAAC,4BAAa,CAAC,KAAK,EAAE,kBAAkB,UAAU,CAAC,aAAa,2CAA2C,CAAC,CAAC;QAEpI,mBAAmB,CAAC,SAAS,CAAC,GAAG,CAAC,UAAU,CAAC,aAAa,EAAE,IAAI,CAAC,CAAC;IACpE,CAAC;IAEO,cAAc,CAAC,UAAkC;QACvD,mBAAmB,CAAC,SAAS,CAAC,MAAM,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC;IACjE,CAAC;;AApDH,kDAqDC;AApDe,6BAAS,GAAqC,IAAI,GAAG,EAAE,AAA9C,CAA+C","sourcesContent":["/*---------------------------------------------------------------------------------------------\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n* See LICENSE.md in the project root for license terms and full copyright notice.\n*--------------------------------------------------------------------------------------------*/\n/** @packageDocumentation\n * @module RpcInterface\n */\n\nimport { BentleyStatus } from \"@itwin/core-bentley\";\nimport { IModelError, IpcSocket, RpcInterface, RpcInterfaceDefinition, RpcProtocol } from \"@itwin/core-common\";\nimport { ElectronIpcTransport, initializeIpc, IpcTransportMessage } from \"./ElectronIpcTransport\";\nimport { ElectronRpcConfiguration } from \"./ElectronRpcManager\";\nimport { ElectronRpcRequest } from \"./ElectronRpcRequest\";\n\n/** RPC interface protocol for an Electron-based application.\n * @internal\n */\nexport class ElectronRpcProtocol extends RpcProtocol {\n public static instances: Map<string, ElectronRpcProtocol> = new Map();\n public ipcSocket: IpcSocket;\n\n /** The RPC request class for this protocol. */\n public readonly requestType = ElectronRpcRequest;\n\n /** Specifies where to break large binary request payloads. */\n public override transferChunkThreshold = 48 * 1024 * 1024;\n\n /** @internal */\n public requests: Map<string, ElectronRpcRequest> = new Map();\n\n /** @internal */\n public readonly transport: ElectronIpcTransport<IpcTransportMessage, IpcTransportMessage>;\n\n /** Constructs an Electron protocol. */\n public constructor(configuration: ElectronRpcConfiguration, ipcSocket: IpcSocket) {\n super(configuration);\n this.ipcSocket = ipcSocket;\n this.transport = initializeIpc(this);\n }\n\n /** @internal */\n public override onRpcClientInitialized(definition: RpcInterfaceDefinition, _client: RpcInterface): void {\n this.registerInterface(definition);\n }\n\n /** @internal */\n public override onRpcImplInitialized(definition: RpcInterfaceDefinition, _impl: RpcInterface): void {\n this.registerInterface(definition);\n }\n\n /** @internal */\n public override onRpcClientTerminated(definition: RpcInterfaceDefinition, _client: RpcInterface): void {\n this.purgeInterface(definition);\n }\n\n /** @internal */\n public override onRpcImplTerminated(definition: RpcInterfaceDefinition, _impl: RpcInterface): void {\n this.purgeInterface(definition);\n }\n\n private registerInterface(definition: RpcInterfaceDefinition) {\n if (ElectronRpcProtocol.instances.has(definition.interfaceName))\n throw new IModelError(BentleyStatus.ERROR, `RPC interface \"${definition.interfaceName}\"\" is already associated with a protocol.`);\n\n ElectronRpcProtocol.instances.set(definition.interfaceName, this);\n }\n\n private purgeInterface(definition: RpcInterfaceDefinition) {\n ElectronRpcProtocol.instances.delete(definition.interfaceName);\n }\n}\n"]}
1
+ {"version":3,"file":"ElectronRpcProtocol.js","sourceRoot":"","sources":["../../../src/common/ElectronRpcProtocol.ts"],"names":[],"mappings":";AAAA;;;+FAG+F;AAC/F;;GAEG;;;AAEH,sDAAoD;AACpD,oDAA+G;AAC/G,iEAAkG;AAElG,6DAA0D;AAE1D;;GAEG;AACH,MAAa,mBAAoB,SAAQ,yBAAW;aACpC,cAAS,GAAqC,IAAI,GAAG,EAAE,AAA9C,CAA+C;IAetE,uCAAuC;IACvC,YAAmB,aAAuC,EAAE,SAAoB;QAC9E,KAAK,CAAC,aAAa,CAAC,CAAC;QAdvB,+CAA+C;QAC/B,gBAAW,GAAG,uCAAkB,CAAC;QAEjD,8DAA8D;QAC9C,2BAAsB,GAAG,EAAE,GAAG,IAAI,GAAG,IAAI,CAAC;QAE1D,gBAAgB;QACT,aAAQ,GAAoC,IAAI,GAAG,EAAE,CAAC;QAQ3D,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;QAC3B,IAAI,CAAC,SAAS,GAAG,IAAA,oCAAa,EAAC,IAAI,CAAC,CAAC;IACvC,CAAC;IAED,gBAAgB;IACA,sBAAsB,CAAC,UAAkC,EAAE,OAAqB;QAC9F,IAAI,CAAC,iBAAiB,CAAC,UAAU,CAAC,CAAC;IACrC,CAAC;IAED,gBAAgB;IACA,oBAAoB,CAAC,UAAkC,EAAE,KAAmB;QAC1F,IAAI,CAAC,iBAAiB,CAAC,UAAU,CAAC,CAAC;IACrC,CAAC;IAED,gBAAgB;IACA,qBAAqB,CAAC,UAAkC,EAAE,OAAqB;QAC7F,IAAI,CAAC,cAAc,CAAC,UAAU,CAAC,CAAC;IAClC,CAAC;IAED,gBAAgB;IACA,mBAAmB,CAAC,UAAkC,EAAE,KAAmB;QACzF,IAAI,CAAC,cAAc,CAAC,UAAU,CAAC,CAAC;IAClC,CAAC;IAEO,iBAAiB,CAAC,UAAkC;QAC1D,IAAI,mBAAmB,CAAC,SAAS,CAAC,GAAG,CAAC,UAAU,CAAC,aAAa,CAAC;YAC7D,MAAM,IAAI,yBAAW,CAAC,4BAAa,CAAC,KAAK,EAAE,kBAAkB,UAAU,CAAC,aAAa,2CAA2C,CAAC,CAAC;QAEpI,mBAAmB,CAAC,SAAS,CAAC,GAAG,CAAC,UAAU,CAAC,aAAa,EAAE,IAAI,CAAC,CAAC;IACpE,CAAC;IAEO,cAAc,CAAC,UAAkC;QACvD,mBAAmB,CAAC,SAAS,CAAC,MAAM,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC;IACjE,CAAC;;AApDH,kDAqDC","sourcesContent":["/*---------------------------------------------------------------------------------------------\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n* See LICENSE.md in the project root for license terms and full copyright notice.\n*--------------------------------------------------------------------------------------------*/\n/** @packageDocumentation\n * @module RpcInterface\n */\n\nimport { BentleyStatus } from \"@itwin/core-bentley\";\nimport { IModelError, IpcSocket, RpcInterface, RpcInterfaceDefinition, RpcProtocol } from \"@itwin/core-common\";\nimport { ElectronIpcTransport, initializeIpc, IpcTransportMessage } from \"./ElectronIpcTransport\";\nimport { ElectronRpcConfiguration } from \"./ElectronRpcManager\";\nimport { ElectronRpcRequest } from \"./ElectronRpcRequest\";\n\n/** RPC interface protocol for an Electron-based application.\n * @internal\n */\nexport class ElectronRpcProtocol extends RpcProtocol {\n public static instances: Map<string, ElectronRpcProtocol> = new Map();\n public ipcSocket: IpcSocket;\n\n /** The RPC request class for this protocol. */\n public readonly requestType = ElectronRpcRequest;\n\n /** Specifies where to break large binary request payloads. */\n public override transferChunkThreshold = 48 * 1024 * 1024;\n\n /** @internal */\n public requests: Map<string, ElectronRpcRequest> = new Map();\n\n /** @internal */\n public readonly transport: ElectronIpcTransport<IpcTransportMessage, IpcTransportMessage>;\n\n /** Constructs an Electron protocol. */\n public constructor(configuration: ElectronRpcConfiguration, ipcSocket: IpcSocket) {\n super(configuration);\n this.ipcSocket = ipcSocket;\n this.transport = initializeIpc(this);\n }\n\n /** @internal */\n public override onRpcClientInitialized(definition: RpcInterfaceDefinition, _client: RpcInterface): void {\n this.registerInterface(definition);\n }\n\n /** @internal */\n public override onRpcImplInitialized(definition: RpcInterfaceDefinition, _impl: RpcInterface): void {\n this.registerInterface(definition);\n }\n\n /** @internal */\n public override onRpcClientTerminated(definition: RpcInterfaceDefinition, _client: RpcInterface): void {\n this.purgeInterface(definition);\n }\n\n /** @internal */\n public override onRpcImplTerminated(definition: RpcInterfaceDefinition, _impl: RpcInterface): void {\n this.purgeInterface(definition);\n }\n\n private registerInterface(definition: RpcInterfaceDefinition) {\n if (ElectronRpcProtocol.instances.has(definition.interfaceName))\n throw new IModelError(BentleyStatus.ERROR, `RPC interface \"${definition.interfaceName}\"\" is already associated with a protocol.`);\n\n ElectronRpcProtocol.instances.set(definition.interfaceName, this);\n }\n\n private purgeInterface(definition: RpcInterfaceDefinition) {\n ElectronRpcProtocol.instances.delete(definition.interfaceName);\n }\n}\n"]}
@@ -1,9 +1,4 @@
1
- /** @packageDocumentation
2
- * @module Renderer
3
- */
4
- import { PromiseReturnType } from "@itwin/core-bentley";
5
1
  import { NativeAppOpts } from "@itwin/core-frontend";
6
- import { DialogModuleMethod } from "../common/ElectronIpcInterface";
7
2
  import type { ITwinElectronApi } from "../common/ITwinElectronApi";
8
3
  declare global {
9
4
  interface Window {
@@ -26,13 +21,6 @@ export declare class ElectronApp {
26
21
  */
27
22
  static startup(opts?: ElectronAppOpts): Promise<void>;
28
23
  static shutdown(): Promise<void>;
29
- /**
30
- * Call an asynchronous method in the [Electron.Dialog](https://www.electronjs.org/docs/api/dialog) interface from a previously initialized ElectronFrontend.
31
- * @param methodName the name of the method to call
32
- * @param args arguments to method
33
- * @deprecated in 3.x. use [[dialogIpc]]
34
- */
35
- static callDialog<T extends DialogModuleMethod>(methodName: T, ...args: Parameters<Electron.Dialog[T]>): Promise<PromiseReturnType<Electron.Dialog[T]>>;
36
24
  /** Proxy object for calling methods of `Electron.Dialog` */
37
25
  static dialogIpc: import("@itwin/core-bentley").PickAsyncMethods<Electron.Dialog>;
38
26
  }
@@ -1 +1 @@
1
- {"version":3,"file":"ElectronApp.d.ts","sourceRoot":"","sources":["../../../src/frontend/ElectronApp.ts"],"names":[],"mappings":"AAKA;;GAEG;AAEH,OAAO,EAAmB,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAEzE,OAAO,EAAsC,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAEzF,OAAO,EAAE,kBAAkB,EAAsB,MAAM,gCAAgC,CAAC;AAExF,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,MAAM,MAAM,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;;;;;OAKG;WACiB,UAAU,CAAC,CAAC,SAAS,kBAAkB,EAAE,UAAU,EAAE,CAAC,EAAE,GAAG,IAAI,EAAE,UAAU,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;IAInH,4DAA4D;IAC5D,OAAc,SAAS,kEAAgG;CACxH"}
1
+ {"version":3,"file":"ElectronApp.d.ts","sourceRoot":"","sources":["../../../src/frontend/ElectronApp.ts"],"names":[],"mappings":"AAWA,OAAO,EAAsC,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAIzF,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,MAAM,MAAM,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,4DAA4D;IAC5D,OAAc,SAAS,kEAAgG;CACxH"}
@@ -61,17 +61,8 @@ class ElectronApp {
61
61
  await core_frontend_1.NativeApp.shutdown();
62
62
  ElectronRpcManager_1.ElectronRpcManager.terminateFrontend();
63
63
  }
64
- /**
65
- * Call an asynchronous method in the [Electron.Dialog](https://www.electronjs.org/docs/api/dialog) interface from a previously initialized ElectronFrontend.
66
- * @param methodName the name of the method to call
67
- * @param args arguments to method
68
- * @deprecated in 3.x. use [[dialogIpc]]
69
- */
70
- static async callDialog(methodName, ...args) {
71
- return core_frontend_1.IpcApp[core_frontend_1._callIpcChannel](ElectronIpcInterface_1.electronIpcStrings.dialogChannel, "callDialog", methodName, ...args);
72
- }
64
+ /** Proxy object for calling methods of `Electron.Dialog` */
65
+ static { this.dialogIpc = core_frontend_1.IpcApp.makeIpcFunctionProxy(ElectronIpcInterface_1.electronIpcStrings.dialogChannel, "callDialog"); }
73
66
  }
74
67
  exports.ElectronApp = ElectronApp;
75
- /** Proxy object for calling methods of `Electron.Dialog` */
76
- ElectronApp.dialogIpc = core_frontend_1.IpcApp.makeIpcFunctionProxy(ElectronIpcInterface_1.electronIpcStrings.dialogChannel, "callDialog");
77
68
  //# sourceMappingURL=ElectronApp.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ElectronApp.js","sourceRoot":"","sources":["../../../src/frontend/ElectronApp.ts"],"names":[],"mappings":";AAAA;;;+FAG+F;;;AAE/F;;GAEG;AAEH,sDAAyE;AAEzE,wDAAyF;AAEzF,yEAAwF;AACxF,qEAAkE;AASlE;;GAEG;AACH,MAAM,WAAW;IAER,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;IACD;QACE,sJAAsJ;QACtJ,iGAAiG;QACjG,iEAAiE;QACjE,IAAI,CAAC,IAAI,GAAG,MAAM,CAAC,OAAO,IAAI,OAAO,CAAC,UAAU,CAAC,CAAC,WAAW,CAAC;IAChE,CAAC;CACF;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,CAAC;YAClB,IAAI,CAAC,IAAI,GAAG,IAAI,WAAW,EAAE,CAAC;YAC9B,uCAAkB,CAAC,kBAAkB,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,SAAS,EAAE,aAAa,CAAC,CAAC,CAAC,uDAAuD;QAC3I,CAAC;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;;;;;OAKG;IACI,MAAM,CAAC,KAAK,CAAC,UAAU,CAA+B,UAAa,EAAE,GAAG,IAAoC;QACjH,OAAO,sBAAM,CAAC,+BAAe,CAAC,CAAC,yCAAkB,CAAC,aAAa,EAAE,YAAY,EAAE,UAAU,EAAE,GAAG,IAAI,CAA0C,CAAC;IAC/I,CAAC;;AAjCH,kCAqCC;AAFC,4DAA4D;AAC9C,qBAAS,GAAG,sBAAM,CAAC,oBAAoB,CAAkB,yCAAkB,CAAC,aAAa,EAAE,YAAY,CAAC,CAAC","sourcesContent":["/*---------------------------------------------------------------------------------------------\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n* See LICENSE.md in the project root for license terms and full copyright notice.\n*--------------------------------------------------------------------------------------------*/\n\n/** @packageDocumentation\n * @module Renderer\n */\n\nimport { ProcessDetector, PromiseReturnType } from \"@itwin/core-bentley\";\nimport { IpcListener, IpcSocketFrontend } from \"@itwin/core-common\";\nimport { _callIpcChannel, IpcApp, NativeApp, NativeAppOpts } from \"@itwin/core-frontend\";\nimport type { IpcRenderer } from \"electron\";\nimport { DialogModuleMethod, electronIpcStrings } from \"../common/ElectronIpcInterface\";\nimport { ElectronRpcManager } from \"../common/ElectronRpcManager\";\nimport type { ITwinElectronApi } from \"../common/ITwinElectronApi\";\n\ndeclare global {\n interface Window {\n itwinjs: ITwinElectronApi;\n }\n}\n\n/**\n * Frontend Ipc support for Electron apps.\n */\nclass ElectronIpc implements IpcSocketFrontend {\n private _api: ITwinElectronApi | IpcRenderer;\n public addListener(channelName: string, listener: IpcListener) {\n this._api.addListener(channelName, listener);\n return () => this._api.removeListener(channelName, listener);\n }\n public removeListener(channelName: string, listener: IpcListener) {\n this._api.removeListener(channelName, listener);\n }\n public send(channel: string, ...data: any[]) {\n this._api.send(channel, ...data);\n }\n public async invoke(channel: string, ...args: any[]) {\n return this._api.invoke(channel, ...args);\n }\n constructor() {\n // use the methods on window.itwinjs exposed by ElectronPreload.ts, or ipcRenderer directly if running with nodeIntegration=true (**only** for tests).\n // Note that `require(\"electron\")` doesn't work with nodeIntegration=false - that's what it stops\n // eslint-disable-next-line @typescript-eslint/no-require-imports\n this._api = window.itwinjs ?? require(\"electron\").ipcRenderer;\n }\n}\n\n/** @beta */\nexport type ElectronAppOpts = NativeAppOpts;\n\n/**\n * Frontend of an Electron App.\n * @beta\n */\nexport class ElectronApp {\n private static _ipc?: ElectronIpc;\n public static get isValid(): boolean { return undefined !== this._ipc; }\n\n /**\n * Start the frontend of an Electron application.\n * @param opts Options for your ElectronApp\n * @note This method must only be called from the frontend of an Electron app (i.e. when [ProcessDetector.isElectronAppFrontend]($bentley) is `true`).\n */\n public static async startup(opts?: ElectronAppOpts) {\n if (!ProcessDetector.isElectronAppFrontend)\n throw new Error(\"Not running under Electron\");\n if (!this.isValid) {\n this._ipc = new ElectronIpc();\n ElectronRpcManager.initializeFrontend(this._ipc, opts?.iModelApp?.rpcInterfaces); // eslint-disable-line @typescript-eslint/no-deprecated\n }\n await NativeApp.startup(this._ipc!, opts);\n }\n\n public static async shutdown() {\n this._ipc = undefined;\n await NativeApp.shutdown();\n ElectronRpcManager.terminateFrontend();\n }\n\n /**\n * Call an asynchronous method in the [Electron.Dialog](https://www.electronjs.org/docs/api/dialog) interface from a previously initialized ElectronFrontend.\n * @param methodName the name of the method to call\n * @param args arguments to method\n * @deprecated in 3.x. use [[dialogIpc]]\n */\n public static async callDialog<T extends DialogModuleMethod>(methodName: T, ...args: Parameters<Electron.Dialog[T]>) {\n return IpcApp[_callIpcChannel](electronIpcStrings.dialogChannel, \"callDialog\", methodName, ...args) as PromiseReturnType<Electron.Dialog[T]>;\n }\n\n /** Proxy object for calling methods of `Electron.Dialog` */\n public static dialogIpc = IpcApp.makeIpcFunctionProxy<Electron.Dialog>(electronIpcStrings.dialogChannel, \"callDialog\");\n}\n"]}
1
+ {"version":3,"file":"ElectronApp.js","sourceRoot":"","sources":["../../../src/frontend/ElectronApp.ts"],"names":[],"mappings":";AAAA;;;+FAG+F;;;AAE/F;;GAEG;AAEH,sDAAsD;AAEtD,wDAAyF;AAEzF,yEAAoE;AACpE,qEAAkE;AASlE;;GAEG;AACH,MAAM,WAAW;IAER,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;IACD;QACE,sJAAsJ;QACtJ,iGAAiG;QACjG,iEAAiE;QACjE,IAAI,CAAC,IAAI,GAAG,MAAM,CAAC,OAAO,IAAI,OAAO,CAAC,UAAU,CAAC,CAAC,WAAW,CAAC;IAChE,CAAC;CACF;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,CAAC;YAClB,IAAI,CAAC,IAAI,GAAG,IAAI,WAAW,EAAE,CAAC;YAC9B,uCAAkB,CAAC,kBAAkB,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,SAAS,EAAE,aAAa,CAAC,CAAC,CAAC,uDAAuD;QAC3I,CAAC;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,4DAA4D;aAC9C,cAAS,GAAG,sBAAM,CAAC,oBAAoB,CAAkB,yCAAkB,CAAC,aAAa,EAAE,YAAY,CAAC,CAAC;;AA1BzH,kCA2BC","sourcesContent":["/*---------------------------------------------------------------------------------------------\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n* See LICENSE.md in the project root for license terms and full copyright notice.\n*--------------------------------------------------------------------------------------------*/\n\n/** @packageDocumentation\n * @module Renderer\n */\n\nimport { ProcessDetector } from \"@itwin/core-bentley\";\nimport { IpcListener, IpcSocketFrontend } from \"@itwin/core-common\";\nimport { _callIpcChannel, IpcApp, NativeApp, NativeAppOpts } from \"@itwin/core-frontend\";\nimport type { IpcRenderer } from \"electron\";\nimport { electronIpcStrings } from \"../common/ElectronIpcInterface\";\nimport { ElectronRpcManager } from \"../common/ElectronRpcManager\";\nimport type { ITwinElectronApi } from \"../common/ITwinElectronApi\";\n\ndeclare global {\n interface Window {\n itwinjs: ITwinElectronApi;\n }\n}\n\n/**\n * Frontend Ipc support for Electron apps.\n */\nclass ElectronIpc implements IpcSocketFrontend {\n private _api: ITwinElectronApi | IpcRenderer;\n public addListener(channelName: string, listener: IpcListener) {\n this._api.addListener(channelName, listener);\n return () => this._api.removeListener(channelName, listener);\n }\n public removeListener(channelName: string, listener: IpcListener) {\n this._api.removeListener(channelName, listener);\n }\n public send(channel: string, ...data: any[]) {\n this._api.send(channel, ...data);\n }\n public async invoke(channel: string, ...args: any[]) {\n return this._api.invoke(channel, ...args);\n }\n constructor() {\n // use the methods on window.itwinjs exposed by ElectronPreload.ts, or ipcRenderer directly if running with nodeIntegration=true (**only** for tests).\n // Note that `require(\"electron\")` doesn't work with nodeIntegration=false - that's what it stops\n // eslint-disable-next-line @typescript-eslint/no-require-imports\n this._api = window.itwinjs ?? require(\"electron\").ipcRenderer;\n }\n}\n\n/** @beta */\nexport type ElectronAppOpts = NativeAppOpts;\n\n/**\n * Frontend of an Electron App.\n * @beta\n */\nexport class ElectronApp {\n private static _ipc?: ElectronIpc;\n public static get isValid(): boolean { return undefined !== this._ipc; }\n\n /**\n * Start the frontend of an Electron application.\n * @param opts Options for your ElectronApp\n * @note This method must only be called from the frontend of an Electron app (i.e. when [ProcessDetector.isElectronAppFrontend]($bentley) is `true`).\n */\n public static async startup(opts?: ElectronAppOpts) {\n if (!ProcessDetector.isElectronAppFrontend)\n throw new Error(\"Not running under Electron\");\n if (!this.isValid) {\n this._ipc = new ElectronIpc();\n ElectronRpcManager.initializeFrontend(this._ipc, opts?.iModelApp?.rpcInterfaces); // eslint-disable-line @typescript-eslint/no-deprecated\n }\n await NativeApp.startup(this._ipc!, opts);\n }\n\n public static async shutdown() {\n this._ipc = undefined;\n await NativeApp.shutdown();\n ElectronRpcManager.terminateFrontend();\n }\n\n /** Proxy object for calling methods of `Electron.Dialog` */\n public static dialogIpc = IpcApp.makeIpcFunctionProxy<Electron.Dialog>(electronIpcStrings.dialogChannel, \"callDialog\");\n}\n"]}
package/package.json CHANGED
@@ -1,10 +1,10 @@
1
1
  {
2
2
  "name": "@itwin/core-electron",
3
- "version": "5.0.0-dev.4",
3
+ "version": "5.0.0-dev.40",
4
4
  "description": "iTwin.js ElectronHost and ElectronApp",
5
5
  "license": "MIT",
6
6
  "engines": {
7
- "node": "^18.0.0 || ^20.0.0 || ^22.0.0"
7
+ "node": "^20.0.0 || ^22.0.0"
8
8
  },
9
9
  "repository": {
10
10
  "type": "git",
@@ -21,18 +21,19 @@
21
21
  "url": "http://www.bentley.com"
22
22
  },
23
23
  "peerDependencies": {
24
- "@itwin/core-backend": "^5.0.0-dev.4",
25
- "@itwin/core-bentley": "^5.0.0-dev.4",
26
- "@itwin/core-common": "^5.0.0-dev.4",
27
- "@itwin/core-frontend": "^5.0.0-dev.4",
28
- "electron": ">=23.0.0 <34.0.0"
24
+ "electron": "^33.0.0",
25
+ "@itwin/core-backend": "5.0.0-dev.40",
26
+ "@itwin/core-bentley": "5.0.0-dev.40",
27
+ "@itwin/core-common": "5.0.0-dev.40",
28
+ "@itwin/core-frontend": "5.0.0-dev.40"
29
29
  },
30
30
  "devDependencies": {
31
31
  "@itwin/eslint-plugin": "5.0.0-dev.1",
32
32
  "@types/chai": "4.3.1",
33
33
  "@types/mocha": "^10.0.6",
34
- "@types/node": "~18.16.20",
34
+ "@types/node": "~20.9.5",
35
35
  "chai": "^4.3.10",
36
+ "cpx2": "^3.0.0",
36
37
  "electron": "^33.0.0",
37
38
  "eslint": "^9.13.0",
38
39
  "glob": "^10.3.12",
@@ -40,25 +41,26 @@
40
41
  "rimraf": "^3.0.2",
41
42
  "source-map-loader": "^4.0.0",
42
43
  "typescript": "~5.6.2",
43
- "webpack": "^5.76.0",
44
+ "webpack": "^5.97.1",
44
45
  "webpack-cli": "^5.0.1",
45
- "@itwin/certa": "5.0.0-dev.4",
46
- "@itwin/core-bentley": "5.0.0-dev.4",
47
- "@itwin/build-tools": "5.0.0-dev.4",
48
- "@itwin/core-backend": "5.0.0-dev.4",
49
- "@itwin/core-common": "5.0.0-dev.4",
50
- "@itwin/core-frontend": "5.0.0-dev.4"
46
+ "@itwin/build-tools": "5.0.0-dev.40",
47
+ "@itwin/core-common": "5.0.0-dev.40",
48
+ "@itwin/certa": "5.0.0-dev.40",
49
+ "@itwin/core-backend": "5.0.0-dev.40",
50
+ "@itwin/core-bentley": "5.0.0-dev.40",
51
+ "@itwin/core-frontend": "5.0.0-dev.40"
51
52
  },
52
53
  "dependencies": {
53
54
  "@openid/appauth": "^1.2.6",
54
55
  "open": "^7.0.0",
55
- "username": "^5.1.0"
56
+ "username": "^7.0.0"
56
57
  },
57
58
  "scripts": {
58
- "build": "npm run -s build:cjs && npm run -s webpack:test",
59
+ "build": "npm run -s build:cjs && npm run -s webpack:test && npm run -s copy:test-assets",
59
60
  "build:cjs": "tsc 1>&2 --outDir lib/cjs",
61
+ "copy:test-assets": "cpx \"./src/test/assets/**/*\" ./lib/cjs/test/assets",
60
62
  "clean": "rimraf lib .rush/temp/package-deps*.json",
61
- "docs": "betools docs --includes=../../generated-docs/extract --json=../../generated-docs/core/core-electron/file.json --tsIndexFile=./__DOC_ONLY__.ts --onlyJson",
63
+ "docs": "betools docs --json=../../generated-docs/core/core-electron/file.json --tsIndexFile=./__DOC_ONLY__.ts --onlyJson",
62
64
  "extract-api": "betools extract-api --entry=__DOC_ONLY__",
63
65
  "lint": "eslint \"./src/**/*.ts\" 1>&2",
64
66
  "test": "",