@lynker-desktop/electron-ipc 0.0.9-alpha.25 → 0.0.9-alpha.27

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/common/index.d.ts CHANGED
@@ -39,5 +39,5 @@ export interface WindowItem extends BrowserWindow {
39
39
  /** BW别名 */
40
40
  _name: string;
41
41
  }
42
- export declare function getRandomUUID(key?: string): string;
42
+ export declare const getRandomUUID: (key?: string) => string;
43
43
  //# sourceMappingURL=index.d.ts.map
@@ -1 +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;AAI9C,eAAO,MAAM,kBAAkB,qBAAqB,CAAC;AAGrD,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;AAED,wBAAgB,aAAa,CAAC,GAAG,GAAE,MAAwB,GAAG,MAAM,CAiBnE"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/common/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAI9C,eAAO,MAAM,kBAAkB,qBAAqB,CAAC;AAGrD,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;AAED,eAAO,MAAM,aAAa,SAAS,MAAM,KAAqB,MAiB7D,CAAA"}
package/common/index.js CHANGED
@@ -1,4 +1,26 @@
1
+ const md5 = require('md5');
2
+ const uuid = require('uuid');
3
+
1
4
  const WINDOWL_GLOBAL_KEY = `__ELECTRON_IPC__`;
5
+ const getRandomUUID = (key = `${Date.now()}`) => {
6
+ let webcrypto;
7
+ let randomValue = Math?.random()?.toString()?.replace('0.', '');
8
+ try {
9
+ if (!webcrypto && !!window && window?.crypto) {
10
+ webcrypto = window.crypto;
11
+ }
12
+ }
13
+ catch (error) {
14
+ }
15
+ try {
16
+ const ar = webcrypto.getRandomValues(new Uint8Array(12));
17
+ randomValue = `${md5(ar)}` || randomValue;
18
+ }
19
+ catch (error) { }
20
+ const uuid$1 = uuid.v5(`${JSON.stringify(key)}_${Date.now()}_${randomValue}`, uuid.v5.URL);
21
+ return uuid$1;
22
+ };
2
23
 
3
24
  exports.WINDOWL_GLOBAL_KEY = WINDOWL_GLOBAL_KEY;
