electron-wcap 1.0.0

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.
Files changed (84) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +112 -0
  3. package/common/declaration.d.ts +8 -0
  4. package/common/declaration.d.ts.map +1 -0
  5. package/common/errors.d.ts +9 -0
  6. package/common/errors.d.ts.map +1 -0
  7. package/common/errors.js +35 -0
  8. package/common/errors.js.map +1 -0
  9. package/common/interfaces.d.ts +4 -0
  10. package/common/interfaces.d.ts.map +1 -0
  11. package/common/protocol.d.ts +11 -0
  12. package/common/protocol.d.ts.map +1 -0
  13. package/common/protocol.js +13 -0
  14. package/common/protocol.js.map +1 -0
  15. package/esm/common/declaration.d.ts +8 -0
  16. package/esm/common/declaration.d.ts.map +1 -0
  17. package/esm/common/errors.d.ts +9 -0
  18. package/esm/common/errors.d.ts.map +1 -0
  19. package/esm/common/errors.js +29 -0
  20. package/esm/common/errors.js.map +1 -0
  21. package/esm/common/interfaces.d.ts +4 -0
  22. package/esm/common/interfaces.d.ts.map +1 -0
  23. package/esm/common/protocol.d.ts +11 -0
  24. package/esm/common/protocol.d.ts.map +1 -0
  25. package/esm/common/protocol.js +11 -0
  26. package/esm/common/protocol.js.map +1 -0
  27. package/esm/index.d.ts +2 -0
  28. package/esm/index.d.ts.map +1 -0
  29. package/esm/index.js +4 -0
  30. package/esm/index.js.map +1 -0
  31. package/esm/main/callback-registry.d.ts +10 -0
  32. package/esm/main/callback-registry.d.ts.map +1 -0
  33. package/esm/main/callback-registry.js +59 -0
  34. package/esm/main/callback-registry.js.map +1 -0
  35. package/esm/main/index.d.ts +3 -0
  36. package/esm/main/index.d.ts.map +1 -0
  37. package/esm/main/index.js +2 -0
  38. package/esm/main/index.js.map +1 -0
  39. package/esm/main/injectable.d.ts +3 -0
  40. package/esm/main/injectable.d.ts.map +1 -0
  41. package/esm/main/injectable.js +30 -0
  42. package/esm/main/injectable.js.map +1 -0
  43. package/esm/main/provider.d.ts +7 -0
  44. package/esm/main/provider.d.ts.map +1 -0
  45. package/esm/main/provider.js +73 -0
  46. package/esm/main/provider.js.map +1 -0
  47. package/esm/package.json +1 -0
  48. package/esm/preload/bridge.d.ts +2 -0
  49. package/esm/preload/bridge.d.ts.map +1 -0
  50. package/esm/preload/bridge.js +17 -0
  51. package/esm/preload/bridge.js.map +1 -0
  52. package/esm/preload/index.d.ts +2 -0
  53. package/esm/preload/index.d.ts.map +1 -0
  54. package/esm/preload/index.js +2 -0
  55. package/esm/preload/index.js.map +1 -0
  56. package/index.d.ts +2 -0
  57. package/index.d.ts.map +1 -0
  58. package/index.js +4 -0
  59. package/index.js.map +1 -0
  60. package/main/callback-registry.d.ts +10 -0
  61. package/main/callback-registry.d.ts.map +1 -0
  62. package/main/callback-registry.js +60 -0
  63. package/main/callback-registry.js.map +1 -0
  64. package/main/index.d.ts +3 -0
  65. package/main/index.d.ts.map +1 -0
  66. package/main/index.js +6 -0
  67. package/main/index.js.map +1 -0
  68. package/main/injectable.d.ts +3 -0
  69. package/main/injectable.d.ts.map +1 -0
  70. package/main/injectable.js +31 -0
  71. package/main/injectable.js.map +1 -0
  72. package/main/provider.d.ts +7 -0
  73. package/main/provider.d.ts.map +1 -0
  74. package/main/provider.js +73 -0
  75. package/main/provider.js.map +1 -0
  76. package/package.json +43 -0
  77. package/preload/bridge.d.ts +2 -0
  78. package/preload/bridge.d.ts.map +1 -0
  79. package/preload/bridge.js +17 -0
  80. package/preload/bridge.js.map +1 -0
  81. package/preload/index.d.ts +2 -0
  82. package/preload/index.d.ts.map +1 -0
  83. package/preload/index.js +6 -0
  84. package/preload/index.js.map +1 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Egor Kushnarev
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,112 @@
1
+ # electron-wcap
2
+
3
+ Electron **W**eb**C**ontent **A**PI **P**rovider — call renderer APIs from the main process with support for passing callbacks.
4
+
5
+ ## Overview
6
+
7
+ electron-wcap lets the main process use an API object that lives in a renderer (a `WebContents`). You get a typed proxy in the main process; calling a method runs the corresponding function in the renderer via injected script. Functions you pass as arguments are registered and bridged so the renderer can invoke them back into the main process.
8
+
9
+ - **Main process**: create a provider for a given `WebContents` and API key; use it like a normal async API.
10
+ - **Preload**: expose the callback bridge so renderer code can invoke those callbacks.
11
+ - **Renderer**: assign your API object to `window[apiKey]` and use it as usual.
12
+
13
+ ## Install
14
+
15
+ ```bash
16
+ npm add electron-wcap
17
+ ```
18
+
19
+ Requires **Electron** (peer dependency). Node 22+ and pnpm are recommended (see `volta` in `package.json`).
20
+
21
+ ## Usage
22
+
23
+ ### 1. Main process
24
+
25
+ Import from `electron-wcap/main` and create a provider for a `WebContents` and a string `apiKey` that the renderer will use for the same API:
26
+
27
+ ```ts
28
+ import { createApiProvider } from 'electron-wcap/main';
29
+
30
+ // e.g. after creating a BrowserWindow
31
+ const provider = createApiProvider<MyApi>(win.webContents, 'myApi');
32
+
33
+ function onData(data: unknown): void {
34
+ // This callback runs in the main process when the renderer calls it
35
+ console.log('Renderer sent:', data);
36
+ }
37
+
38
+ // Call renderer methods (return value is a Promise)
39
+ const result = await provider.someMethod('arg', onData);
40
+ ```
41
+
42
+ - The generic `MyApi` is for typing only; the real implementation lives in the renderer.
43
+ - Callbacks must be **named functions** (used as registry keys).
44
+
45
+ ### 2. Preload
46
+
47
+ Import from `electron-wcap/preload` and enable the callback bridge so the renderer can invoke callbacks passed from main:
48
+
49
+ ```ts
50
+ import { enableCallbacks } from 'electron-wcap/preload';
51
+
52
+ enableCallbacks();
53
+ ```
54
+
55
+ Load this script as the preload for any window whose renderer API you use with `createApiProvider`.
56
+
57
+ ### 3. Renderer - optional
58
+
59
+ Expose your API on `window` under the same `apiKey` you used in `createApiProvider`:
60
+
61
+ ```ts
62
+ const apiKey = 'myApi';
63
+
64
+ window[apiKey] = {
65
+ someMethod(arg: string, callback: (data: unknown) => void) {
66
+ // callback is a function that runs in the main process
67
+ callback({ received: arg });
68
+ return 'done';
69
+ },
70
+ };
71
+ ```
72
+
73
+ The renderer can call the callback (possibly asynchronously); the call is sent to the main process via IPC and the registered function runs there.
74
+
75
+ ## API
76
+
77
+ ### Main (`electron-wcap/main`)
78
+
79
+ - **`createApiProvider<ApiInterface>(webContents, apiKey)`**
80
+ Returns a proxy that implements `ApiInterface` (and `Promisify<ApiInterface>` so methods are async). Each property access returns an async function that runs the corresponding method in the renderer via `webContents.executeJavaScript`.
81
+ The proxy also has a readonly **`webContents`** property (the `WebContents` you passed in).
82
+
83
+ ### Preload (`electron-wcap/preload`)
84
+
85
+ - **`enableCallbacks()`**
86
+ Exposes `__ElectronWCAPBridge__` on the renderer’s `window` via `contextBridge`, so renderer code can invoke callbacks that were passed from the main process.
87
+
88
+ ### Important
89
+
90
+ - **Entry points**: Use `electron-wcap/main` in the main process and `electron-wcap/preload` in the preload script. Importing from `electron-wcap` alone throws an error that explains this.
91
+ - **Callback names**: Callbacks you pass from main must be named (e.g. `function onData(x) { ... }`), not anonymous, so they can be registered and invoked by name.
92
+ - **sandbox**: as Electron now deafult sandbox to `true`, you should disable sandoxing to use callbacks.
93
+
94
+ ## Build
95
+
96
+ From the repo:
97
+
98
+ ```bash
99
+ pnpm i
100
+ pnpm build
101
+ ```
102
+
103
+ Output: `dist/` (CommonJS) and `dist/esm/` (ESM).
104
+
105
+ ## Scripts
106
+
107
+ - `pnpm build` — Rollup build (CJS + ESM)
108
+ - `pnpm lint` — Lint (editorconfig + ESLint)
109
+
110
+ ## License
111
+
112
+ See [LICENSE](LICENSE).
@@ -0,0 +1,8 @@
1
+ import { CallbackBridge } from './interfaces';
2
+ declare global {
3
+ interface Window {
4
+ [key: string]: any;
5
+ __ElectronWCAPBridge__: CallbackBridge;
6
+ }
7
+ }
8
+ //# sourceMappingURL=declaration.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"declaration.d.ts","sourceRoot":"","sources":["../../src/common/declaration.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAE9C,OAAO,CAAC,MAAM,CAAC;IACd,UAAU,MAAM;QACf,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;QAEnB,sBAAsB,EAAE,cAAc,CAAC;KACvC;CACD"}
@@ -0,0 +1,9 @@
1
+ export declare function unknownOptionsType(): Error;
2
+ export declare function apiKeyNotExists(apiKey: string, webContentsId: number): Error;
3
+ export declare function callbackNotRegistered(method: string, senderId: number): Error;
4
+ export declare function nonInvocationRequest(): Error;
5
+ export declare function callbackWithoutName(): Error;
6
+ export declare function callbackRegisteredAlready(callbackName: string, webContentsId: number): Error;
7
+ export declare function bridgeNotRegistered(): Error;
8
+ export declare function exportFromRoot(): Error;
9
+ //# sourceMappingURL=errors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/common/errors.ts"],"names":[],"mappings":"AAAA,wBAAgB,kBAAkB,IAAI,KAAK,CAE1C;AAED,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,GAAG,KAAK,CAE5E;AAED,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,KAAK,CAE7E;AAED,wBAAgB,oBAAoB,IAAI,KAAK,CAE5C;AAED,wBAAgB,mBAAmB,IAAI,KAAK,CAE3C;AAED,wBAAgB,yBAAyB,CAAC,YAAY,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,GAAG,KAAK,CAE5F;AAED,wBAAgB,mBAAmB,IAAI,KAAK,CAE3C;AAED,wBAAgB,cAAc,IAAI,KAAK,CAOtC"}
@@ -0,0 +1,35 @@
1
+ function apiKeyNotExists(apiKey, webContentsId) {
2
+ return Error(`electron-wcap: api with key '${apiKey}' does not exists in host with id '${webContentsId}'`);
3
+ }
4
+ function callbackNotRegistered(method, senderId) {
5
+ return Error(`electron-wcap: callback '${method}' is not registered in host '${senderId}'`);
6
+ }
7
+ function nonInvocationRequest() {
8
+ return Error('electron-wcap: got non callback invocation request');
9
+ }
10
+ function callbackWithoutName() {
11
+ return Error('electron-wcap: callback must have a name - use function decration syntax');
12
+ }
13
+ function callbackRegisteredAlready(callbackName, webContentsId) {
14
+ return Error(`electron-wcap: callback with name '${callbackName}' already registered in host with id '${webContentsId}'`);
15
+ }
16
+ function bridgeNotRegistered() {
17
+ return Error('electron-wcap: __ApiProviderBridge__ does not exists; make sure you have expose it via preload');
18
+ }
19
+ function exportFromRoot() {
20
+ return Error(`electron-wcap uses different code for the main and preload processes:
21
+
22
+ In the Electron main process you should import 'electron-wcap/main'
23
+ In the Electron preload you should import 'electron-wcap/preload'
24
+
25
+ `);
26
+ }
27
+
28
+ exports.apiKeyNotExists = apiKeyNotExists;
29
+ exports.bridgeNotRegistered = bridgeNotRegistered;
30
+ exports.callbackNotRegistered = callbackNotRegistered;
31
+ exports.callbackRegisteredAlready = callbackRegisteredAlready;
32
+ exports.callbackWithoutName = callbackWithoutName;
33
+ exports.exportFromRoot = exportFromRoot;
34
+ exports.nonInvocationRequest = nonInvocationRequest;
35
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.js","sources":["../../src/common/errors.ts"],"sourcesContent":[null],"names":[],"mappings":"AAIM,SAAU,eAAe,CAAC,MAAc,EAAE,aAAqB,EAAA;IACpE,OAAO,KAAK,CAAC,CAAA,6BAAA,EAAiC,MAAO,sCAAuC,aAAc,CAAA,CAAA,CAAG,CAAC;AAC/G;AAEM,SAAU,qBAAqB,CAAC,MAAc,EAAE,QAAgB,EAAA;IACrE,OAAO,KAAK,CAAC,CAAA,yBAAA,EAA6B,MAAO,gCAAiC,QAAS,CAAA,CAAA,CAAG,CAAC;AAChG;SAEgB,oBAAoB,GAAA;AACnC,IAAA,OAAO,KAAK,CAAC,oDAAoD,CAAC;AACnE;SAEgB,mBAAmB,GAAA;AAClC,IAAA,OAAO,KAAK,CAAC,0EAA0E,CAAC;AACzF;AAEM,SAAU,yBAAyB,CAAC,YAAoB,EAAE,aAAqB,EAAA;IACpF,OAAO,KAAK,CAAC,CAAA,mCAAA,EAAuC,YAAa,yCAA0C,aAAc,CAAA,CAAA,CAAG,CAAC;AAC9H;SAEgB,mBAAmB,GAAA;AAClC,IAAA,OAAO,KAAK,CAAC,gGAAgG,CAAC;AAC/G;SAEgB,cAAc,GAAA;AAC7B,IAAA,OAAO,KAAK,CAAC,CAAA;;;;;AAKX,EAAA,CAAA,CAAC;AACJ;;;;;;;;;;"}
@@ -0,0 +1,4 @@
1
+ export interface CallbackBridge {
2
+ invoke(callbackName: string, ...args: unknown[]): unknown;
3
+ }
4
+ //# sourceMappingURL=interfaces.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"interfaces.d.ts","sourceRoot":"","sources":["../../src/common/interfaces.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,cAAc;IAC9B,MAAM,CAAC,YAAY,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC;CAC1D"}
@@ -0,0 +1,11 @@
1
+ export interface CallbackInvokeRequest {
2
+ method: string;
3
+ args: unknown[];
4
+ }
5
+ export interface DispatchedCallback {
6
+ dispatchedCallbackName: string;
7
+ }
8
+ export declare function isCallbackInvokeRequest(msg: unknown): msg is CallbackInvokeRequest;
9
+ export declare const BRIDGE_INVOKE_REQUEST_CHANNEL = "api-provider:bridge-request";
10
+ export declare const CALLBACK_BRIDGE_NAME = "__ElectronWCAPBridge__";
11
+ //# sourceMappingURL=protocol.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"protocol.d.ts","sourceRoot":"","sources":["../../src/common/protocol.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,qBAAqB;IACrC,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,OAAO,EAAE,CAAC;CAChB;AAED,MAAM,WAAW,kBAAkB;IAClC,sBAAsB,EAAE,MAAM,CAAA;CAC9B;AAED,wBAAgB,uBAAuB,CAAC,GAAG,EAAE,OAAO,GAAG,GAAG,IAAI,qBAAqB,CAMlF;AAED,eAAO,MAAM,6BAA6B,gCAAgC,CAAC;AAE3E,eAAO,MAAM,oBAAoB,2BAA2B,CAAC"}
@@ -0,0 +1,13 @@
1
+ function isCallbackInvokeRequest(msg) {
2
+ const mayBeRequest = msg;
3
+ return mayBeRequest !== null &&
4
+ typeof mayBeRequest.method === 'string' &&
5
+ Array.isArray(mayBeRequest.args);
6
+ }
7
+ const BRIDGE_INVOKE_REQUEST_CHANNEL = 'api-provider:bridge-request';
8
+ const CALLBACK_BRIDGE_NAME = '__ElectronWCAPBridge__';
9
+
10
+ exports.BRIDGE_INVOKE_REQUEST_CHANNEL = BRIDGE_INVOKE_REQUEST_CHANNEL;
11
+ exports.CALLBACK_BRIDGE_NAME = CALLBACK_BRIDGE_NAME;
12
+ exports.isCallbackInvokeRequest = isCallbackInvokeRequest;
13
+ //# sourceMappingURL=protocol.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"protocol.js","sources":["../../src/common/protocol.ts"],"sourcesContent":[null],"names":[],"mappings":"AASM,SAAU,uBAAuB,CAAC,GAAY,EAAA;IACnD,MAAM,YAAY,GAAG,GAA4B;IAEjD,OAAO,YAAY,KAAK,IAAI;AAC3B,QAAA,OAAO,YAAY,CAAC,MAAM,KAAK,QAAQ;AACvC,QAAA,KAAK,CAAC,OAAO,CAAC,YAAY,CAAC,IAAI,CAAC;AAClC;AAEO,MAAM,6BAA6B,GAAG;AAEtC,MAAM,oBAAoB,GAAG;;;;;;"}
@@ -0,0 +1,8 @@
1
+ import { CallbackBridge } from './interfaces';
2
+ declare global {
3
+ interface Window {
4
+ [key: string]: any;
5
+ __ElectronWCAPBridge__: CallbackBridge;
6
+ }
7
+ }
8
+ //# sourceMappingURL=declaration.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"declaration.d.ts","sourceRoot":"","sources":["../../../src/common/declaration.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAE9C,OAAO,CAAC,MAAM,CAAC;IACd,UAAU,MAAM;QACf,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;QAEnB,sBAAsB,EAAE,cAAc,CAAC;KACvC;CACD"}
@@ -0,0 +1,9 @@
1
+ export declare function unknownOptionsType(): Error;
2
+ export declare function apiKeyNotExists(apiKey: string, webContentsId: number): Error;
3
+ export declare function callbackNotRegistered(method: string, senderId: number): Error;
4
+ export declare function nonInvocationRequest(): Error;
5
+ export declare function callbackWithoutName(): Error;
6
+ export declare function callbackRegisteredAlready(callbackName: string, webContentsId: number): Error;
7
+ export declare function bridgeNotRegistered(): Error;
8
+ export declare function exportFromRoot(): Error;
9
+ //# sourceMappingURL=errors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../../src/common/errors.ts"],"names":[],"mappings":"AAAA,wBAAgB,kBAAkB,IAAI,KAAK,CAE1C;AAED,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,GAAG,KAAK,CAE5E;AAED,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,KAAK,CAE7E;AAED,wBAAgB,oBAAoB,IAAI,KAAK,CAE5C;AAED,wBAAgB,mBAAmB,IAAI,KAAK,CAE3C;AAED,wBAAgB,yBAAyB,CAAC,YAAY,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,GAAG,KAAK,CAE5F;AAED,wBAAgB,mBAAmB,IAAI,KAAK,CAE3C;AAED,wBAAgB,cAAc,IAAI,KAAK,CAOtC"}
@@ -0,0 +1,29 @@
1
+ function apiKeyNotExists(apiKey, webContentsId) {
2
+ return Error(`electron-wcap: api with key '${apiKey}' does not exists in host with id '${webContentsId}'`);
3
+ }
4
+ function callbackNotRegistered(method, senderId) {
5
+ return Error(`electron-wcap: callback '${method}' is not registered in host '${senderId}'`);
6
+ }
7
+ function nonInvocationRequest() {
8
+ return Error('electron-wcap: got non callback invocation request');
9
+ }
10
+ function callbackWithoutName() {
11
+ return Error('electron-wcap: callback must have a name - use function decration syntax');
12
+ }
13
+ function callbackRegisteredAlready(callbackName, webContentsId) {
14
+ return Error(`electron-wcap: callback with name '${callbackName}' already registered in host with id '${webContentsId}'`);
15
+ }
16
+ function bridgeNotRegistered() {
17
+ return Error('electron-wcap: __ApiProviderBridge__ does not exists; make sure you have expose it via preload');
18
+ }
19
+ function exportFromRoot() {
20
+ return Error(`electron-wcap uses different code for the main and preload processes:
21
+
22
+ In the Electron main process you should import 'electron-wcap/main'
23
+ In the Electron preload you should import 'electron-wcap/preload'
24
+
25
+ `);
26
+ }
27
+
28
+ export { apiKeyNotExists, bridgeNotRegistered, callbackNotRegistered, callbackRegisteredAlready, callbackWithoutName, exportFromRoot, nonInvocationRequest };
29
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.js","sources":["../../../../src/common/errors.ts"],"sourcesContent":[null],"names":[],"mappings":"AAIM,SAAU,eAAe,CAAC,MAAc,EAAE,aAAqB,EAAA;IACpE,OAAO,KAAK,CAAC,CAAA,6BAAA,EAAiC,MAAO,sCAAuC,aAAc,CAAA,CAAA,CAAG,CAAC;AAC/G;AAEM,SAAU,qBAAqB,CAAC,MAAc,EAAE,QAAgB,EAAA;IACrE,OAAO,KAAK,CAAC,CAAA,yBAAA,EAA6B,MAAO,gCAAiC,QAAS,CAAA,CAAA,CAAG,CAAC;AAChG;SAEgB,oBAAoB,GAAA;AACnC,IAAA,OAAO,KAAK,CAAC,oDAAoD,CAAC;AACnE;SAEgB,mBAAmB,GAAA;AAClC,IAAA,OAAO,KAAK,CAAC,0EAA0E,CAAC;AACzF;AAEM,SAAU,yBAAyB,CAAC,YAAoB,EAAE,aAAqB,EAAA;IACpF,OAAO,KAAK,CAAC,CAAA,mCAAA,EAAuC,YAAa,yCAA0C,aAAc,CAAA,CAAA,CAAG,CAAC;AAC9H;SAEgB,mBAAmB,GAAA;AAClC,IAAA,OAAO,KAAK,CAAC,gGAAgG,CAAC;AAC/G;SAEgB,cAAc,GAAA;AAC7B,IAAA,OAAO,KAAK,CAAC,CAAA;;;;;AAKX,EAAA,CAAA,CAAC;AACJ;;;;"}
@@ -0,0 +1,4 @@
1
+ export interface CallbackBridge {
2
+ invoke(callbackName: string, ...args: unknown[]): unknown;
3
+ }
4
+ //# sourceMappingURL=interfaces.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"interfaces.d.ts","sourceRoot":"","sources":["../../../src/common/interfaces.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,cAAc;IAC9B,MAAM,CAAC,YAAY,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC;CAC1D"}
@@ -0,0 +1,11 @@
1
+ export interface CallbackInvokeRequest {
2
+ method: string;
3
+ args: unknown[];
4
+ }
5
+ export interface DispatchedCallback {
6
+ dispatchedCallbackName: string;
7
+ }
8
+ export declare function isCallbackInvokeRequest(msg: unknown): msg is CallbackInvokeRequest;
9
+ export declare const BRIDGE_INVOKE_REQUEST_CHANNEL = "api-provider:bridge-request";
10
+ export declare const CALLBACK_BRIDGE_NAME = "__ElectronWCAPBridge__";
11
+ //# sourceMappingURL=protocol.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"protocol.d.ts","sourceRoot":"","sources":["../../../src/common/protocol.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,qBAAqB;IACrC,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,OAAO,EAAE,CAAC;CAChB;AAED,MAAM,WAAW,kBAAkB;IAClC,sBAAsB,EAAE,MAAM,CAAA;CAC9B;AAED,wBAAgB,uBAAuB,CAAC,GAAG,EAAE,OAAO,GAAG,GAAG,IAAI,qBAAqB,CAMlF;AAED,eAAO,MAAM,6BAA6B,gCAAgC,CAAC;AAE3E,eAAO,MAAM,oBAAoB,2BAA2B,CAAC"}
@@ -0,0 +1,11 @@
1
+ function isCallbackInvokeRequest(msg) {
2
+ const mayBeRequest = msg;
3
+ return mayBeRequest !== null &&
4
+ typeof mayBeRequest.method === 'string' &&
5
+ Array.isArray(mayBeRequest.args);
6
+ }
7
+ const BRIDGE_INVOKE_REQUEST_CHANNEL = 'api-provider:bridge-request';
8
+ const CALLBACK_BRIDGE_NAME = '__ElectronWCAPBridge__';
9
+
10
+ export { BRIDGE_INVOKE_REQUEST_CHANNEL, CALLBACK_BRIDGE_NAME, isCallbackInvokeRequest };
11
+ //# sourceMappingURL=protocol.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"protocol.js","sources":["../../../../src/common/protocol.ts"],"sourcesContent":[null],"names":[],"mappings":"AASM,SAAU,uBAAuB,CAAC,GAAY,EAAA;IACnD,MAAM,YAAY,GAAG,GAA4B;IAEjD,OAAO,YAAY,KAAK,IAAI;AAC3B,QAAA,OAAO,YAAY,CAAC,MAAM,KAAK,QAAQ;AACvC,QAAA,KAAK,CAAC,OAAO,CAAC,YAAY,CAAC,IAAI,CAAC;AAClC;AAEO,MAAM,6BAA6B,GAAG;AAEtC,MAAM,oBAAoB,GAAG;;;;"}
package/esm/index.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,CAAC"}
package/esm/index.js ADDED
@@ -0,0 +1,4 @@
1
+ import { exportFromRoot } from './common/errors.js';
2
+
3
+ throw exportFromRoot();
4
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sources":["../../../src/index.ts"],"sourcesContent":[null],"names":[],"mappings":";;AAEA,MAAM,cAAc,EAAE"}
@@ -0,0 +1,10 @@
1
+ import { WebContents } from 'electron';
2
+ export declare class CallbackRegistry {
3
+ private readonly callbacks;
4
+ constructor();
5
+ registerCallback(webContents: WebContents, callback: (...args: unknown[]) => unknown): string;
6
+ unregisterCallback(hostId: number, name: string): boolean;
7
+ private watchForHost;
8
+ }
9
+ export declare function globalCallbacksRegistry(): CallbackRegistry;
10
+ //# sourceMappingURL=callback-registry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"callback-registry.d.ts","sourceRoot":"","sources":["../../../src/main/callback-registry.ts"],"names":[],"mappings":"AAAA,OAAO,EAAW,WAAW,EAAE,MAAM,UAAU,CAAC;AAKhD,qBAAa,gBAAgB;IAC5B,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAmE;;IAoB7F,gBAAgB,CAAC,WAAW,EAAE,WAAW,EAAE,QAAQ,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,OAAO,GAAG,MAAM;IAoB7F,kBAAkB,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO;IAUzD,OAAO,CAAC,YAAY;CAKpB;AAID,wBAAgB,uBAAuB,IAAI,gBAAgB,CAM1D"}
@@ -0,0 +1,59 @@
1
+ import { ipcMain } from 'electron';
2
+ import { BRIDGE_INVOKE_REQUEST_CHANNEL, isCallbackInvokeRequest } from '../common/protocol.js';
3
+ import { callbackNotRegistered, nonInvocationRequest, callbackWithoutName, callbackRegisteredAlready } from '../common/errors.js';
4
+
5
+ class CallbackRegistry {
6
+ callbacks = new Map();
7
+ constructor() {
8
+ ipcMain.on(BRIDGE_INVOKE_REQUEST_CHANNEL, (event, msg) => {
9
+ if (isCallbackInvokeRequest(msg)) {
10
+ const callback = this.callbacks.get(event.sender.id)?.get(msg.method);
11
+ if (!callback) {
12
+ console.error(callbackNotRegistered(msg.method, event.sender.id));
13
+ return;
14
+ }
15
+ event.returnValue = callback?.(...msg.args);
16
+ return;
17
+ }
18
+ console.error(nonInvocationRequest());
19
+ });
20
+ }
21
+ registerCallback(webContents, callback) {
22
+ if (!callback.name) {
23
+ throw callbackWithoutName();
24
+ }
25
+ let callbacksByIdBucket = this.callbacks.get(webContents.id);
26
+ if (!callbacksByIdBucket) {
27
+ callbacksByIdBucket = new Map();
28
+ this.callbacks.set(webContents.id, callbacksByIdBucket);
29
+ this.watchForHost(webContents);
30
+ }
31
+ if (callbacksByIdBucket.has(callback.name)) {
32
+ throw callbackRegisteredAlready(callback.name, webContents.id);
33
+ }
34
+ callbacksByIdBucket.set(callback.name, callback);
35
+ return callback.name;
36
+ }
37
+ unregisterCallback(hostId, name) {
38
+ const callbacksByIdBucket = this.callbacks.get(hostId);
39
+ if (!callbacksByIdBucket) {
40
+ return false;
41
+ }
42
+ return callbacksByIdBucket.delete(name);
43
+ }
44
+ watchForHost(webContents) {
45
+ webContents.once('destroyed', () => {
46
+ this.callbacks.delete(webContents.id);
47
+ });
48
+ }
49
+ }
50
+ let registryInstance = null;
51
+ function globalCallbacksRegistry() {
52
+ if (!registryInstance) {
53
+ registryInstance = new CallbackRegistry();
54
+ }
55
+ return registryInstance;
56
+ }
57
+
58
+ export { CallbackRegistry, globalCallbacksRegistry };
59
+ //# sourceMappingURL=callback-registry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"callback-registry.js","sources":["../../../../src/main/callback-registry.ts"],"sourcesContent":[null],"names":[],"mappings":";;;;MAKa,gBAAgB,CAAA;AACX,IAAA,SAAS,GAAG,IAAI,GAAG,EAAwD;AAE5F,IAAA,WAAA,GAAA;QACC,OAAO,CAAC,EAAE,CAAC,6BAA6B,EAAE,CAAC,KAA4B,EAAE,GAAY,KAAI;AACxF,YAAA,IAAI,uBAAuB,CAAC,GAAG,CAAC,EAAE;gBACjC,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC;gBAErE,IAAI,CAAC,QAAQ,EAAE;AACd,oBAAA,OAAO,CAAC,KAAK,CAAC,qBAAqB,CAAC,GAAG,CAAC,MAAM,EAAE,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;oBACjE;gBACD;gBAEA,KAAK,CAAC,WAAW,GAAG,QAAQ,GAAG,GAAG,GAAG,CAAC,IAAI,CAAC;gBAC3C;YACD;AAEA,YAAA,OAAO,CAAC,KAAK,CAAC,oBAAoB,EAAE,CAAC;AACtC,QAAA,CAAC,CAAC;IACH;IAEA,gBAAgB,CAAC,WAAwB,EAAE,QAAyC,EAAA;AACnF,QAAA,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE;YACnB,MAAM,mBAAmB,EAAE;QAC5B;AAEA,QAAA,IAAI,mBAAmB,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,WAAW,CAAC,EAAE,CAAC;QAC5D,IAAI,CAAC,mBAAmB,EAAE;AACzB,YAAA,mBAAmB,GAAG,IAAI,GAAG,EAA2C;YACxE,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,WAAW,CAAC,EAAE,EAAE,mBAAmB,CAAC;AACvD,YAAA,IAAI,CAAC,YAAY,CAAC,WAAW,CAAC;QAC/B;QAEA,IAAI,mBAAmB,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE;YAC3C,MAAM,yBAAyB,CAAC,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAC,EAAE,CAAC;QAC/D;QAEA,mBAAmB,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;QAChD,OAAO,QAAQ,CAAC,IAAI;IACrB;IAEA,kBAAkB,CAAC,MAAc,EAAE,IAAY,EAAA;QAC9C,MAAM,mBAAmB,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC;QAEtD,IAAI,CAAC,mBAAmB,EAAE;AACzB,YAAA,OAAO,KAAK;QACb;AAEA,QAAA,OAAO,mBAAmB,CAAC,MAAM,CAAC,IAAI,CAAC;IACxC;AAEQ,IAAA,YAAY,CAAC,WAAwB,EAAA;AAC5C,QAAA,WAAW,CAAC,IAAI,CAAC,WAAW,EAAE,MAAK;YAClC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,WAAW,CAAC,EAAE,CAAC;AACtC,QAAA,CAAC,CAAC;IACH;AACA;AAED,IAAI,gBAAgB,GAA4B,IAAI;SAEpC,uBAAuB,GAAA;IACtC,IAAI,CAAC,gBAAgB,EAAE;AACtB,QAAA,gBAAgB,GAAG,IAAI,gBAAgB,EAAE;IAC1C;AAEA,IAAA,OAAO,gBAAgB;AACxB;;;;"}
@@ -0,0 +1,3 @@
1
+ export { createApiProvider } from './provider';
2
+ export type { WebContentsApiProvider } from './provider';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/main/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAC/C,YAAY,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAC"}
@@ -0,0 +1,2 @@
1
+ export { createApiProvider } from './provider.js';
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":""}
@@ -0,0 +1,3 @@
1
+ export declare function invoke(apiKey: string, method: string, args: unknown[]): unknown;
2
+ export declare function apiExists(apiKey: string): boolean;
3
+ //# sourceMappingURL=injectable.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"injectable.d.ts","sourceRoot":"","sources":["../../../src/main/injectable.ts"],"names":[],"mappings":"AAGA,wBAAgB,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,OAAO,CA0B/E;AAED,wBAAgB,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAEjD"}
@@ -0,0 +1,30 @@
1
+ import { bridgeNotRegistered } from '../common/errors.js';
2
+
3
+ function invoke(apiKey, method, args) {
4
+ function isDispachedCallback(o) {
5
+ return typeof o === 'object' && typeof o.dispatchedCallbackName === 'string';
6
+ }
7
+ function checkBridgeExists() {
8
+ if (window.__ElectronWCAPBridge__ === null || window.__ElectronWCAPBridge__ === undefined) {
9
+ throw bridgeNotRegistered();
10
+ }
11
+ }
12
+ function handleDispatchedCallback(arg, index) {
13
+ if (isDispachedCallback(arg)) {
14
+ checkBridgeExists();
15
+ const name = arg.dispatchedCallbackName;
16
+ args[index] = (...cbArgs) => {
17
+ return window.__ElectronWCAPBridge__.invoke(name, cbArgs);
18
+ };
19
+ }
20
+ }
21
+ args.map(handleDispatchedCallback);
22
+ const api = window[apiKey];
23
+ return api[method](...args);
24
+ }
25
+ function apiExists(apiKey) {
26
+ return window[apiKey] !== null && window[apiKey] !== undefined && typeof window[apiKey] === 'object';
27
+ }
28
+
29
+ export { apiExists, invoke };
30
+ //# sourceMappingURL=injectable.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"injectable.js","sources":["../../../../src/main/injectable.ts"],"sourcesContent":[null],"names":[],"mappings":";;SAGgB,MAAM,CAAC,MAAc,EAAE,MAAc,EAAE,IAAe,EAAA;IACrE,SAAS,mBAAmB,CAAC,CAAU,EAAA;QACtC,OAAO,OAAO,CAAC,KAAK,QAAQ,IAAI,OAAQ,CAAwB,CAAC,sBAAsB,KAAK,QAAQ;IACrG;AAEA,IAAA,SAAS,iBAAiB,GAAA;AACzB,QAAA,IAAI,MAAM,CAAC,sBAAsB,KAAK,IAAI,IAAI,MAAM,CAAC,sBAAsB,KAAK,SAAS,EAAE;YAC1F,MAAM,mBAAmB,EAAE;QAC5B;IACD;AAEA,IAAA,SAAS,wBAAwB,CAAC,GAAY,EAAE,KAAa,EAAA;AAC5D,QAAA,IAAI,mBAAmB,CAAC,GAAG,CAAC,EAAE;AAC7B,YAAA,iBAAiB,EAAE;AAEnB,YAAA,MAAM,IAAI,GAAG,GAAG,CAAC,sBAAsB;YACvC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,MAAiB,KAAI;gBACtC,OAAO,MAAM,CAAC,sBAAsB,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC;AAC1D,YAAA,CAAC;QACF;IACD;AAEA,IAAA,IAAI,CAAC,GAAG,CAAC,wBAAwB,CAAC;AAElC,IAAA,MAAM,GAAG,GAAG,MAAM,CAAC,MAAM,CAAuD;IAChF,OAAO,GAAG,CAAC,MAAM,CAAC,CAAC,GAAG,IAAI,CAAC;AAC5B;AAEM,SAAU,SAAS,CAAC,MAAc,EAAA;IACvC,OAAO,MAAM,CAAC,MAAM,CAAC,KAAK,IAAI,IAAI,MAAM,CAAC,MAAM,CAAC,KAAK,SAAS,IAAI,OAAO,MAAM,CAAC,MAAM,CAAC,KAAK,QAAQ;AACrG;;;;"}
@@ -0,0 +1,7 @@
1
+ import { WebContents } from 'electron';
2
+ import { Promisify } from 'promisify-ts';
3
+ export type WebContentsApiProvider<T> = Promisify<T> & {
4
+ readonly webContents: WebContents;
5
+ };
6
+ export declare function createApiProvider<ApiInterface>(webContents: WebContents, apiKey: string): WebContentsApiProvider<ApiInterface>;
7
+ //# sourceMappingURL=provider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provider.d.ts","sourceRoot":"","sources":["../../../src/main/provider.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AACvC,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAOzC,MAAM,MAAM,sBAAsB,CAAC,CAAC,IAAI,SAAS,CAAC,CAAC,CAAC,GAAG;IAAE,QAAQ,CAAC,WAAW,EAAE,WAAW,CAAA;CAAE,CAAC;AAmE7F,wBAAgB,iBAAiB,CAAC,YAAY,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,GAAG,sBAAsB,CAAC,YAAY,CAAC,CAS9H"}
@@ -0,0 +1,73 @@
1
+ import { globalCallbacksRegistry } from './callback-registry.js';
2
+ import { apiExists, invoke } from './injectable.js';
3
+ import { apiKeyNotExists } from '../common/errors.js';
4
+
5
+ class ApiProviderPropertiesHandler {
6
+ webContents;
7
+ apiKey;
8
+ callbackRegistry;
9
+ constructor(webContents, apiKey, callbackRegistry) {
10
+ this.webContents = webContents;
11
+ this.apiKey = apiKey;
12
+ this.callbackRegistry = callbackRegistry;
13
+ }
14
+ compile(fn, ...args) {
15
+ return `(${fn.toString()})(${this.serializeArguments(...args)})`;
16
+ }
17
+ ;
18
+ serializeArguments(...args) {
19
+ const serialized = args.map((arg) => {
20
+ if (Array.isArray(arg)) {
21
+ arg.forEach((value, index) => {
22
+ if (typeof value === 'function') {
23
+ const dispatched = {
24
+ dispatchedCallbackName: this.callbackRegistry.registerCallback(this.webContents, value)
25
+ };
26
+ arg[index] = dispatched;
27
+ }
28
+ });
29
+ }
30
+ return JSON.stringify(arg);
31
+ });
32
+ return serialized.join(',');
33
+ }
34
+ }
35
+ class ApiProviderProxyHandler {
36
+ apiExistsAwaiter;
37
+ properties = {};
38
+ constructor(apiExistsAwaiter) {
39
+ this.apiExistsAwaiter = apiExistsAwaiter;
40
+ }
41
+ get(context, propertyKey) {
42
+ if (Object.hasOwn(context, propertyKey) || typeof context[propertyKey] === 'function') {
43
+ return context[propertyKey];
44
+ }
45
+ const propertyProxy = this.properties[propertyKey];
46
+ if (propertyProxy) {
47
+ return propertyProxy;
48
+ }
49
+ const apiExistsClosure = this.apiExistsAwaiter;
50
+ // proxy context must be a function, to allow using handler 'apply'.
51
+ const propProxy = new Proxy(() => { }, {
52
+ async apply(_target, this_, args) {
53
+ if (!(await apiExistsClosure)) {
54
+ throw apiKeyNotExists(this_.apiKey, this_.webContents.id);
55
+ }
56
+ const injectable = this_.compile(invoke, this_.apiKey, propertyKey, args);
57
+ return this_.webContents.executeJavaScript(injectable);
58
+ },
59
+ });
60
+ this.properties[propertyKey] = propProxy;
61
+ return propProxy;
62
+ }
63
+ }
64
+ function createApiProvider(webContents, apiKey) {
65
+ const propertiesHandler = new ApiProviderPropertiesHandler(webContents, apiKey, globalCallbacksRegistry());
66
+ const checkApiExistsInjectable = propertiesHandler.compile(apiExists, apiKey);
67
+ const checkApiExistsPromise = webContents.executeJavaScript(checkApiExistsInjectable);
68
+ const proxyHandler = new ApiProviderProxyHandler(checkApiExistsPromise);
69
+ return new Proxy(propertiesHandler, proxyHandler);
70
+ }
71
+
72
+ export { createApiProvider };
73
+ //# sourceMappingURL=provider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provider.js","sources":["../../../../src/main/provider.ts"],"sourcesContent":[null],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ {"type": "module"}
@@ -0,0 +1,2 @@
1
+ export declare function enableCallbacks(): void;
2
+ //# sourceMappingURL=bridge.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bridge.d.ts","sourceRoot":"","sources":["../../../src/preload/bridge.ts"],"names":[],"mappings":"AAIA,wBAAgB,eAAe,IAAI,IAAI,CAWtC"}
@@ -0,0 +1,17 @@
1
+ import { contextBridge, ipcRenderer } from 'electron';
2
+ import { CALLBACK_BRIDGE_NAME, BRIDGE_INVOKE_REQUEST_CHANNEL } from '../common/protocol.js';
3
+
4
+ function enableCallbacks() {
5
+ contextBridge.exposeInMainWorld(CALLBACK_BRIDGE_NAME, {
6
+ invoke(callbackName, args) {
7
+ const invokeRequest = {
8
+ method: callbackName,
9
+ args
10
+ };
11
+ return ipcRenderer.sendSync(BRIDGE_INVOKE_REQUEST_CHANNEL, invokeRequest);
12
+ }
13
+ });
14
+ }
15
+
16
+ export { enableCallbacks };
17
+ //# sourceMappingURL=bridge.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bridge.js","sources":["../../../../src/preload/bridge.ts"],"sourcesContent":[null],"names":[],"mappings":";;;SAIgB,eAAe,GAAA;AAC9B,IAAA,aAAa,CAAC,iBAAiB,CAAC,oBAAoB,EAAE;QACrD,MAAM,CAAC,YAAoB,EAAE,IAAe,EAAA;AAC3C,YAAA,MAAM,aAAa,GAA0B;AAC5C,gBAAA,MAAM,EAAE,YAAY;gBACpB;aACA;YAED,OAAO,WAAW,CAAC,QAAQ,CAAC,6BAA6B,EAAE,aAAa,CAAC;QAC1E;AACA,KAAA,CAAC;AACH;;;;"}
@@ -0,0 +1,2 @@
1
+ export { enableCallbacks } from './bridge';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/preload/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC"}
@@ -0,0 +1,2 @@
1
+ export { enableCallbacks } from './bridge.js';
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":""}
package/index.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=index.d.ts.map
package/index.d.ts.map ADDED
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,CAAC"}
package/index.js ADDED
@@ -0,0 +1,4 @@
1
+ const errors = require('./common/errors.js');
2
+
3
+ throw errors.exportFromRoot();
4
+ //# sourceMappingURL=index.js.map
package/index.js.map ADDED
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sources":["../src/index.ts"],"sourcesContent":[null],"names":["exportFromRoot"],"mappings":";;AAEA,MAAMA,qBAAc,EAAE;;"}
@@ -0,0 +1,10 @@
1
+ import { WebContents } from 'electron';
2
+ export declare class CallbackRegistry {
3
+ private readonly callbacks;
4
+ constructor();
5
+ registerCallback(webContents: WebContents, callback: (...args: unknown[]) => unknown): string;
6
+ unregisterCallback(hostId: number, name: string): boolean;
7
+ private watchForHost;
8
+ }
9
+ export declare function globalCallbacksRegistry(): CallbackRegistry;
10
+ //# sourceMappingURL=callback-registry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"callback-registry.d.ts","sourceRoot":"","sources":["../../src/main/callback-registry.ts"],"names":[],"mappings":"AAAA,OAAO,EAAW,WAAW,EAAE,MAAM,UAAU,CAAC;AAKhD,qBAAa,gBAAgB;IAC5B,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAmE;;IAoB7F,gBAAgB,CAAC,WAAW,EAAE,WAAW,EAAE,QAAQ,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,OAAO,GAAG,MAAM;IAoB7F,kBAAkB,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO;IAUzD,OAAO,CAAC,YAAY;CAKpB;AAID,wBAAgB,uBAAuB,IAAI,gBAAgB,CAM1D"}
@@ -0,0 +1,60 @@
1
+ const electron = require('electron');
2
+ const protocol = require('../common/protocol.js');
3
+ const errors = require('../common/errors.js');
4
+
5
+ class CallbackRegistry {
6
+ callbacks = new Map();
7
+ constructor() {
8
+ electron.ipcMain.on(protocol.BRIDGE_INVOKE_REQUEST_CHANNEL, (event, msg) => {
9
+ if (protocol.isCallbackInvokeRequest(msg)) {
10
+ const callback = this.callbacks.get(event.sender.id)?.get(msg.method);
11
+ if (!callback) {
12
+ console.error(errors.callbackNotRegistered(msg.method, event.sender.id));
13
+ return;
14
+ }
15
+ event.returnValue = callback?.(...msg.args);
16
+ return;
17
+ }
18
+ console.error(errors.nonInvocationRequest());
19
+ });
20
+ }
21
+ registerCallback(webContents, callback) {
22
+ if (!callback.name) {
23
+ throw errors.callbackWithoutName();
24
+ }
25
+ let callbacksByIdBucket = this.callbacks.get(webContents.id);
26
+ if (!callbacksByIdBucket) {
27
+ callbacksByIdBucket = new Map();
28
+ this.callbacks.set(webContents.id, callbacksByIdBucket);
29
+ this.watchForHost(webContents);
30
+ }
31
+ if (callbacksByIdBucket.has(callback.name)) {
32
+ throw errors.callbackRegisteredAlready(callback.name, webContents.id);
33
+ }
34
+ callbacksByIdBucket.set(callback.name, callback);
35
+ return callback.name;
36
+ }
37
+ unregisterCallback(hostId, name) {
38
+ const callbacksByIdBucket = this.callbacks.get(hostId);
39
+ if (!callbacksByIdBucket) {
40
+ return false;
41
+ }
42
+ return callbacksByIdBucket.delete(name);
43
+ }
44
+ watchForHost(webContents) {
45
+ webContents.once('destroyed', () => {
46
+ this.callbacks.delete(webContents.id);
47
+ });
48
+ }
49
+ }
50
+ let registryInstance = null;
51
+ function globalCallbacksRegistry() {
52
+ if (!registryInstance) {
53
+ registryInstance = new CallbackRegistry();
54
+ }
55
+ return registryInstance;
56
+ }
57
+
58
+ exports.CallbackRegistry = CallbackRegistry;
59
+ exports.globalCallbacksRegistry = globalCallbacksRegistry;
60
+ //# sourceMappingURL=callback-registry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"callback-registry.js","sources":["../../src/main/callback-registry.ts"],"sourcesContent":[null],"names":["ipcMain","BRIDGE_INVOKE_REQUEST_CHANNEL","isCallbackInvokeRequest","callbackNotRegistered","nonInvocationRequest","callbackWithoutName","callbackRegisteredAlready"],"mappings":";;;;MAKa,gBAAgB,CAAA;AACX,IAAA,SAAS,GAAG,IAAI,GAAG,EAAwD;AAE5F,IAAA,WAAA,GAAA;QACCA,gBAAO,CAAC,EAAE,CAACC,sCAA6B,EAAE,CAAC,KAA4B,EAAE,GAAY,KAAI;AACxF,YAAA,IAAIC,gCAAuB,CAAC,GAAG,CAAC,EAAE;gBACjC,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC;gBAErE,IAAI,CAAC,QAAQ,EAAE;AACd,oBAAA,OAAO,CAAC,KAAK,CAACC,4BAAqB,CAAC,GAAG,CAAC,MAAM,EAAE,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;oBACjE;gBACD;gBAEA,KAAK,CAAC,WAAW,GAAG,QAAQ,GAAG,GAAG,GAAG,CAAC,IAAI,CAAC;gBAC3C;YACD;AAEA,YAAA,OAAO,CAAC,KAAK,CAACC,2BAAoB,EAAE,CAAC;AACtC,QAAA,CAAC,CAAC;IACH;IAEA,gBAAgB,CAAC,WAAwB,EAAE,QAAyC,EAAA;AACnF,QAAA,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE;YACnB,MAAMC,0BAAmB,EAAE;QAC5B;AAEA,QAAA,IAAI,mBAAmB,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,WAAW,CAAC,EAAE,CAAC;QAC5D,IAAI,CAAC,mBAAmB,EAAE;AACzB,YAAA,mBAAmB,GAAG,IAAI,GAAG,EAA2C;YACxE,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,WAAW,CAAC,EAAE,EAAE,mBAAmB,CAAC;AACvD,YAAA,IAAI,CAAC,YAAY,CAAC,WAAW,CAAC;QAC/B;QAEA,IAAI,mBAAmB,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE;YAC3C,MAAMC,gCAAyB,CAAC,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAC,EAAE,CAAC;QAC/D;QAEA,mBAAmB,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;QAChD,OAAO,QAAQ,CAAC,IAAI;IACrB;IAEA,kBAAkB,CAAC,MAAc,EAAE,IAAY,EAAA;QAC9C,MAAM,mBAAmB,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC;QAEtD,IAAI,CAAC,mBAAmB,EAAE;AACzB,YAAA,OAAO,KAAK;QACb;AAEA,QAAA,OAAO,mBAAmB,CAAC,MAAM,CAAC,IAAI,CAAC;IACxC;AAEQ,IAAA,YAAY,CAAC,WAAwB,EAAA;AAC5C,QAAA,WAAW,CAAC,IAAI,CAAC,WAAW,EAAE,MAAK;YAClC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,WAAW,CAAC,EAAE,CAAC;AACtC,QAAA,CAAC,CAAC;IACH;AACA;AAED,IAAI,gBAAgB,GAA4B,IAAI;SAEpC,uBAAuB,GAAA;IACtC,IAAI,CAAC,gBAAgB,EAAE;AACtB,QAAA,gBAAgB,GAAG,IAAI,gBAAgB,EAAE;IAC1C;AAEA,IAAA,OAAO,gBAAgB;AACxB;;;;;"}
@@ -0,0 +1,3 @@
1
+ export { createApiProvider } from './provider';
2
+ export type { WebContentsApiProvider } from './provider';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/main/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAC/C,YAAY,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAC"}
package/main/index.js ADDED
@@ -0,0 +1,6 @@
1
+ const provider = require('./provider.js');
2
+
3
+
4
+
5
+ exports.createApiProvider = provider.createApiProvider;
6
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;"}
@@ -0,0 +1,3 @@
1
+ export declare function invoke(apiKey: string, method: string, args: unknown[]): unknown;
2
+ export declare function apiExists(apiKey: string): boolean;
3
+ //# sourceMappingURL=injectable.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"injectable.d.ts","sourceRoot":"","sources":["../../src/main/injectable.ts"],"names":[],"mappings":"AAGA,wBAAgB,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,OAAO,CA0B/E;AAED,wBAAgB,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAEjD"}
@@ -0,0 +1,31 @@
1
+ const errors = require('../common/errors.js');
2
+
3
+ function invoke(apiKey, method, args) {
4
+ function isDispachedCallback(o) {
5
+ return typeof o === 'object' && typeof o.dispatchedCallbackName === 'string';
6
+ }
7
+ function checkBridgeExists() {
8
+ if (window.__ElectronWCAPBridge__ === null || window.__ElectronWCAPBridge__ === undefined) {
9
+ throw errors.bridgeNotRegistered();
10
+ }
11
+ }
12
+ function handleDispatchedCallback(arg, index) {
13
+ if (isDispachedCallback(arg)) {
14
+ checkBridgeExists();
15
+ const name = arg.dispatchedCallbackName;
16
+ args[index] = (...cbArgs) => {
17
+ return window.__ElectronWCAPBridge__.invoke(name, cbArgs);
18
+ };
19
+ }
20
+ }
21
+ args.map(handleDispatchedCallback);
22
+ const api = window[apiKey];
23
+ return api[method](...args);
24
+ }
25
+ function apiExists(apiKey) {
26
+ return window[apiKey] !== null && window[apiKey] !== undefined && typeof window[apiKey] === 'object';
27
+ }
28
+
29
+ exports.apiExists = apiExists;
30
+ exports.invoke = invoke;
31
+ //# sourceMappingURL=injectable.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"injectable.js","sources":["../../src/main/injectable.ts"],"sourcesContent":[null],"names":["bridgeNotRegistered"],"mappings":";;SAGgB,MAAM,CAAC,MAAc,EAAE,MAAc,EAAE,IAAe,EAAA;IACrE,SAAS,mBAAmB,CAAC,CAAU,EAAA;QACtC,OAAO,OAAO,CAAC,KAAK,QAAQ,IAAI,OAAQ,CAAwB,CAAC,sBAAsB,KAAK,QAAQ;IACrG;AAEA,IAAA,SAAS,iBAAiB,GAAA;AACzB,QAAA,IAAI,MAAM,CAAC,sBAAsB,KAAK,IAAI,IAAI,MAAM,CAAC,sBAAsB,KAAK,SAAS,EAAE;YAC1F,MAAMA,0BAAmB,EAAE;QAC5B;IACD;AAEA,IAAA,SAAS,wBAAwB,CAAC,GAAY,EAAE,KAAa,EAAA;AAC5D,QAAA,IAAI,mBAAmB,CAAC,GAAG,CAAC,EAAE;AAC7B,YAAA,iBAAiB,EAAE;AAEnB,YAAA,MAAM,IAAI,GAAG,GAAG,CAAC,sBAAsB;YACvC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,MAAiB,KAAI;gBACtC,OAAO,MAAM,CAAC,sBAAsB,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC;AAC1D,YAAA,CAAC;QACF;IACD;AAEA,IAAA,IAAI,CAAC,GAAG,CAAC,wBAAwB,CAAC;AAElC,IAAA,MAAM,GAAG,GAAG,MAAM,CAAC,MAAM,CAAuD;IAChF,OAAO,GAAG,CAAC,MAAM,CAAC,CAAC,GAAG,IAAI,CAAC;AAC5B;AAEM,SAAU,SAAS,CAAC,MAAc,EAAA;IACvC,OAAO,MAAM,CAAC,MAAM,CAAC,KAAK,IAAI,IAAI,MAAM,CAAC,MAAM,CAAC,KAAK,SAAS,IAAI,OAAO,MAAM,CAAC,MAAM,CAAC,KAAK,QAAQ;AACrG;;;;;"}
@@ -0,0 +1,7 @@
1
+ import { WebContents } from 'electron';
2
+ import { Promisify } from 'promisify-ts';
3
+ export type WebContentsApiProvider<T> = Promisify<T> & {
4
+ readonly webContents: WebContents;
5
+ };
6
+ export declare function createApiProvider<ApiInterface>(webContents: WebContents, apiKey: string): WebContentsApiProvider<ApiInterface>;
7
+ //# sourceMappingURL=provider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provider.d.ts","sourceRoot":"","sources":["../../src/main/provider.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AACvC,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAOzC,MAAM,MAAM,sBAAsB,CAAC,CAAC,IAAI,SAAS,CAAC,CAAC,CAAC,GAAG;IAAE,QAAQ,CAAC,WAAW,EAAE,WAAW,CAAA;CAAE,CAAC;AAmE7F,wBAAgB,iBAAiB,CAAC,YAAY,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,GAAG,sBAAsB,CAAC,YAAY,CAAC,CAS9H"}
@@ -0,0 +1,73 @@
1
+ const callbackRegistry = require('./callback-registry.js');
2
+ const injectable = require('./injectable.js');
3
+ const errors = require('../common/errors.js');
4
+
5
+ class ApiProviderPropertiesHandler {
6
+ webContents;
7
+ apiKey;
8
+ callbackRegistry;
9
+ constructor(webContents, apiKey, callbackRegistry) {
10
+ this.webContents = webContents;
11
+ this.apiKey = apiKey;
12
+ this.callbackRegistry = callbackRegistry;
13
+ }
14
+ compile(fn, ...args) {
15
+ return `(${fn.toString()})(${this.serializeArguments(...args)})`;
16
+ }
17
+ ;
18
+ serializeArguments(...args) {
19
+ const serialized = args.map((arg) => {
20
+ if (Array.isArray(arg)) {
21
+ arg.forEach((value, index) => {
22
+ if (typeof value === 'function') {
23
+ const dispatched = {
24
+ dispatchedCallbackName: this.callbackRegistry.registerCallback(this.webContents, value)
25
+ };
26
+ arg[index] = dispatched;
27
+ }
28
+ });
29
+ }
30
+ return JSON.stringify(arg);
31
+ });
32
+ return serialized.join(',');
33
+ }
34
+ }
35
+ class ApiProviderProxyHandler {
36
+ apiExistsAwaiter;
37
+ properties = {};
38
+ constructor(apiExistsAwaiter) {
39
+ this.apiExistsAwaiter = apiExistsAwaiter;
40
+ }
41
+ get(context, propertyKey) {
42
+ if (Object.hasOwn(context, propertyKey) || typeof context[propertyKey] === 'function') {
43
+ return context[propertyKey];
44
+ }
45
+ const propertyProxy = this.properties[propertyKey];
46
+ if (propertyProxy) {
47
+ return propertyProxy;
48
+ }
49
+ const apiExistsClosure = this.apiExistsAwaiter;
50
+ // proxy context must be a function, to allow using handler 'apply'.
51
+ const propProxy = new Proxy(() => { }, {
52
+ async apply(_target, this_, args) {
53
+ if (!(await apiExistsClosure)) {
54
+ throw errors.apiKeyNotExists(this_.apiKey, this_.webContents.id);
55
+ }
56
+ const injectable$1 = this_.compile(injectable.invoke, this_.apiKey, propertyKey, args);
57
+ return this_.webContents.executeJavaScript(injectable$1);
58
+ },
59
+ });
60
+ this.properties[propertyKey] = propProxy;
61
+ return propProxy;
62
+ }
63
+ }
64
+ function createApiProvider(webContents, apiKey) {
65
+ const propertiesHandler = new ApiProviderPropertiesHandler(webContents, apiKey, callbackRegistry.globalCallbacksRegistry());
66
+ const checkApiExistsInjectable = propertiesHandler.compile(injectable.apiExists, apiKey);
67
+ const checkApiExistsPromise = webContents.executeJavaScript(checkApiExistsInjectable);
68
+ const proxyHandler = new ApiProviderProxyHandler(checkApiExistsPromise);
69
+ return new Proxy(propertiesHandler, proxyHandler);
70
+ }
71
+
72
+ exports.createApiProvider = createApiProvider;
73
+ //# sourceMappingURL=provider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provider.js","sources":["../../src/main/provider.ts"],"sourcesContent":[null],"names":["apiKeyNotExists","injectable","invoke","globalCallbacksRegistry","apiExists"],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,43 @@
1
+ {
2
+ "name": "electron-wcap",
3
+ "version": "1.0.0",
4
+ "author": "Egor Kushnarev",
5
+ "description": "Electron WebContent API Provider — call renderer APIs from the main process with support for passing callbacks.",
6
+ "license": "MIT",
7
+ "keywords": [
8
+ "electron",
9
+ "webcontent",
10
+ "executeJavaScript",
11
+ "renderer",
12
+ "API"
13
+ ],
14
+ "homepage": "https://github.com/origin-yaropolk/electron-wcap",
15
+ "repository": {
16
+ "type": "git",
17
+ "url": "https://github.com/origin-yaropolk/electron-wcap"
18
+ },
19
+ "exports": {
20
+ "./main": {
21
+ "require": {
22
+ "types": "./main/index.d.ts",
23
+ "default": "./main/index.js"
24
+ },
25
+ "import": {
26
+ "types": "./esm/main/index.d.ts",
27
+ "default": "./esm/main/index.js"
28
+ }
29
+ },
30
+ "./preload": {
31
+ "require": {
32
+ "types": "./preload/index.d.ts",
33
+ "default": "./preload/index.js"
34
+ },
35
+ "import": {
36
+ "types": "./esm/preload/index.d.ts",
37
+ "default": "./esm/preload/index.js"
38
+ }
39
+ }
40
+ },
41
+ "module": "./esm/main/index.js",
42
+ "browser": "./esm/renderer/index.js"
43
+ }
@@ -0,0 +1,2 @@
1
+ export declare function enableCallbacks(): void;
2
+ //# sourceMappingURL=bridge.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bridge.d.ts","sourceRoot":"","sources":["../../src/preload/bridge.ts"],"names":[],"mappings":"AAIA,wBAAgB,eAAe,IAAI,IAAI,CAWtC"}
@@ -0,0 +1,17 @@
1
+ const electron = require('electron');
2
+ const protocol = require('../common/protocol.js');
3
+
4
+ function enableCallbacks() {
5
+ electron.contextBridge.exposeInMainWorld(protocol.CALLBACK_BRIDGE_NAME, {
6
+ invoke(callbackName, args) {
7
+ const invokeRequest = {
8
+ method: callbackName,
9
+ args
10
+ };
11
+ return electron.ipcRenderer.sendSync(protocol.BRIDGE_INVOKE_REQUEST_CHANNEL, invokeRequest);
12
+ }
13
+ });
14
+ }
15
+
16
+ exports.enableCallbacks = enableCallbacks;
17
+ //# sourceMappingURL=bridge.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bridge.js","sources":["../../src/preload/bridge.ts"],"sourcesContent":[null],"names":["contextBridge","CALLBACK_BRIDGE_NAME","ipcRenderer","BRIDGE_INVOKE_REQUEST_CHANNEL"],"mappings":";;;SAIgB,eAAe,GAAA;AAC9B,IAAAA,sBAAa,CAAC,iBAAiB,CAACC,6BAAoB,EAAE;QACrD,MAAM,CAAC,YAAoB,EAAE,IAAe,EAAA;AAC3C,YAAA,MAAM,aAAa,GAA0B;AAC5C,gBAAA,MAAM,EAAE,YAAY;gBACpB;aACA;YAED,OAAOC,oBAAW,CAAC,QAAQ,CAACC,sCAA6B,EAAE,aAAa,CAAC;QAC1E;AACA,KAAA,CAAC;AACH;;;;"}
@@ -0,0 +1,2 @@
1
+ export { enableCallbacks } from './bridge';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/preload/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC"}
@@ -0,0 +1,6 @@
1
+ const bridge = require('./bridge.js');
2
+
3
+
4
+
5
+ exports.enableCallbacks = bridge.enableCallbacks;
6
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;"}