@lynker-desktop/electron-ipc 0.0.2

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2019 hui.liu
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,115 @@
1
+ # electron-ipc
2
+
3
+ ✨ 异步 electron ipc 调用机制.
4
+
5
+ > 渲染进程 窗口注意设置 contextIsolation=false
6
+ > https://github.com/electron/electron/pull/20307
7
+ > contextIsolation=false
8
+
9
+ ## 🌿 安装
10
+
11
+ 安装方式 [npm](https://www.npmjs.com/package/@lynker-desktop/electron-ipc):
12
+
13
+ ```shell
14
+ npm i @lynker-desktop/electron-ipc --save
15
+ ```
16
+
17
+
18
+ ## 🌿 使用
19
+
20
+ 📍 它必须导入到主进程的入口文件中。
21
+
22
+ ( 否则,呈现进程之间将无法通信。 )
23
+
24
+ ```js
25
+ import {initialize} from '@lynker-desktop/electron-ipc/main'
26
+ initialize();
27
+ ```
28
+
29
+ ### 1. 在 [主进程](https://electronjs.org/docs/glossary#main-process)
30
+
31
+ ```js
32
+ import MainIPC from '@lynker-desktop/electron-ipc/main'
33
+ // ... other code ...
34
+ ```
35
+
36
+ ### 2. 在 [preload](https://www.electronjs.org/docs/latest/tutorial/tutorial-preload) 引入
37
+
38
+ ```javascript
39
+ import '@lynker-desktop/electron-ipc/preload'
40
+ ```
41
+
42
+ ### 3. 在 [渲染进程](https://electronjs.org/docs/glossary#renderer-process)
43
+
44
+ ```typescript
45
+ import RendererIPC from '@lynker-desktop/electron-ipc/renderer'
46
+ // ... other code ...
47
+ ```
48
+
49
+ ## 🌿 例子
50
+
51
+ #### 🌵 1. 主进程A ↔ 主进程B
52
+
53
+ 主进程可以向主进程发送消息并接收回调,如下面的示例所示 :
54
+
55
+ ```js
56
+ // 主进程A:
57
+ const res = await MainIPC.invokeMain(`${channel}`, ...args)
58
+
59
+ // 主进程B: (two choices)
60
+ MainIPC.handleMain(`${channel}`, async (...args) => { return res })
61
+ MainIPC.handleMainOnce(`${channel}`, async (...args) => { return res })
62
+ ```
63
+
64
+
65
+ #### 🌵 2. 主进程 ↔ 渲染进程
66
+
67
+ 主进程可以向呈现进程发送消息并接收回调,如下面的示例所示 :
68
+
69
+ ```js
70
+ /* 主进程: (two choices) */
71
+ const res = await MainIPC.invokeRenderer(`${webContents}`, `${channel}`, ...args)
72
+ const res = await MainIPC.invokeAllRenderer(`${channel}`, ...args)
73
+
74
+ /* 渲染进程: (two choices) */
75
+ RendererIPC.handleMain(`${channel}`, async (...args) => { return res })
76
+ RendererIPC.handleMainOnce(`${channel}`, async (...args) => { return res })
77
+ ```
78
+
79
+
80
+ #### 🌱 3. 渲染进程A ↔ 渲染进程B
81
+
82
+ 渲染进程可以向渲染进程发送消息并接收回调,如下所示
83
+ example :
84
+
85
+ ```js
86
+ // 渲染进程A:
87
+ const res = await RendererIPC.invokeRenderer(`${channel}`, ...args)
88
+
89
+ // 渲染进程B: (two choices)
90
+ RendererIPC.handleRenderer(`${channel}`, async (...args) => { return res })
91
+ RendererIPC.handleRendererOnce(`${channel}`, async (...args) => { return res })
92
+ ```
93
+
94
+
95
+ #### 🌱 4. Renderer ↔ Main
96
+
97
+ 渲染进程可以向主进程发送消息并接收回调,如下面的示例所示 :
98
+
99
+ ```js
100
+ // RendererA:
101
+ const res = await RendererIPC.invokeMain(`${channel}`, ...args)
102
+
103
+ // MainB:
104
+ MainIPC.handleRenderer(`${channel}`, async (...args) => { return res })
105
+ ```
106
+
107
+ 这个例子是once的情况(handleRendererOnce必须与invokeMainOnce一起使用) :
108
+
109
+ ```js
110
+ // RendererA:
111
+ const res = await RendererIPC.invokeMainOnce(`${channel}`, ...args)
112
+
113
+ // MainB:
114
+ MainIPC.handleRendererOnce(`${channel}`, async (...args) => { return res })
115
+ ```
@@ -0,0 +1,41 @@
1
+ import type { BrowserWindow } from 'electron';
2
+ declare global {
3
+ interface Window {
4
+ __ELECTRON_WINDOW_MANAGER__?: any;
5
+ }
6
+ }
7
+ /** Tab ID */
8
+ export type TabID = number;
9
+ export interface Tab {
10
+ /** 标签URL */
11
+ url: string;
12
+ /** 标签href */
13
+ href: string;
14
+ /** 标签标题 */
15
+ title: string;
16
+ /** 标签favicon */
17
+ favicon: string;
18
+ /** loading */
19
+ isLoading: boolean;
20
+ /** 是否可返回上一页 */
21
+ canGoBack: boolean;
22
+ canGoForward: boolean;
23
+ }
24
+ export interface Tabs {
25
+ [key: number]: Tab;
26
+ }
27
+ export interface ElectronWindowsManagerOptions {
28
+ name: string;
29
+ loadingView?: {
30
+ url: string;
31
+ };
32
+ browserWindow?: any;
33
+ openDevTools?: boolean;
34
+ preventOriginClose?: boolean;
35
+ preventOriginNavigate?: boolean;
36
+ }
37
+ export interface WindowItem extends BrowserWindow {
38
+ /** BW别名 */
39
+ _name: string;
40
+ }
41
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/common/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAG9C,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,MAAM;QACd,2BAA2B,CAAC,EAAE,GAAG,CAAC;KACnC;CACF;AAED,aAAa;AACb,MAAM,MAAM,KAAK,GAAG,MAAM,CAAC;AAE3B,MAAM,WAAW,GAAG;IAClB,YAAY;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,aAAa;IACb,IAAI,EAAE,MAAM,CAAC;IACZ,WAAW;IACZ,KAAK,EAAE,MAAM,CAAC;IACb,gBAAgB;IACjB,OAAO,EAAE,MAAM,CAAC;IACf,cAAc;IACf,SAAS,EAAE,OAAO,CAAC;IACnB,eAAe;IACf,SAAS,EAAE,OAAO,CAAC;IACnB,YAAY,EAAE,OAAO,CAAC;CACvB;AAED,MAAM,WAAW,IAAI;IACjB,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;CACtB;AAED,MAAM,WAAW,6BAA6B;IAC1C,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE;QACZ,GAAG,EAAE,MAAM,CAAC;KACb,CAAC;IACF,aAAa,CAAC,EAAE,GAAG,CAAC;IACpB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,qBAAqB,CAAC,EAAE,OAAO,CAAC;CACnC;AAED,MAAM,WAAW,UAAW,SAAQ,aAAa;IAC/C,WAAW;IACX,KAAK,EAAE,MAAM,CAAC;CACf"}
@@ -0,0 +1,41 @@
1
+ import type { BrowserWindow } from 'electron';
2
+ declare global {
3
+ interface Window {
4
+ __ELECTRON_WINDOW_MANAGER__?: any;
5
+ }
6
+ }
7
+ /** Tab ID */
8
+ export type TabID = number;
9
+ export interface Tab {
10
+ /** 标签URL */
11
+ url: string;
12
+ /** 标签href */
13
+ href: string;
14
+ /** 标签标题 */
15
+ title: string;
16
+ /** 标签favicon */
17
+ favicon: string;
18
+ /** loading */
19
+ isLoading: boolean;
20
+ /** 是否可返回上一页 */
21
+ canGoBack: boolean;
22
+ canGoForward: boolean;
23
+ }
24
+ export interface Tabs {
25
+ [key: number]: Tab;
26
+ }
27
+ export interface ElectronWindowsManagerOptions {
28
+ name: string;
29
+ loadingView?: {
30
+ url: string;
31
+ };
32
+ browserWindow?: any;
33
+ openDevTools?: boolean;
34
+ preventOriginClose?: boolean;
35
+ preventOriginNavigate?: boolean;
36
+ }
37
+ export interface WindowItem extends BrowserWindow {
38
+ /** BW别名 */
39
+ _name: string;
40
+ }
41
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/common/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAG9C,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,MAAM;QACd,2BAA2B,CAAC,EAAE,GAAG,CAAC;KACnC;CACF;AAED,aAAa;AACb,MAAM,MAAM,KAAK,GAAG,MAAM,CAAC;AAE3B,MAAM,WAAW,GAAG;IAClB,YAAY;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,aAAa;IACb,IAAI,EAAE,MAAM,CAAC;IACZ,WAAW;IACZ,KAAK,EAAE,MAAM,CAAC;IACb,gBAAgB;IACjB,OAAO,EAAE,MAAM,CAAC;IACf,cAAc;IACf,SAAS,EAAE,OAAO,CAAC;IACnB,eAAe;IACf,SAAS,EAAE,OAAO,CAAC;IACnB,YAAY,EAAE,OAAO,CAAC;CACvB;AAED,MAAM,WAAW,IAAI;IACjB,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;CACtB;AAED,MAAM,WAAW,6BAA6B;IAC1C,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE;QACZ,GAAG,EAAE,MAAM,CAAC;KACb,CAAC;IACF,aAAa,CAAC,EAAE,GAAG,CAAC;IACpB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,qBAAqB,CAAC,EAAE,OAAO,CAAC;CACnC;AAED,MAAM,WAAW,UAAW,SAAQ,aAAa;IAC/C,WAAW;IACX,KAAK,EAAE,MAAM,CAAC;CACf"}
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":"AAKA,OAAO,EAAE,CAAC"}
package/esm/index.js ADDED
@@ -0,0 +1,5 @@
1
+ throw new Error(`electron 对主进程和渲染进程使用不同的代码:
2
+ 在electron主进程中, 你应该导入“@lynker-desktop/electron-ipc/main”
3
+ 在electron渲染过程中, 你应该导入“@lynker-desktop/electron-ipc/renderer”
4
+ `);
5
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sources":["../src/index.ts"],"sourcesContent":["throw new Error(`electron 对主进程和渲染进程使用不同的代码: \n在electron主进程中, 你应该导入“@lynker-desktop/electron-ipc/main” \n在electron渲染过程中, 你应该导入“@lynker-desktop/electron-ipc/renderer”\n`);\n\nexport {};"],"names":[],"mappings":"AAAA,MAAM,IAAI,KAAK,CAAC,CAAA;;;AAGf,CAAA,CAAC"}
@@ -0,0 +1,60 @@
1
+ export declare let isInitialized: boolean;
2
+ declare class MainIPC {
3
+ static instance: MainIPC;
4
+ private eventEmitter;
5
+ constructor();
6
+ /**
7
+ * 发送给主进程消息
8
+ * @param channel
9
+ * @param args
10
+ * @returns
11
+ */
12
+ invokeMain(channel: string, ...args: any[]): Promise<unknown>;
13
+ /**
14
+ * 处理一次性主进程发送过来的消息
15
+ * @param channel
16
+ * @param handler
17
+ */
18
+ handleMainOnce(channel: string, handler: (...args: any[]) => Promise<any>): void;
19
+ /**
20
+ * 处理主进程发送过来的消息
21
+ * @param channel
22
+ * @param handler
23
+ */
24
+ handleMain(channel: string, handler: (...args: any[]) => Promise<any>): void;
25
+ /**
26
+ * 发送给渲染进程消息
27
+ * @param webContents
28
+ * @param channel
29
+ * @param args
30
+ * @returns
31
+ */
32
+ invokeRenderer(webContents: Electron.WebContents, channel: string, ...args: any[]): Promise<any>;
33
+ /**
34
+ * 发送给所有渲染进程消息
35
+ * @param channel
36
+ * @param args
37
+ * @returns
38
+ */
39
+ invokeAllRenderer(channel: string, ...args: any[]): Promise<any>;
40
+ /**
41
+ * 处理一次性渲染进程发送过来的消息
42
+ * @param channel
43
+ * @param handler
44
+ */
45
+ handleRendererOnce(channel: string, handler: (...args: any[]) => Promise<any>): void;
46
+ /**
47
+ * 处理渲染进程发送过来的消息
48
+ * @param channel
49
+ * @param handler
50
+ */
51
+ handleRenderer(channel: string, handler: (...args: any[]) => Promise<any>): void;
52
+ /**
53
+ * 初始化
54
+ */
55
+ relayMessage(): void;
56
+ }
57
+ export declare const mainIPC: MainIPC;
58
+ export declare const initialize: () => void;
59
+ export {};
60
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/main/index.ts"],"names":[],"mappings":"AAIA,eAAO,IAAI,aAAa,SAAQ,CAAC;AACjC,cAAM,OAAO;IACZ,MAAM,CAAC,QAAQ,EAAE,OAAO,CAAA;IACxB,OAAO,CAAC,YAAY,CAAmC;;IAUtD;;;;;OAKG;IACE,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE;IAS/C;;;;OAIG;IACJ,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,OAAO,CAAC,GAAG,CAAC;IAOxE;;;;OAIG;IACJ,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,OAAO,CAAC,GAAG,CAAC;IAOpE;;;;;;OAMG;IACJ,cAAc,CAAC,WAAW,EAAE,QAAQ,CAAC,WAAW,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,OAAO,CAAC,GAAG,CAAC;IAoB/F;;;;;OAKG;IACJ,iBAAiB,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,OAAO,CAAC,GAAG,CAAC;IAqB/D;;;;OAIG;IACJ,kBAAkB,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,OAAO,CAAC,GAAG,CAAC;IAM5E;;;;OAIG;IACJ,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,OAAO,CAAC,GAAG,CAAC;IAKxE;;OAEG;IACJ,YAAY;CAoCZ;AAED,eAAO,MAAM,OAAO,SAAgB,CAAA;AAEpC,eAAO,MAAM,UAAU,YAKtB,CAAA"}
@@ -0,0 +1,171 @@
1
+ import { EventEmitter } from 'events';
2
+ import { webContents, ipcMain, BrowserWindow } from 'electron';
3
+
4
+ let isInitialized = false;
5
+ class MainIPC {
6
+ constructor() {
7
+ this.eventEmitter = new EventEmitter();
8
+ if (!MainIPC.instance) {
9
+ this.eventEmitter = new EventEmitter();
10
+ MainIPC.instance = this;
11
+ }
12
+ return MainIPC.instance;
13
+ }
14
+ /**
15
+ * 发送给主进程消息
16
+ * @param channel
17
+ * @param args
18
+ * @returns
19
+ */
20
+ async invokeMain(channel, ...args) {
21
+ return new Promise(resolve => {
22
+ this.eventEmitter.once(`${channel}-reply`, result => {
23
+ resolve(result);
24
+ });
25
+ this.eventEmitter.emit(channel, ...args);
26
+ });
27
+ }
28
+ /**
29
+ * 处理一次性主进程发送过来的消息
30
+ * @param channel
31
+ * @param handler
32
+ */
33
+ handleMainOnce(channel, handler) {
34
+ this.eventEmitter.once(channel, async (...args) => {
35
+ const result = await handler(...args);
36
+ this.eventEmitter.emit(`${channel}-reply`, result);
37
+ });
38
+ }
39
+ /**
40
+ * 处理主进程发送过来的消息
41
+ * @param channel
42
+ * @param handler
43
+ */
44
+ handleMain(channel, handler) {
45
+ this.eventEmitter.on(channel, async (...args) => {
46
+ const result = await handler(...args);
47
+ this.eventEmitter.emit(`${channel}-reply`, result);
48
+ });
49
+ }
50
+ /**
51
+ * 发送给渲染进程消息
52
+ * @param webContents
53
+ * @param channel
54
+ * @param args
55
+ * @returns
56
+ */
57
+ invokeRenderer(webContents, channel, ...args) {
58
+ return new Promise(resolve => {
59
+ const sendMessage = () => {
60
+ ipcMain.once(`${channel}-reply`, (_event, result) => {
61
+ resolve(result);
62
+ });
63
+ webContents.send(channel, ...args);
64
+ };
65
+ // 等待渲染进程加载完成后再推送,否则会导致渲染进程收不到消息
66
+ if (webContents.isLoading()) {
67
+ webContents.once('did-finish-load', () => {
68
+ setTimeout(() => sendMessage());
69
+ });
70
+ }
71
+ else {
72
+ sendMessage();
73
+ }
74
+ });
75
+ }
76
+ /**
77
+ * 发送给所有渲染进程消息
78
+ * @param channel
79
+ * @param args
80
+ * @returns
81
+ */
82
+ invokeAllRenderer(channel, ...args) {
83
+ return new Promise(resolve => {
84
+ webContents.getAllWebContents().forEach(webContent => {
85
+ const sendMessage = () => {
86
+ ipcMain.once(`${channel}-reply`, (_event, result) => {
87
+ resolve(result);
88
+ });
89
+ webContent.send(channel, ...args);
90
+ };
91
+ // 等待渲染进程加载完成后再推送,否则会导致渲染进程收不到消息
92
+ if (webContent.isLoading()) {
93
+ webContent.once('did-finish-load', () => {
94
+ setTimeout(() => sendMessage());
95
+ });
96
+ }
97
+ else {
98
+ sendMessage();
99
+ }
100
+ });
101
+ });
102
+ }
103
+ /**
104
+ * 处理一次性渲染进程发送过来的消息
105
+ * @param channel
106
+ * @param handler
107
+ */
108
+ handleRendererOnce(channel, handler) {
109
+ ipcMain.once(channel, async (_event, ...args) => {
110
+ const result = await handler(...args);
111
+ _event.sender.send(`${channel}-reply`, result);
112
+ });
113
+ }
114
+ /**
115
+ * 处理渲染进程发送过来的消息
116
+ * @param channel
117
+ * @param handler
118
+ */
119
+ handleRenderer(channel, handler) {
120
+ ipcMain.handle(channel, async (_event, ...args) => {
121
+ return await handler(...args);
122
+ });
123
+ }
124
+ /**
125
+ * 初始化
126
+ */
127
+ relayMessage() {
128
+ ipcMain.on('relay-message', (_event, { targetWindowId, channel, args }) => {
129
+ if (targetWindowId) {
130
+ const targetWindow = BrowserWindow.fromId(targetWindowId);
131
+ if (targetWindow) {
132
+ targetWindow.webContents.send(channel, ...args);
133
+ }
134
+ }
135
+ else {
136
+ BrowserWindow.getAllWindows().forEach(window => {
137
+ window.webContents.send(channel, ...args);
138
+ });
139
+ }
140
+ });
141
+ ipcMain.on('relay-reply', (_event, { originalChannel, result }) => {
142
+ // 所有渲染进程都会接收 ${originalChannel}-reply 事件,要求仅需要的渲染进程处理该事件的回复。
143
+ // 这样可以避免需要指定窗口 ID 回复消息,并确保消息能够正确传递和接收
144
+ BrowserWindow.getAllWindows().forEach(window => {
145
+ window.webContents.send(`${originalChannel}-reply`, result);
146
+ });
147
+ });
148
+ const getCurrentWebContentIdChannel = '__GetCurrentWebContentId__';
149
+ ipcMain.on(getCurrentWebContentIdChannel, (_event) => {
150
+ try {
151
+ _event.frameId;
152
+ const webContentId = _event?.sender?.id;
153
+ _event.sender.send(`${getCurrentWebContentIdChannel}-reply`, webContentId);
154
+ }
155
+ catch (error) {
156
+ return undefined;
157
+ }
158
+ });
159
+ console.error('xxxxx');
160
+ }
161
+ }
162
+ const mainIPC = new MainIPC();
163
+ const initialize = () => {
164
+ if (!isInitialized) {
165
+ isInitialized = true;
166
+ mainIPC.relayMessage();
167
+ }
168
+ };
169
+
170
+ export { initialize, isInitialized, mainIPC };
171
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sources":["../../src/main/index.ts"],"sourcesContent":["import { EventEmitter } from 'events'\n\nimport { ipcMain, BrowserWindow, webContents } from 'electron'\n\nexport let isInitialized = false;\nclass MainIPC {\n\tstatic instance: MainIPC\n\tprivate eventEmitter: EventEmitter = new EventEmitter()\n\n\tconstructor() {\n\t\tif (!MainIPC.instance) {\n\t\t\tthis.eventEmitter = new EventEmitter()\n\t\t\tMainIPC.instance = this\n\t\t}\n\t\treturn MainIPC.instance\n\t}\n\n /**\n * 发送给主进程消息\n * @param channel\n * @param args\n * @returns\n */\n\tasync invokeMain(channel: string, ...args: any[]) {\n\t\treturn new Promise(resolve => {\n\t\t\tthis.eventEmitter.once(`${channel}-reply`, result => {\n\t\t\t\tresolve(result)\n\t\t\t})\n\t\t\tthis.eventEmitter.emit(channel, ...args)\n\t\t})\n\t}\n\n /**\n * 处理一次性主进程发送过来的消息\n * @param channel\n * @param handler\n */\n\thandleMainOnce(channel: string, handler: (...args: any[]) => Promise<any>) {\n\t\tthis.eventEmitter.once(channel, async (...args) => {\n\t\t\tconst result = await handler(...args)\n\t\t\tthis.eventEmitter.emit(`${channel}-reply`, result)\n\t\t})\n\t}\n\n /**\n * 处理主进程发送过来的消息\n * @param channel\n * @param handler\n */\n\thandleMain(channel: string, handler: (...args: any[]) => Promise<any>) {\n\t\tthis.eventEmitter.on(channel, async (...args) => {\n\t\t\tconst result = await handler(...args)\n\t\t\tthis.eventEmitter.emit(`${channel}-reply`, result)\n\t\t})\n\t}\n\n /**\n * 发送给渲染进程消息\n * @param webContents\n * @param channel\n * @param args\n * @returns\n */\n\tinvokeRenderer(webContents: Electron.WebContents, channel: string, ...args: any[]): Promise<any> {\n\t\treturn new Promise(resolve => {\n\t\t\tconst sendMessage = () => {\n\t\t\t\tipcMain.once(`${channel}-reply`, (_event, result) => {\n\t\t\t\t\tresolve(result)\n\t\t\t\t})\n\t\t\t\twebContents.send(channel, ...args)\n\t\t\t}\n\n\t\t\t// 等待渲染进程加载完成后再推送,否则会导致渲染进程收不到消息\n\t\t\tif (webContents.isLoading()) {\n\t\t\t\twebContents.once('did-finish-load', () => {\n\t\t\t\t\tsetTimeout(() => sendMessage())\n\t\t\t\t})\n\t\t\t} else {\n\t\t\t\tsendMessage()\n\t\t\t}\n\t\t})\n\t}\n\n /**\n * 发送给所有渲染进程消息\n * @param channel\n * @param args\n * @returns\n */\n\tinvokeAllRenderer(channel: string, ...args: any[]): Promise<any> {\n\t\treturn new Promise(resolve => {\n\t\t\twebContents.getAllWebContents().forEach(webContent => {\n\t\t\t\tconst sendMessage = () => {\n\t\t\t\t\tipcMain.once(`${channel}-reply`, (_event, result) => {\n\t\t\t\t\t\tresolve(result)\n\t\t\t\t\t})\n\t\t\t\t\twebContent.send(channel, ...args)\n\t\t\t\t}\n\n\t\t\t\t// 等待渲染进程加载完成后再推送,否则会导致渲染进程收不到消息\n\t\t\t\tif (webContent.isLoading()) {\n\t\t\t\t\twebContent.once('did-finish-load', () => {\n\t\t\t\t\t\tsetTimeout(() => sendMessage())\n\t\t\t\t\t})\n\t\t\t\t} else {\n\t\t\t\t\tsendMessage()\n\t\t\t\t}\n\t\t\t})\n\t\t})\n\t}\n /**\n * 处理一次性渲染进程发送过来的消息\n * @param channel\n * @param handler\n */\n\thandleRendererOnce(channel: string, handler: (...args: any[]) => Promise<any>) {\n\t\tipcMain.once(channel, async (_event, ...args: any[]) => {\n\t\t\tconst result = await handler(...args)\n\t\t\t_event.sender.send(`${channel}-reply`, result)\n\t\t})\n\t}\n /**\n * 处理渲染进程发送过来的消息\n * @param channel\n * @param handler\n */\n\thandleRenderer(channel: string, handler: (...args: any[]) => Promise<any>) {\n\t\tipcMain.handle(channel, async (_event, ...args: any[]) => {\n\t\t\treturn await handler(...args)\n\t\t})\n\t}\n /**\n * 初始化\n */\n\trelayMessage() {\n\t\tipcMain.on('relay-message', (_event, { targetWindowId, channel, args }) => {\n\t\t\tif (targetWindowId) {\n\t\t\t\tconst targetWindow = BrowserWindow.fromId(targetWindowId)\n\t\t\t\tif (targetWindow) {\n\t\t\t\t\ttargetWindow.webContents.send(channel, ...args)\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tBrowserWindow.getAllWindows().forEach(window => {\n\t\t\t\t\twindow.webContents.send(channel, ...args)\n\t\t\t\t})\n\t\t\t}\n\t\t})\n\n\t\tipcMain.on('relay-reply', (_event, { originalChannel, result }) => {\n\t\t\t// 所有渲染进程都会接收 ${originalChannel}-reply 事件,要求仅需要的渲染进程处理该事件的回复。\n\t\t\t// 这样可以避免需要指定窗口 ID 回复消息,并确保消息能够正确传递和接收\n\t\t\tBrowserWindow.getAllWindows().forEach(window => {\n\t\t\t\twindow.webContents.send(`${originalChannel}-reply`, result)\n\t\t\t})\n\t\t})\n\n const getCurrentWebContentIdChannel = '__GetCurrentWebContentId__'\n ipcMain.on(getCurrentWebContentIdChannel, (_event) => {\n try {\n _event.frameId\n const webContentId = _event?.sender?.id;\n _event.sender.send(`${getCurrentWebContentIdChannel}-reply`, webContentId)\n } catch (error) {\n return undefined\n }\n\t\t})\n\n console.error('xxxxx')\n\t}\n\n}\n\nexport const mainIPC = new MainIPC()\n\nexport const initialize = () => {\n if (!isInitialized){\n isInitialized = true;\n\t\tmainIPC.relayMessage()\n }\n}\n"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ {"type": "module"}
@@ -0,0 +1,22 @@
1
+ import { ipcRenderer, contextBridge } from 'electron';
2
+
3
+ // @ts-ignore
4
+ if (window.__ELECTRON_IPC__) {
5
+ // eslint-disable-next-line no-console
6
+ console.log('electron-ipc Electron preload has already been run');
7
+ }
8
+ else {
9
+ // @ts-ignore
10
+ window.__ELECTRON_IPC__ = ipcRenderer;
11
+ if (contextBridge) {
12
+ // This will fail if contextIsolation is not enabled
13
+ try {
14
+ // @ts-ignore
15
+ contextBridge.exposeInMainWorld('__ELECTRON_IPC__', ipcRenderer);
16
+ }
17
+ catch (e) {
18
+ // console.error(e)
19
+ }
20
+ }
21
+ }
22
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sources":["../../src/src/preload/index.ts"],"sourcesContent":["import { ipcRenderer, contextBridge } from 'electron';\n\n// @ts-ignore\nif (window.__ELECTRON_IPC__) {\n // eslint-disable-next-line no-console\n console.log('electron-ipc Electron preload has already been run');\n} else {\n // @ts-ignore\n window.__ELECTRON_IPC__ = ipcRenderer;\n if (contextBridge) {\n // This will fail if contextIsolation is not enabled\n try {\n // @ts-ignore\n contextBridge.exposeInMainWorld('__ELECTRON_IPC__', ipcRenderer);\n } catch (e) {\n // console.error(e)\n }\n }\n}\n"],"names":[],"mappings":";;AAEA;AACA,IAAI,MAAM,CAAC,gBAAgB,EAAE;;AAE3B,IAAA,OAAO,CAAC,GAAG,CAAC,oDAAoD,CAAC,CAAC;AACpE,CAAC;KAAM;;AAEL,IAAA,MAAM,CAAC,gBAAgB,GAAG,WAAW,CAAC;IACtC,IAAI,aAAa,EAAE;;AAEjB,QAAA,IAAI;;AAEF,YAAA,aAAa,CAAC,iBAAiB,CAAC,kBAAkB,EAAE,WAAW,CAAC,CAAC;SAClE;QAAC,OAAO,CAAC,EAAE;;SAEX;KACF;AACH"}
@@ -0,0 +1,62 @@
1
+ import type { IpcRenderer } from 'electron';
2
+ export declare const getIpc: () => IpcRenderer;
3
+ export declare class RendererIPC {
4
+ /**
5
+ * 发送一次性给主进程消息
6
+ * @param channel
7
+ * @param args
8
+ * @returns
9
+ */
10
+ static invokeMainOnce(channel: string, ...args: any[]): Promise<any>;
11
+ /**
12
+ * 发送给主进程消息
13
+ * @param channel
14
+ * @param args
15
+ * @returns
16
+ */
17
+ static invokeMain(channel: string, ...args: any[]): Promise<any>;
18
+ /**
19
+ * 处理一次性主进程发送过来的消息
20
+ * @param channel
21
+ * @param handler
22
+ */
23
+ static handleMainOnce(channel: string, handler: (...args: any[]) => Promise<any>): void;
24
+ /**
25
+ * 处理主进程发送过来的消息
26
+ * @param channel
27
+ * @param handler
28
+ */
29
+ static handleMain(channel: string, handler: (...args: any[]) => Promise<any>): void;
30
+ /**
31
+ * 发送给渲染进程消息
32
+ * @param channel
33
+ * @param args
34
+ * @returns
35
+ */
36
+ static invokeRenderer(channel: string, ...args: any[]): Promise<any>;
37
+ /**
38
+ * 发送给指定渲染进程消息
39
+ * @param targetWindowId
40
+ * @param channel
41
+ * @param args
42
+ * @returns
43
+ */
44
+ static invokeRendererByWinId(targetWindowId: number, channel: string, ...args: any[]): Promise<any>;
45
+ /**
46
+ * 处理一次性渲染进程发送过来的消息
47
+ * @param channel
48
+ * @param handler
49
+ */
50
+ static handleRendererOnce(channel: string, handler: (...args: any[]) => Promise<any>): void;
51
+ /**
52
+ * 处理渲染进程发送过来的消息
53
+ * @param channel
54
+ * @param handler
55
+ */
56
+ static handleRenderer(channel: string, handler: (...args: any[]) => Promise<any>): void;
57
+ /**
58
+ * 获取当前渲染进程id
59
+ */
60
+ static getCurrentWebContentId(): Promise<number>;
61
+ }
62
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/renderer/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAoB,MAAM,UAAU,CAAA;AAC7D,eAAO,MAAM,MAAM,QAAO,WAQzB,CAAA;AAED,qBAAa,WAAW;IACtB;;;;;OAKG;IACJ,MAAM,CAAC,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,OAAO,CAAC,GAAG,CAAC;IAQnE;;;;;OAKG;WACS,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,OAAO,CAAC,GAAG,CAAC;IAGrE;;;;OAIG;IACJ,MAAM,CAAC,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,OAAO,CAAC,GAAG,CAAC;IAM/E;;;;OAIG;IACJ,MAAM,CAAC,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,OAAO,CAAC,GAAG,CAAC;IAM3E;;;;;OAKG;IACJ,MAAM,CAAC,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,OAAO,CAAC,GAAG,CAAC;IASnE;;;;;;OAMG;IACJ,MAAM,CAAC,qBAAqB,CAAC,cAAc,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,OAAO,CAAC,GAAG,CAAC;IASlG;;;;OAIG;IACJ,MAAM,CAAC,kBAAkB,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,OAAO,CAAC,GAAG,CAAC;IAOnF;;;;OAIG;IACJ,MAAM,CAAC,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,OAAO,CAAC,GAAG,CAAC;IAO/E;;OAEG;WACU,sBAAsB,IAAI,OAAO,CAAC,MAAM,CAAC;CASvD"}