25
+ exports.getRandomUUID = getRandomUUID;
4
26
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../src/src/common/index.ts"],"sourcesContent":["import type { BrowserWindow } from 'electron';\nimport md5 from 'md5';\nimport { v5 as uuidv5 } from 'uuid';\n\nexport const WINDOWL_GLOBAL_KEY = `__ELECTRON_IPC__`;\n\n// @ts-ignore\ndeclare global {\n interface Window {\n __ELECTRON_WINDOW_MANAGER__?: any;\n }\n}\n\n/** Tab ID */\nexport type TabID = number;\n\nexport interface Tab {\n /** 标签URL */\n url: string;\n /** 标签href */\n href: string;\n /** 标签标题 */\n title: string;\n /** 标签favicon */\n favicon: string;\n /** loading */\n isLoading: boolean;\n /** 是否可返回上一页 */\n canGoBack: boolean;\n canGoForward: boolean;\n}\n\nexport interface Tabs {\n [key: number]: Tab;\n}\n\nexport interface ElectronWindowsManagerOptions {\n name: string;\n loadingView?: {\n url: string;\n };\n browserWindow?: any;\n openDevTools?: boolean;\n preventOriginClose?: boolean;\n preventOriginNavigate?: boolean;\n}\n\nexport interface WindowItem extends BrowserWindow {\n /** BW别名 */\n _name: string;\n}\n\nexport function getRandomUUID(key: string = `${Date.now()}`): string {\n let webcrypto!: Crypto;\n let randomValue = Math?.random()?.toString()?.replace('0.', '');\n try {\n if (!webcrypto && !!window && window?.crypto) {\n webcrypto = window.crypto;\n }\n } catch (error) {console.log}\n try {\n const ar = webcrypto.getRandomValues(new Uint8Array(12));\n randomValue = `${md5(ar)}` || randomValue;\n } catch (error) {}\n const uuid = uuidv5(\n `${JSON.stringify(key)}_${Date.now()}_${randomValue}`,\n uuidv5.URL,\n );\n return uuid;\n}\n"],"names":[],"mappings":"AAIO,MAAM,kBAAkB,GAAG;;;;"}
1
+ {"version":3,"file":"index.js","sources":["../src/src/common/index.ts"],"sourcesContent":["import type { BrowserWindow } from 'electron';\nimport md5 from 'md5';\nimport { v5 as uuidv5 } from 'uuid';\n\nexport const WINDOWL_GLOBAL_KEY = `__ELECTRON_IPC__`;\n\n// @ts-ignore\ndeclare global {\n interface Window {\n __ELECTRON_WINDOW_MANAGER__?: any;\n }\n}\n\n/** Tab ID */\nexport type TabID = number;\n\nexport interface Tab {\n /** 标签URL */\n url: string;\n /** 标签href */\n href: string;\n /** 标签标题 */\n title: string;\n /** 标签favicon */\n favicon: string;\n /** loading */\n isLoading: boolean;\n /** 是否可返回上一页 */\n canGoBack: boolean;\n canGoForward: boolean;\n}\n\nexport interface Tabs {\n [key: number]: Tab;\n}\n\nexport interface ElectronWindowsManagerOptions {\n name: string;\n loadingView?: {\n url: string;\n };\n browserWindow?: any;\n openDevTools?: boolean;\n preventOriginClose?: boolean;\n preventOriginNavigate?: boolean;\n}\n\nexport interface WindowItem extends BrowserWindow {\n /** BW别名 */\n _name: string;\n}\n\nexport const getRandomUUID = (key: string = `${Date.now()}`): string => {\n let webcrypto!: Crypto;\n let randomValue = Math?.random()?.toString()?.replace('0.', '');\n try {\n if (!webcrypto && !!window && window?.crypto) {\n webcrypto = window.crypto;\n }\n } catch (error) {console.log}\n try {\n const ar = webcrypto.getRandomValues(new Uint8Array(12));\n randomValue = `${md5(ar)}` || randomValue;\n } catch (error) {}\n const uuid = uuidv5(\n `${JSON.stringify(key)}_${Date.now()}_${randomValue}`,\n uuidv5.URL,\n );\n return uuid;\n}\n"],"names":["uuid","uuidv5"],"mappings":";;;AAIO,MAAM,kBAAkB,GAAG,mBAAmB;AAgD9C,MAAM,aAAa,GAAG,CAAC,GAAA,GAAc,CAAG,EAAA,IAAI,CAAC,GAAG,EAAE,CAAA,CAAE,KAAY;AACrE,IAAA,IAAI,SAAkB,CAAC;AACvB,IAAA,IAAI,WAAW,GAAG,IAAI,EAAE,MAAM,EAAE,EAAE,QAAQ,EAAE,EAAE,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;AAChE,IAAA,IAAI;QACF,IAAI,CAAC,SAAS,IAAI,CAAC,CAAC,MAAM,IAAI,MAAM,EAAE,MAAM,EAAE;AAC5C,YAAA,SAAS,GAAG,MAAM,CAAC,MAAM,CAAC;SAC3B;KACF;IAAC,OAAO,KAAK,EAAE;KAAa;AAC7B,IAAA,IAAI;AACF,QAAA,MAAM,EAAE,GAAG,SAAS,CAAC,eAAe,CAAC,IAAI,UAAU,CAAC,EAAE,CAAC,CAAC,CAAC;QACzD,WAAW,GAAG,GAAG,GAAG,CAAC,EAAE,CAAC,CAAA,CAAE,IAAI,WAAW,CAAC;KAC3C;AAAC,IAAA,OAAO,KAAK,EAAE,GAAE;IAClB,MAAMA,MAAI,GAAGC,OAAM,CACjB,CAAA,EAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAA,CAAA,EAAI,IAAI,CAAC,GAAG,EAAE,CAAA,CAAA,EAAI,WAAW,CAAA,CAAE,EACrDA,OAAM,CAAC,GAAG,CACX,CAAC;AACF,IAAA,OAAOD,MAAI,CAAC;AACd;;;;;"}
@@ -39,5 +39,5 @@ export interface WindowItem extends BrowserWindow {
39
39
  /** BW别名 */
40
40
  _name: string;
41
41
  }
42
- export declare function getRandomUUID(key?: string): string;
42
+ export declare const getRandomUUID: (key?: string) => string;
43
43
  //# sourceMappingURL=index.d.ts.map
@@ -1 +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;AAI9C,eAAO,MAAM,kBAAkB,qBAAqB,CAAC;AAGrD,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;AAED,wBAAgB,aAAa,CAAC,GAAG,GAAE,MAAwB,GAAG,MAAM,CAiBnE"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/common/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAI9C,eAAO,MAAM,kBAAkB,qBAAqB,CAAC;AAGrD,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;AAED,eAAO,MAAM,aAAa,SAAS,MAAM,KAAqB,MAiB7D,CAAA"}
@@ -1,4 +1,25 @@
1
+ import md5 from 'md5';
2
+ import { v5 } from 'uuid';
3
+
1
4
  const WINDOWL_GLOBAL_KEY = `__ELECTRON_IPC__`;
