aboutsummaryrefslogtreecommitdiffstats
path: root/packages/service-preload/src/index.ts
diff options
context:
space:
mode:
authorLibravatar Kristóf Marussy <kristof@marussy.com>2022-04-08 02:10:22 +0200
committerLibravatar Kristóf Marussy <kristof@marussy.com>2022-05-16 00:55:00 +0200
commitab1cda612cf6d427bffb66d5674a3673eb958e50 (patch)
treeaeb01a0b431ca850b75d276af745bde807851839 /packages/service-preload/src/index.ts
parentfix(main): Do not show spurious abort error (diff)
downloadsophie-ab1cda612cf6d427bffb66d5674a3673eb958e50.tar.gz
sophie-ab1cda612cf6d427bffb66d5674a3673eb958e50.tar.zst
sophie-ab1cda612cf6d427bffb66d5674a3673eb958e50.zip
feat(service-preload): Embed service-inject
Embed the service-inject script into the service-preload script to avoid having to load it manually and reduce IPC communication when a service loads. Signed-off-by: Kristóf Marussy <kristof@marussy.com>
Diffstat (limited to 'packages/service-preload/src/index.ts')
-rw-r--r--packages/service-preload/src/index.ts35
1 files changed, 16 insertions, 19 deletions
diff --git a/packages/service-preload/src/index.ts b/packages/service-preload/src/index.ts
index a49a3a4..99d02ec 100644
--- a/packages/service-preload/src/index.ts
+++ b/packages/service-preload/src/index.ts
@@ -18,9 +18,10 @@
18 * SPDX-License-Identifier: AGPL-3.0-only 18 * SPDX-License-Identifier: AGPL-3.0-only
19 */ 19 */
20 20
21import { ServiceToMainIpcMessage, WebSource } from '@sophie/service-shared';
22import colorString from 'color-string'; 21import colorString from 'color-string';
23import { ipcRenderer, webFrame } from 'electron'; 22import { webFrame } from 'electron';
23// eslint-disable-next-line import/no-unresolved -- Synthetic import provided by an eslint plugin.
24import injectSource from 'sophie-src:@sophie/service-inject';
24 25
25const DEFAULT_BG_COLOR = '#fff'; 26const DEFAULT_BG_COLOR = '#fff';
26 27
@@ -79,35 +80,31 @@ if (webFrame.parent === null) {
79} 80}
80 81
81/** 82/**
82 * Fetches and executes the service inject script in the isolated world. 83 * Executes the service inject script in the isolated world.
83 * 84 *
84 * The service inject script relies on exposed APIs, so this function can only 85 * The service inject script relies on exposed APIs, so this function can only
85 * be called after APIs have been exposed via `contextBridge` to the main world. 86 * be called after APIs have been exposed via `contextBridge` to the main world.
86 * 87 *
87 * We have to call `executeJavaScriptInIsolatedWorld` from the service preload script, 88 * We embed the source code of the inject script into the preload script
88 * beause there is no way currently (electron 16) to execute a script on a 89 * with an esbuild plugin, so there is no need to fetch it separately.
89 * `WebFrameMain` in the main process by specifying a `WebSource`. 90 *
90 * Calling `executeJavaScriptInInsolatedWorld` on a `WebContents` in the main process
91 * will always inject the script into the _top-level_ frame, but here we
92 * are injecting into the _current_ frame instead.
93 * As a tradeoff, the promise returned by `executeJavaScriptInIsolatedWorld` 91 * As a tradeoff, the promise returned by `executeJavaScriptInIsolatedWorld`
94 * will resolve to `unknown` (instead of rejecting) even if the injected script fails, 92 * will resolve to `unknown` (instead of rejecting) even if the injected script fails,
95 * because chromium doesn't dispatch main world errors to isolated worlds. 93 * because chromium doesn't dispatch main world errors to isolated worlds.
96 * 94 *
97 * @return A promise that only rejects if we fail to fetch the inject script. 95 * @return A promise that always resolves to `undefined`.
98 * @see https://www.electronjs.org/docs/latest/api/web-frame#webframeexecutejavascriptinisolatedworldworldid-scripts-usergesture-callback
99 * @see https://www.electronjs.org/docs/latest/api/web-frame-main#frameexecutejavascriptcode-usergesture
100 * @see https://www.electronjs.org/docs/latest/api/web-contents#contentsexecutejavascriptinisolatedworldworldid-scripts-usergesture
101 */ 96 */
102async function fetchAndExecuteInjectScript(): Promise<void> { 97async function fetchAndExecuteInjectScript(): Promise<void> {
103 const apiExposedResponse: unknown = await ipcRenderer.invoke(
104 ServiceToMainIpcMessage.ApiExposedInMainWorld,
105 );
106 const injectSource = WebSource.parse(apiExposedResponse);
107 // Isolated world 0 is the main world. 98 // Isolated world 0 is the main world.
108 await webFrame.executeJavaScriptInIsolatedWorld(0, [injectSource]); 99 await webFrame.executeJavaScriptInIsolatedWorld(0, [
100 {
101 code: injectSource,
102 },
103 ]);
109} 104}
110 105
111fetchAndExecuteInjectScript().catch((error) => { 106fetchAndExecuteInjectScript().catch((error) => {
112 console.error('Failed to fetch inject source:', error); 107 // This will never happen because of
108 // https://www.electronjs.org/docs/latest/api/web-frame#webframeexecutejavascriptinisolatedworldworldid-scripts-usergesture-callback
109 console.error('Failed to execute service inject:', error);
113}); 110});