5
+ const getRandomUUID = (key = `${Date.now()}`) => {
6
+ let webcrypto;
7
+ let randomValue = Math?.random()?.toString()?.replace('0.', '');
8
+ try {
9
+ if (!webcrypto && !!window && window?.crypto) {
10
+ webcrypto = window.crypto;
11
+ }
12
+ }
13
+ catch (error) {
14
+ }
15
+ try {
16
+ const ar = webcrypto.getRandomValues(new Uint8Array(12));
17
+ randomValue = `${md5(ar)}` || randomValue;
18
+ }
19
+ catch (error) { }
20
+ const uuid = v5(`${JSON.stringify(key)}_${Date.now()}_${randomValue}`, v5.URL);
21
+ return uuid;
22
+ };
2
23
 
3
- export { WINDOWL_GLOBAL_KEY };
24
+ export { WINDOWL_GLOBAL_KEY, getRandomUUID };
4
25
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../../src/common/index.ts"],"sourcesContent":["import type { BrowserWindow } from 'electron';\nimport md5 from 'md5';\nimport { v5 as uuidv5 } from 'uuid';\n\nexport const WINDOWL_GLOBAL_KEY = `__ELECTRON_IPC__`;\n\n// @ts-ignore\ndeclare global {\n interface Window {\n __ELECTRON_WINDOW_MANAGER__?: any;\n }\n}\n\n/** Tab ID */\nexport type TabID = number;\n\nexport interface Tab {\n /** 标签URL */\n url: string;\n /** 标签href */\n href: string;\n /** 标签标题 */\n title: string;\n /** 标签favicon */\n favicon: string;\n /** loading */\n isLoading: boolean;\n /** 是否可返回上一页 */\n canGoBack: boolean;\n canGoForward: boolean;\n}\n\nexport interface Tabs {\n [key: number]: Tab;\n}\n\nexport interface ElectronWindowsManagerOptions {\n name: string;\n loadingView?: {\n url: string;\n };\n browserWindow?: any;\n openDevTools?: boolean;\n preventOriginClose?: boolean;\n preventOriginNavigate?: boolean;\n}\n\nexport interface WindowItem extends BrowserWindow {\n /** BW别名 */\n _name: string;\n}\n\nexport function getRandomUUID(key: string = `${Date.now()}`): string {\n let webcrypto!: Crypto;\n let randomValue = Math?.random()?.toString()?.replace('0.', '');\n try {\n if (!webcrypto && !!window && window?.crypto) {\n webcrypto = window.crypto;\n }\n } catch (error) {console.log}\n try {\n const ar = webcrypto.getRandomValues(new Uint8Array(12));\n randomValue = `${md5(ar)}` || randomValue;\n } catch (error) {}\n const uuid = uuidv5(\n `${JSON.stringify(key)}_${Date.now()}_${randomValue}`,\n uuidv5.URL,\n );\n return uuid;\n}\n"],"names":[],"mappings":"AAIO,MAAM,kBAAkB,GAAG;;;;"}
1
+ {"version":3,"file":"index.js","sources":["../../src/common/index.ts"],"sourcesContent":["import type { BrowserWindow } from 'electron';\nimport md5 from 'md5';\nimport { v5 as uuidv5 } from 'uuid';\n\nexport const WINDOWL_GLOBAL_KEY = `__ELECTRON_IPC__`;\n\n// @ts-ignore\ndeclare global {\n interface Window {\n __ELECTRON_WINDOW_MANAGER__?: any;\n }\n}\n\n/** Tab ID */\nexport type TabID = number;\n\nexport interface Tab {\n /** 标签URL */\n url: string;\n /** 标签href */\n href: string;\n /** 标签标题 */\n title: string;\n /** 标签favicon */\n favicon: string;\n /** loading */\n isLoading: boolean;\n /** 是否可返回上一页 */\n canGoBack: boolean;\n canGoForward: boolean;\n}\n\nexport interface Tabs {\n [key: number]: Tab;\n}\n\nexport interface ElectronWindowsManagerOptions {\n name: string;\n loadingView?: {\n url: string;\n };\n browserWindow?: any;\n openDevTools?: boolean;\n preventOriginClose?: boolean;\n preventOriginNavigate?: boolean;\n}\n\nexport interface WindowItem extends BrowserWindow {\n /** BW别名 */\n _name: string;\n}\n\nexport const getRandomUUID = (key: string = `${Date.now()}`): string => {\n let webcrypto!: Crypto;\n let randomValue = Math?.random()?.toString()?.replace('0.', '');\n try {\n if (!webcrypto && !!window && window?.crypto) {\n webcrypto = window.crypto;\n }\n } catch (error) {console.log}\n try {\n const ar = webcrypto.getRandomValues(new Uint8Array(12));\n randomValue = `${md5(ar)}` || randomValue;\n } catch (error) {}\n const uuid = uuidv5(\n `${JSON.stringify(key)}_${Date.now()}_${randomValue}`,\n uuidv5.URL,\n );\n return uuid;\n}\n"],"names":["uuidv5"],"mappings":";;;AAIO,MAAM,kBAAkB,GAAG,mBAAmB;AAgD9C,MAAM,aAAa,GAAG,CAAC,GAAA,GAAc,CAAG,EAAA,IAAI,CAAC,GAAG,EAAE,CAAA,CAAE,KAAY;AACrE,IAAA,IAAI,SAAkB,CAAC;AACvB,IAAA,IAAI,WAAW,GAAG,IAAI,EAAE,MAAM,EAAE,EAAE,QAAQ,EAAE,EAAE,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;AAChE,IAAA,IAAI;QACF,IAAI,CAAC,SAAS,IAAI,CAAC,CAAC,MAAM,IAAI,MAAM,EAAE,MAAM,EAAE;AAC5C,YAAA,SAAS,GAAG,MAAM,CAAC,MAAM,CAAC;SAC3B;KACF;IAAC,OAAO,KAAK,EAAE;KAAa;AAC7B,IAAA,IAAI;AACF,QAAA,MAAM,EAAE,GAAG,SAAS,CAAC,eAAe,CAAC,IAAI,UAAU,CAAC,EAAE,CAAC,CAAC,CAAC;QACzD,WAAW,GAAG,GAAG,GAAG,CAAC,EAAE,CAAC,CAAA,CAAE,IAAI,WAAW,CAAC;KAC3C;AAAC,IAAA,OAAO,KAAK,EAAE,GAAE;IAClB,MAAM,IAAI,GAAGA,EAAM,CACjB,CAAA,EAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAA,CAAA,EAAI,IAAI,CAAC,GAAG,EAAE,CAAA,CAAA,EAAI,WAAW,CAAA,CAAE,EACrDA,EAAM,CAAC,GAAG,CACX,CAAC;AACF,IAAA,OAAO,IAAI,CAAC;AACd;;;;"}
@@ -1,60 +1,123 @@
1
1
  export declare let isInitialized: boolean;
2
+ /**
3
+ * 主进程 IPC 通信类
4
+ * 负责处理主进程与渲染进程之间的消息通信
5
+ * 使用单例模式确保全局唯一实例
6
+ *
7
+ * 修复说明:
8
+ * - 为每个请求生成唯一的 requestId,解决并发请求数据错乱问题
9
+ * - 确保请求和响应能够正确匹配,避免多个并发请求互相干扰
10
+ */
2
11
  declare class MainIPC {
3
12
  static instance: MainIPC;
4
13
  private eventEmitter;
5
14
  constructor();
6
15
  /**
7
16
  * 发送给主进程消息
8
- * @param channel
9
- * @param args
10
- * @returns
17
+ * 使用唯一的 requestId 确保并发请求不会互相干扰
18
+ *
19
+ * @param channel 消息通道名称
20
+ * @param args 传递给处理器的参数
21
+ * @returns Promise<any> 返回处理结果
22
+ *
23
+ * 修复说明:
24
+ * - 为每个请求生成唯一的 requestId
25
+ * - 监听 `${channel}-reply-${requestId}` 事件,确保只接收对应请求的回复
26
+ * - 发送请求时包含 requestId,让处理器知道如何回复
11
27
  */
12
28
  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
29
  /**
20
30
  * 处理主进程发送过来的消息
21
- * @param channel
22
- * @param handler
31
+ * 持续监听指定通道的消息
32
+ *
33
+ * @param channel 消息通道名称
34
+ * @param handler 处理函数,接收除 requestId 外的所有参数
35
+ *
36
+ * 修复说明:
37
+ * - 接收 requestId 作为第一个参数
38
+ * - 使用 `${channel}-reply-${requestId}` 发送回复,确保回复给正确的请求
39
+ * - 支持多个并发请求,每个请求都有独立的回复通道
23
40
  */
24
- handleMain(channel: string, handler: (...args: any[]) => Promise<any>): void;
41
+ handleMain(channel: string, handler: (...args: any[]) => Promise<any>): {
42
+ cancel: () => void;
43
+ };
25
44
  /**
26
45
  * 发送给渲染进程消息
27
- * @param webContents
28
- * @param channel
29
- * @param args
30
- * @returns
46
+ * 使用唯一的 requestId 确保并发请求不会互相干扰
47
+ *
48
+ * @param webContents 目标渲染进程的 WebContents 对象
49
+ * @param channel 消息通道名称
50
+ * @param args 传递给渲染进程的参数
51
+ * @returns Promise<any> 返回渲染进程的处理结果
52
+ *
53
+ * 修复说明:
54
+ * - 为每个请求生成唯一的 requestId
55
+ * - 监听 `${channel}-reply-${requestId}` 事件,确保只接收对应请求的回复
56
+ * - 发送请求时包含 requestId,让渲染进程知道如何回复
57
+ * - 等待渲染进程加载完成后再发送消息,确保消息能够被正确接收
31
58
  */
32
59
  invokeRenderer(webContents: Electron.WebContents, channel: string, ...args: any[]): Promise<any>;
33
60
  /**
34
- * 发送给所有渲染进程消息
35
- * @param channel
36
- * @param args
37
- * @returns
38
- */
61
+ * 发送给所有渲染进程消息
62
+ * 向所有渲染进程发送消息并收集所有响应
63
+ *
64
+ * @param channel 消息通道名称
65
+ * @param args 传递给所有渲染进程的参数
66
+ * @returns Promise<any[]> 返回所有渲染进程的处理结果数组
67
+ *
68
+ * 修复说明:
69
+ * - 为每个请求生成唯一的 requestId
70
+ * - 收集所有渲染进程的响应,当所有响应都收到时才 resolve
71
+ * - 使用 `${channel}-reply-${requestId}` 确保只接收对应请求的回复
72
+ * - 如果没有渲染进程,直接返回空数组
73
+ * - 等待每个渲染进程加载完成后再发送消息
74
+ */
39
75
  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
76
  /**
47
77
  * 处理渲染进程发送过来的消息
48
- * @param channel
49
- * @param handler
78
+ * 持续监听指定通道的消息,支持超时处理
79
+ *
80
+ * @param channel 消息通道名称
81
+ * @param handler 处理函数,接收除 requestId 外的所有参数
82
+ *
83
+ * 修复说明:
84
+ * - 接收 requestId 作为第一个参数
85
+ * - 使用 ipcMain.handle 替代 ipcMain.on,提供更好的错误处理
86
+ * - 支持 8 秒超时机制,避免长时间等待
87
+ * - 支持并发请求,每个请求都有独立的处理流程
88
+ * - 提供详细的错误日志记录
50
89
  */
51
- handleRenderer(channel: string, handler: (...args: any[]) => Promise<any>): void;
90
+ handleRenderer(channel: string, handler: (...args: any[]) => Promise<any>): {
91
+ cancel: () => void;
92
+ };
52
93
  /**
53
- * 初始化
94
+ * 初始化消息中继功能
95
+ * 设置消息转发和回复机制,支持跨渲染进程通信
96
+ *
97
+ * 功能说明:
98
+ * - relay-message: 转发消息到指定的渲染进程或所有渲染进程
99
+ * - relay-reply: 处理回复消息,广播给所有渲染进程
100
+ * - __GetCurrentWebContentId__: 获取当前 WebContent ID
101
+ * - __OpenCurrentWebContentDevTools__: 打开当前 WebContent 的开发者工具
54
102
  */
55
103
  relayMessage(): void;
56
104
  }
105
+ /**
106
+ * 全局 MainIPC 实例
107
+ * 使用全局变量确保单例模式,避免重复创建实例
108
+ */
57
109
  export declare const mainIPC: MainIPC;
110
+ /**
111
+ * 初始化 IPC 通信系统
112
+ * 设置消息中继功能,确保跨进程通信正常工作
113
+ *
114
+ * @returns MainIPC 实例
115
+ *
116
+ * 功能说明:
117
+ * - 检查是否已经初始化,避免重复初始化
118
+ * - 设置消息中继功能,支持跨渲染进程通信
119
+ * - 返回全局 MainIPC 实例
120
+ */
58
121
  export declare const initialize: () => any;
59
122
  export {};
60
123
  //# sourceMappingURL=index.d.ts.map
@@ -1 +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;IAqCxE;;OAEG;IACJ,YAAY;CA8CZ;AAED,eAAO,MAAM,OAAO,EAAE,OAAgH,CAAC;AAEvI,eAAO,MAAM,UAAU,WAWtB,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/main/index.ts"],"names":[],"mappings":"AAIA,eAAO,IAAI,aAAa,SAAQ,CAAC;AAEjC;;;;;;;;GAQG;AACH,cAAM,OAAO;IACZ,MAAM,CAAC,QAAQ,EAAE,OAAO,CAAA;IACxB,OAAO,CAAC,YAAY,CAAmC;;IAUtD;;;;;;;;;;;;OAYG;IACE,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE;IAU/C;;;;;;;;;;;OAWG;IACJ,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,OAAO,CAAC,GAAG,CAAC;;;IAYpE;;;;;;;;;;;;;;OAcG;IACJ,cAAc,CAAC,WAAW,EAAE,QAAQ,CAAC,WAAW,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,OAAO,CAAC,GAAG,CAAC;IAqB7F;;;;;;;;;;;;;;KAcC;IACJ,iBAAiB,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,OAAO,CAAC,GAAG,CAAC;IAqC/D;;;;;;;;;;;;;OAaG;IACJ,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,OAAO,CAAC,GAAG,CAAC;;;IA0CxE;;;;;;;;;OASG;IACJ,YAAY;CAuDZ;AAED;;;GAGG;AAEH,eAAO,MAAM,OAAO,EAAE,OAAgH,CAAC;AAEvI;;;;;;;;;;GAUG;AACH,eAAO,MAAM,UAAU,WAWtB,CAAA"}
package/esm/main/index.js CHANGED
@@ -1,8 +1,17 @@
1
1
  import { EventEmitter } from 'events';
2
2
  import { webContents, ipcMain } from 'electron';
3
+ import { getRandomUUID } from '../common/index.js';
3
4
 
4
- // import { getRandomUUID } from '../common'
5
5
  let isInitialized = false;
6
+ /**
7
+ * 主进程 IPC 通信类
8
+ * 负责处理主进程与渲染进程之间的消息通信
9
+ * 使用单例模式确保全局唯一实例
10
+ *
11
+ * 修复说明:
12
+ * - 为每个请求生成唯一的 requestId,解决并发请求数据错乱问题
13
+ * - 确保请求和响应能够正确匹配,避免多个并发请求互相干扰
14
+ */
6
15
  class MainIPC {
7
16
  constructor() {
8
17
  this.eventEmitter = new EventEmitter();
@@ -14,54 +23,72 @@ class MainIPC {
14
23
  }
15
24
  /**
16
25
  * 发送给主进程消息
17
- * @param channel
18
- * @param args
19
- * @returns
26
+ * 使用唯一的 requestId 确保并发请求不会互相干扰
27
+ *
28
+ * @param channel 消息通道名称
29
+ * @param args 传递给处理器的参数
30
+ * @returns Promise<any> 返回处理结果
31
+ *
32
+ * 修复说明:
33
+ * - 为每个请求生成唯一的 requestId
34
+ * - 监听 `${channel}-reply-${requestId}` 事件,确保只接收对应请求的回复
35
+ * - 发送请求时包含 requestId,让处理器知道如何回复
20
36
  */
21
37
  async invokeMain(channel, ...args) {
22
38
  return new Promise(resolve => {
23
- this.eventEmitter.once(`${channel}-reply`, result => {
39
+ const requestId = getRandomUUID();
40
+ this.eventEmitter.once(`${channel}-reply-${requestId}`, result => {
24
41
  resolve(result);
25
42
  });
26
- this.eventEmitter.emit(channel, ...args);
27
- });
28
- }
29
- /**
30
- * 处理一次性主进程发送过来的消息
31
- * @param channel
32
- * @param handler
33
- */
34
- handleMainOnce(channel, handler) {
35
- this.eventEmitter.once(channel, async (...args) => {
36
- const result = await handler(...args);
37
- this.eventEmitter.emit(`${channel}-reply`, result);
43
+ this.eventEmitter.emit(channel, requestId, ...args);
38
44
  });
39
45
  }
40
46
  /**
41
47
  * 处理主进程发送过来的消息
42
- * @param channel
43
- * @param handler
48
+ * 持续监听指定通道的消息
49
+ *
50
+ * @param channel 消息通道名称
51
+ * @param handler 处理函数,接收除 requestId 外的所有参数
52
+ *
53
+ * 修复说明:
54
+ * - 接收 requestId 作为第一个参数
55
+ * - 使用 `${channel}-reply-${requestId}` 发送回复,确保回复给正确的请求
56
+ * - 支持多个并发请求,每个请求都有独立的回复通道
44
57
  */
45
58
  handleMain(channel, handler) {
46
- this.eventEmitter.on(channel, async (...args) => {
59
+ this.eventEmitter.on(channel, async (requestId, ...args) => {
47
60
  const result = await handler(...args);
48
- this.eventEmitter.emit(`${channel}-reply`, result);
61
+ this.eventEmitter.emit(`${channel}-reply-${requestId}`, result);
49
62
  });
63
+ return {
64
+ cancel: () => {
65
+ this.eventEmitter.removeAllListeners(channel);
66
+ }
67
+ };
50
68
  }
51
69
  /**
52
70
  * 发送给渲染进程消息
53
- * @param webContents
54
- * @param channel
55
- * @param args
56
- * @returns
71
+ * 使用唯一的 requestId 确保并发请求不会互相干扰
72
+ *
73
+ * @param webContents 目标渲染进程的 WebContents 对象
74
+ * @param channel 消息通道名称
75
+ * @param args 传递给渲染进程的参数
76
+ * @returns Promise<any> 返回渲染进程的处理结果
77
+ *
78
+ * 修复说明:
79
+ * - 为每个请求生成唯一的 requestId
80
+ * - 监听 `${channel}-reply-${requestId}` 事件,确保只接收对应请求的回复
81
+ * - 发送请求时包含 requestId,让渲染进程知道如何回复
82
+ * - 等待渲染进程加载完成后再发送消息,确保消息能够被正确接收
57
83
  */
58
84
  invokeRenderer(webContents, channel, ...args) {
59
85
  return new Promise(resolve => {
86
+ const requestId = getRandomUUID();
60
87
  const sendMessage = () => {
61
- ipcMain.once(`${channel}-reply`, (_event, result) => {
88
+ ipcMain.once(`${channel}-reply-${requestId}`, (_event, result) => {
62
89
  resolve(result);
63
90
  });
64
- webContents.send(channel, ...args);
91
+ webContents.send(channel, requestId, ...args);
65
92
  };
66
93
  // 等待渲染进程加载完成后再推送,否则会导致渲染进程收不到消息
67
94
  if (webContents.isLoading()) {
@@ -75,19 +102,40 @@ class MainIPC {
75
102
  });
76
103
  }
77
104
  /**
78
- * 发送给所有渲染进程消息
79
- * @param channel
80
- * @param args
81
- * @returns
82
- */
105
+ * 发送给所有渲染进程消息
106
+ * 向所有渲染进程发送消息并收集所有响应
107
+ *
108
+ * @param channel 消息通道名称
109
+ * @param args 传递给所有渲染进程的参数
110
+ * @returns Promise<any[]> 返回所有渲染进程的处理结果数组
111
+ *
112
+ * 修复说明:
113
+ * - 为每个请求生成唯一的 requestId
114
+ * - 收集所有渲染进程的响应,当所有响应都收到时才 resolve
115
+ * - 使用 `${channel}-reply-${requestId}` 确保只接收对应请求的回复
116
+ * - 如果没有渲染进程,直接返回空数组
117
+ * - 等待每个渲染进程加载完成后再发送消息
118
+ */
83
119
  invokeAllRenderer(channel, ...args) {
84
120
  return new Promise(resolve => {
121
+ const requestId = getRandomUUID();
122
+ let responseCount = 0;
123
+ const totalWebContents = webContents.getAllWebContents().length;
124
+ if (totalWebContents === 0) {
125
+ resolve([]);
126
+ return;
127
+ }
128
+ const responses = [];
85
129
  webContents.getAllWebContents().forEach(webContent => {
86
130
  const sendMessage = () => {
87
- ipcMain.once(`${channel}-reply`, (_event, result) => {
88
- resolve(result);
131
+ ipcMain.once(`${channel}-reply-${requestId}`, (_event, result) => {
132
+ responses.push(result);
133
+ responseCount++;
134
+ if (responseCount === totalWebContents) {
135
+ resolve(responses);
136
+ }
89
137
  });
90
- webContent.send(channel, ...args);
138
+ webContent.send(channel, requestId, ...args);
91
139
  };
92
140
  // 等待渲染进程加载完成后再推送,否则会导致渲染进程收不到消息
93
141
  if (webContent.isLoading()) {
@@ -101,21 +149,19 @@ class MainIPC {
101
149
  });
102
150
  });
103
151
  }
104
- /**
105
- * 处理一次性渲染进程发送过来的消息
106
- * @param channel
107
- * @param handler
108
- */
109
- handleRendererOnce(channel, handler) {
110
- ipcMain.once(channel, async (_event, ...args) => {
111
- const result = await handler(...args);
112
- _event.sender.send(`${channel}-reply`, result);
113
- });
114
- }
115
152
  /**
116
153
  * 处理渲染进程发送过来的消息
117
- * @param channel
118
- * @param handler
154
+ * 持续监听指定通道的消息,支持超时处理
155
+ *
156
+ * @param channel 消息通道名称
157
+ * @param handler 处理函数,接收除 requestId 外的所有参数
158
+ *
159
+ * 修复说明:
160
+ * - 接收 requestId 作为第一个参数
161
+ * - 使用 ipcMain.handle 替代 ipcMain.on,提供更好的错误处理
162
+ * - 支持 8 秒超时机制,避免长时间等待
163
+ * - 支持并发请求,每个请求都有独立的处理流程
164
+ * - 提供详细的错误日志记录
119
165
  */
120
166
  handleRenderer(channel, handler) {
121
167
  try {
@@ -155,31 +201,51 @@ class MainIPC {
155
201
  catch (error) {
156
202
  console.error('SDK handleRenderer error: ', error);
157
203
  }
204
+ return {
205
+ cancel: () => {
206
+ ipcMain.removeHandler(channel);
207
+ }
208
+ };
158
209
  }
159
210
  /**
160
- * 初始化
211
+ * 初始化消息中继功能
212
+ * 设置消息转发和回复机制,支持跨渲染进程通信
213
+ *
214
+ * 功能说明:
215
+ * - relay-message: 转发消息到指定的渲染进程或所有渲染进程
216
+ * - relay-reply: 处理回复消息,广播给所有渲染进程
217
+ * - __GetCurrentWebContentId__: 获取当前 WebContent ID
218
+ * - __OpenCurrentWebContentDevTools__: 打开当前 WebContent 的开发者工具
161
219
  */
162
220
  relayMessage() {
163
- ipcMain.on('relay-message', (_event, { targetWebContentId, channel, args }) => {
221
+ // 处理消息转发请求
222
+ ipcMain.on('relay-message', (_event, { targetWebContentId, channel, requestId, args }) => {
223
+ log('log', 'relay-message', { targetWebContentId, channel, requestId, args });
164
224
  if (targetWebContentId) {
225
+ // 转发到指定的渲染进程
165
226
  const targetWebContent = webContents.fromId(targetWebContentId);
166
227
  if (targetWebContent) {
167
- targetWebContent.send(channel, ...args);
228
+ targetWebContent.send(channel, requestId, ...args);
168
229
  }
169
230
  }
170
231
  else {
232
+ // 广播到所有渲染进程
171
233
  webContents.getAllWebContents().forEach(webContent => {
172
- webContent.send(channel, ...args);
234
+ webContent.send(channel, requestId, ...args);
173
235
  });
174
236
  }
175
237
  });
176
- ipcMain.on('relay-reply', (_event, { originalChannel, result }) => {
177
- // 所有渲染进程都会接收 ${originalChannel}-reply 事件,要求仅需要的渲染进程处理该事件的回复。
178
- // 这样可以避免需要指定窗口 ID 回复消息,并确保消息能够正确传递和接收
238
+ // 处理回复消息广播
239
+ ipcMain.on('relay-reply', (_event, { originalChannel, requestId, result }) => {
240
+ log('log', 'relay-reply', { originalChannel, requestId, result });
241
+ // 使用 requestId 确保回复发送给正确的请求
242
+ // 所有渲染进程都会接收 ${originalChannel}-reply-${requestId} 事件
243
+ // 只有对应的请求才会处理该回复,避免数据错乱
179
244
  webContents.getAllWebContents().forEach(webContent => {
180
- webContent.send(`${originalChannel}-reply`, result);
245
+ webContent.send(`${originalChannel}-reply-${requestId}`, result);
181
246
  });
182
247
  });
248
+ // 获取当前 WebContent ID 的通道
183
249
  const getCurrentWebContentIdChannel = '__GetCurrentWebContentId__';
184
250
  ipcMain.on(getCurrentWebContentIdChannel, (_event) => {
185
251
  try {
@@ -191,6 +257,7 @@ class MainIPC {
191
257
  return undefined;
192
258
  }
193
259
  });
260
+ // 打开当前 WebContent 开发者工具的通道
194
261
  const openCurrentWebContentDevToolsChannel = '__OpenCurrentWebContentDevTools__';
195
262
  ipcMain.on(openCurrentWebContentDevToolsChannel, (_event) => {
196
263
  try {
@@ -205,8 +272,23 @@ class MainIPC {
205
272
  });
206
273
  }
207
274
  }
275
+ /**
276
+ * 全局 MainIPC 实例
277
+ * 使用全局变量确保单例模式,避免重复创建实例
278
+ */
208
279
  // @ts-ignore
209
280
  const mainIPC = global['__ELECTRON_IPC__'] ? global['__ELECTRON_IPC__'] : (global['__ELECTRON_IPC__'] = new MainIPC());
281
+ /**
282
+ * 初始化 IPC 通信系统
283
+ * 设置消息中继功能,确保跨进程通信正常工作
284
+ *
285
+ * @returns MainIPC 实例
286
+ *
287
+ * 功能说明:
288
+ * - 检查是否已经初始化,避免重复初始化
289
+ * - 设置消息中继功能,支持跨渲染进程通信
290
+ * - 返回全局 MainIPC 实例
291
+ */
210
292
  const initialize = () => {
211
293
  // @ts-ignore
212
294
  if (isInitialized && global['__ELECTRON_IPC__']) {
@@ -219,6 +301,22 @@ const initialize = () => {
219
301
  // @ts-ignore
220
302
  return global['__ELECTRON_IPC__'];
221
303
  };
304
+ /**
305
+ * 日志记录工具函数
306
+ * 提供统一的日志格式和错误处理
307
+ *
308
+ * @param type 日志类型:'log' 或 'error'
309
+ * @param data 要记录的数据
310
+ */
311
+ const log = (type, ...data) => {
312
+ const key = `[electron-ipc]: `;
313
+ try {
314
+ console[type](key, ...data);
315
+ }
316
+ catch (error) {
317
+ console.error(key, error);
318
+ }
319
+ };
222
320
 
223
321
  export { initialize, isInitialized, mainIPC };
224
322
  //# sourceMappingURL=index.js.map