@lynker-desktop/electron-window-manager 0.0.9-alpha.5 → 0.0.9-alpha.50

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/renderer/index.js CHANGED
@@ -7,28 +7,37 @@ const eIpc = require('@lynker-desktop/electron-ipc/renderer');
7
7
  * @author Lynker Desktop Team
8
8
  * @version 1.0.0
9
9
  */
10
- // ==================== 工具函数 ====================
11
10
  /**
12
- * 获取 IPC 渲染器实例
13
- * 优先从全局变量获取,回退到 require 方式
14
- *
15
- * @returns IpcRenderer 实例或空对象
11
+ * 通用获取函数:从全局变量或 require 获取模块
12
+ * @param globalKey 全局对象中的键名
13
+ * @param requirePath require 路径
14
+ * @param errorMessage 错误提示信息
15
+ * @returns 获取到的模块或空对象
16
16
  */
17
- const getIpc = () => {
17
+ const getModule = (globalKey, requirePath, errorMessage) => {
18
18
  try {
19
19
  // 优先从全局变量获取(预加载脚本注入)
20
- const globalIpc = window?.__ELECTRON_WINDOW_MANAGER__?.ipcRenderer;
21
- if (globalIpc) {
22
- return globalIpc;
20
+ const globalValue = window?.__ELECTRON_WINDOW_MANAGER__?.[globalKey];
21
+ if (globalValue) {
22
+ return globalValue;
23
23
  }
24
24
  // 回退到 require 方式
25
- return window?.require('electron').ipcRenderer;
25
+ return window?.require?.(requirePath);
26
26
  }
27
27
  catch (error) {
28
- console.error('当前非桌面端环境, 请在桌面端中调用');
28
+ console.error(errorMessage, error);
29
29
  return {};
30
30
  }
31
31
  };
32
+ /**
33
+ * 获取 IPC 渲染器实例
34
+ * 优先从全局变量获取,回退到 require 方式
35
+ *
36
+ * @returns IpcRenderer 实例或空对象
37
+ */
38
+ const getIpc = () => {
39
+ return getModule('ipcRenderer', 'electron', '当前非桌面端环境, 请在桌面端中调用');
40
+ };
32
41
  /**
33
42
  * 获取 Electron Remote 模块
34
43
  * 优先从全局变量获取,回退到 require 方式
@@ -36,55 +45,95 @@ const getIpc = () => {
36
45
  * @returns RemoteType 实例或空对象
37
46
  */
38
47
  const getRemote = () => {
39
- try {
40
- // 优先从全局变量获取(预加载脚本注入)
41
- const globalRemote = window?.__ELECTRON_WINDOW_MANAGER__?.remote;
42
- if (globalRemote) {
43
- return globalRemote;
44
- }
45
- // 回退到 require 方式
46
- return window?.require('@electron/remote');
47
- }
48
- catch (error) {
49
- console.error('获取 Remote 模块失败: ', error);
50
- return {};
51
- }
48
+ return getModule('remote', '@electron/remote', '获取 Remote 模块失败');
52
49
  };
53
50
  /**
54
51
  * 获取所有窗口的 BrowserView 列表
55
- * 遍历所有窗口并收集其 BrowserView
52
+ * 遍历所有窗口并收集其 BrowserView(带缓存优化)
56
53
  *
54
+ * @param forceRefresh 是否强制刷新缓存
57
55
  * @returns BrowserView 数组
58
56
  */
59
- const getAllBrowserViews = () => {
60
- const remote = getRemote();
61
- const allWindows = remote.BrowserWindow.getAllWindows();
62
- const allBrowserViews = [];
63
- allWindows.forEach(window => {
64
- const views = window.getBrowserViews();
65
- allBrowserViews.push(...views);
66
- });
67
- return allBrowserViews;
68
- };
57
+ const getAllBrowserViews = (() => {
58
+ let cachedViews = null;
59
+ let cacheTime = 0;
60
+ const CACHE_DURATION = 100; // 缓存 100ms
61
+ return (forceRefresh = false) => {
62
+ const now = Date.now();
63
+ if (!forceRefresh && cachedViews && (now - cacheTime < CACHE_DURATION)) {
64
+ return cachedViews;
65
+ }
66
+ const remote = getRemote();
67
+ try {
68
+ const allWindows = remote.BrowserWindow?.getAllWindows?.() || [];
69
+ const allBrowserViews = [];
70
+ allWindows.forEach(window => {
71
+ try {
72
+ const views = window.getBrowserViews?.() || [];
73
+ allBrowserViews.push(...views);
74
+ }
75
+ catch (error) {
76
+ // 忽略获取 views 失败的情况
77
+ }
78
+ });
79
+ cachedViews = allBrowserViews;
80
+ cacheTime = now;
81
+ return allBrowserViews;
82
+ }
83
+ catch (error) {
84
+ console.error('获取 BrowserView 列表失败:', error);
85
+ return cachedViews || [];
86
+ }
87
+ };
88
+ })();
69
89
  /**
70
90
  * 通过 WebContents 查找对应的 BrowserView
71
91
  * 如果找不到已挂载的 BrowserView,则创建虚拟的 BrowserView 对象
72
92
  *
73
93
  * @param webContent - WebContents 实例
74
- * @returns BVItem 实例
94
+ * @returns BVItem 实例或 null
75
95
  */
76
96
  const getBrowserViewByWebContent = (webContent) => {
77
- const allBrowserViews = getAllBrowserViews();
78
- const existingView = allBrowserViews.find(view => view.webContents === webContent);
79
- // 如果找到已挂载的 BrowserView,直接返回
80
- if (existingView) {
81
- return existingView;
97
+ if (!webContent) {
98
+ return null;
82
99
  }
83
- // 如果 WebContents 存在但未挂载到窗口,创建虚拟 BrowserView
84
- if (webContent && !webContent.isDestroyed?.()) {
100
+ try {
101
+ // 检查 webContents 是否已销毁
102
+ if (webContent.isDestroyed?.()) {
103
+ return null;
104
+ }
105
+ // 查找已挂载的 BrowserView
106
+ const allBrowserViews = getAllBrowserViews();
107
+ const existingView = allBrowserViews.find(view => view.webContents === webContent);
108
+ if (existingView) {
109
+ return existingView;
110
+ }
111
+ // 如果 WebContents 存在但未挂载到窗口,创建虚拟 BrowserView
85
112
  return createVirtualBrowserView(webContent);
86
113
  }
87
- return existingView;
114
+ catch (error) {
115
+ console.error('获取 BrowserView 失败:', error);
116
+ return null;
117
+ }
118
+ };
119
+ /**
120
+ * 统一的 IPC 调用封装
121
+ * @param type IPC 消息类型
122
+ * @param data IPC 消息数据
123
+ * @returns Promise<T> IPC 调用结果
124
+ */
125
+ const invokeIpc = async (type, data) => {
126
+ try {
127
+ const ipc = getIpc();
128
+ if (!ipc || !ipc.invoke) {
129
+ throw new Error('IPC 不可用');
130
+ }
131
+ return await ipc.invoke('__ELECTRON_WINDOW_MANAGER_IPC_CHANNEL__', { type, data });
132
+ }
133
+ catch (error) {
134
+ console.error(`IPC 调用失败 [${type}]:`, error);
135
+ throw error;
136
+ }
88
137
  };
89
138
  /**
90
139
  * 创建虚拟的 BrowserView 对象
@@ -94,37 +143,37 @@ const getBrowserViewByWebContent = (webContent) => {
94
143
  * @returns 虚拟的 BVItem 对象
95
144
  */
96
145
  const createVirtualBrowserView = (webContent) => {
146
+ const webContentId = webContent.id;
97
147
  const virtualView = {
98
- id: webContent.id,
99
- _id: webContent.id,
148
+ id: webContentId,
149
+ _id: webContentId,
100
150
  _type: 'BV',
101
151
  _name: '',
102
152
  _extraData: '',
103
153
  webContents: webContent,
104
154
  // 代理方法,通过 IPC 调用主进程
105
155
  getBounds: async () => {
106
- const result = await getIpc().invoke('__ELECTRON_WINDOW_MANAGER_IPC_CHANNEL__', {
107
- type: 'borrowView_getBounds',
108
- data: { webContentId: webContent.id, options: {} }
156
+ return invokeIpc('borrowView_getBounds', {
157
+ webContentId,
158
+ options: {}
109
159
  });
110
- return result;
111
160
  },
112
161
  setBounds: async (bounds) => {
113
- return await getIpc().invoke('__ELECTRON_WINDOW_MANAGER_IPC_CHANNEL__', {
114
- type: 'borrowView_setBounds',
115
- data: { webContentId: webContent.id, options: bounds }
162
+ return invokeIpc('borrowView_setBounds', {
163
+ webContentId,
164
+ options: bounds
116
165
  });
117
166
  },
118
167
  setAutoResize: async (autoResize) => {
119
- return await getIpc().invoke('__ELECTRON_WINDOW_MANAGER_IPC_CHANNEL__', {
120
- type: 'borrowView_setAutoResize',
121
- data: { webContentId: webContent.id, options: autoResize }
168
+ return invokeIpc('borrowView_setAutoResize', {
169
+ webContentId,
170
+ options: autoResize
122
171
  });
123
172
  },
124
173
  setBackgroundColor: async (color) => {
125
- return await getIpc().invoke('__ELECTRON_WINDOW_MANAGER_IPC_CHANNEL__', {
126
- type: 'borrowView_setBackgroundColor',
127
- data: { webContentId: webContent.id, options: color }
174
+ return invokeIpc('borrowView_setBackgroundColor', {
175
+ webContentId,
176
+ options: color
128
177
  });
129
178
  },
130
179
  };
@@ -137,34 +186,80 @@ const createVirtualBrowserView = (webContent) => {
137
186
  * @param data - 窗口数据
138
187
  */
139
188
  const setWindowProperties = (window, data) => {
140
- if (!window)
189
+ if (!window || !data)
141
190
  return;
142
- window._name = data.winName || '';
143
- window._type = data.winType || '';
144
- window._extraData = data.winExtraData || '';
145
- window._initUrl = data.winInitUrl || '';
191
+ try {
192
+ window._name = data.winName || '';
193
+ window._type = data.winType || '';
194
+ window._extraData = data.winExtraData || '';
195
+ window._initUrl = data.winInitUrl || '';
196
+ window._zIndex = data.winZIndex ?? 0;
197
+ // 尝试设置 ID
198
+ if (data.winId) {
199
+ try {
200
+ window.id = Number(data.winId);
201
+ }
202
+ catch (error) {
203
+ // 忽略设置 ID 失败的情况
204
+ }
205
+ }
206
+ }
207
+ catch (error) {
208
+ console.error('设置窗口属性失败:', error);
209
+ }
146
210
  };
147
- async function create(options) {
211
+ /**
212
+ * 根据窗口 ID 查找窗口实例
213
+ * 优先查找 BrowserWindow,如果找不到则查找 BrowserView
214
+ *
215
+ * @param winId - 窗口 ID
216
+ * @returns 窗口实例或 null
217
+ */
218
+ const findWindowById = (winId) => {
219
+ if (!winId || winId <= 0) {
220
+ return null;
221
+ }
148
222
  const remote = getRemote();
149
- // 通过 IPC 调用主进程创建窗口
150
- const data = await eIpc.RendererIPC.invokeMain('__ELECTRON_WINDOW_MANAGER_IPC_CHANNEL__', {
151
- type: 'create',
152
- data: options
153
- });
154
- // 尝试通过 ID 获取窗口
155
- let window = remote.BrowserWindow.fromId(data.winId);
156
- // 如果不是 BrowserWindow,尝试获取 BrowserView
157
- if (!window) {
158
- const webContent = remote.webContents.fromId(data.winId);
223
+ try {
224
+ // 优先查找 BrowserWindow
225
+ const browserWindow = remote.BrowserWindow?.fromId?.(winId);
226
+ if (browserWindow) {
227
+ return browserWindow;
228
+ }
229
+ // 如果不是 BrowserWindow,尝试查找 BrowserView
230
+ const webContent = remote.webContents?.fromId?.(winId);
159
231
  if (webContent) {
160
- window = getBrowserViewByWebContent(webContent);
232
+ return getBrowserViewByWebContent(webContent);
161
233
  }
162
234
  }
163
- // 设置窗口属性
164
- if (window) {
235
+ catch (error) {
236
+ console.error(`查找窗口失败 [${winId}]:`, error);
237
+ }
238
+ return null;
239
+ };
240
+ async function create(options) {
241
+ try {
242
+ // 通过 IPC 调用主进程创建窗口
243
+ const data = await eIpc.RendererIPC.invokeMain('__ELECTRON_WINDOW_MANAGER_IPC_CHANNEL__', {
244
+ type: 'create',
245
+ data: options
246
+ });
247
+ if (!data?.winId) {
248
+ throw new Error('创建窗口失败: 未返回有效的窗口 ID');
249
+ }
250
+ // 查找窗口实例
251
+ const window = findWindowById(data.winId);
252
+ if (!window) {
253
+ throw new Error(`创建窗口失败: 无法找到窗口实例 [${data.winId}]`);
254
+ }
255
+ // 设置窗口属性
165
256
  setWindowProperties(window, data);
257
+ return window;
258
+ }
259
+ catch (error) {
260
+ console.error('创建窗口失败:', error);
261
+ throw error;
166
262
  }
167
- return window;
168
263
  }
169
264
  /**
170
265
  * 获取当前窗口实例
@@ -192,85 +287,69 @@ const getCurrentWindow = async () => {
192
287
  * ```
193
288
  */
194
289
  const get = async (idOrName) => {
195
- const remote = getRemote();
196
- // 通过 IPC 获取窗口信息
197
- const data = await getIpc().invoke('__ELECTRON_WINDOW_MANAGER_IPC_CHANNEL__', {
198
- type: 'get',
199
- data: idOrName
200
- });
201
- // 尝试通过 ID 获取窗口
202
- let window = remote.BrowserWindow.fromId(data.winId);
203
- // 如果不是 BrowserWindow,尝试获取 BrowserView
204
- if (!window) {
205
- const webContent = remote.webContents.fromId(data.winId);
206
- if (webContent) {
207
- window = getBrowserViewByWebContent(webContent);
290
+ try {
291
+ // 通过 IPC 获取窗口信息
292
+ const data = await invokeIpc('get', idOrName);
293
+ if (!data?.winId) {
294
+ return undefined;
295
+ }
296
+ // 查找窗口实例
297
+ const window = findWindowById(data.winId);
298
+ if (window) {
299
+ setWindowProperties(window, data);
208
300
  }
301
+ return window || undefined;
209
302
  }
210
- // 设置窗口属性
211
- if (window) {
212
- setWindowProperties(window, data);
303
+ catch (error) {
304
+ console.error('获取窗口失败:', error);
305
+ return undefined;
213
306
  }
214
- return window;
215
307
  };
216
308
  async function getAll(type) {
217
- const remote = getRemote();
218
- // 通过 IPC 获取所有窗口信息
219
- const windowData = await getIpc().invoke('__ELECTRON_WINDOW_MANAGER_IPC_CHANNEL__', {
220
- type: 'getAll',
221
- data: undefined
222
- });
223
- const allWindows = new Map();
224
- const browserWindows = new Map();
225
- const browserViews = new Map();
226
- const allBrowserWindows = remote.BrowserWindow.getAllWindows();
227
- // 遍历窗口数据
228
- for (const key in windowData) {
229
- const element = windowData[key];
230
- let window;
231
- // 尝试在 BrowserWindow 中查找
232
- window = allBrowserWindows.find(win => `${win.id}` === `${element?.winId}`);
233
- // 如果不是 BrowserWindow,尝试获取 BrowserView
234
- if (!window) {
235
- const webContent = remote.webContents.fromId(element.winId);
236
- if (webContent) {
237
- window = getBrowserViewByWebContent(webContent);
238
- }
309
+ try {
310
+ // 通过 IPC 获取所有窗口信息
311
+ const windowData = await invokeIpc('getAll', undefined);
312
+ if (!windowData || typeof windowData !== 'object') {
313
+ return new Map();
239
314
  }
240
- if (window) {
241
- // 设置窗口属性
242
- try {
243
- window.id = Number(element?.winId);
244
- }
245
- catch (error) {
246
- // 忽略设置 ID 失败的情况
247
- }
248
- setWindowProperties(window, {
249
- winId: element.winId,
250
- winName: element.winName,
251
- winType: element.winType,
252
- winExtraData: element.winExtraData,
253
- winInitUrl: element.winInitUrl
254
- });
255
- const windowId = window.id || window._id;
256
- allWindows.set(windowId, window);
257
- // 按类型分类
258
- if (window._type === 'BW') {
259
- browserWindows.set(windowId, window);
315
+ const allWindows = new Map();
316
+ const browserWindows = new Map();
317
+ const browserViews = new Map();
318
+ // 遍历窗口数据
319
+ for (const key in windowData) {
320
+ const element = windowData[key];
321
+ if (!element?.winId) {
322
+ continue;
260
323
  }
261
- else if (window._type === 'BV') {
262
- browserViews.set(windowId, window);
324
+ // 查找窗口实例
325
+ const window = findWindowById(element.winId);
326
+ if (window) {
327
+ // 设置窗口属性
328
+ setWindowProperties(window, element);
329
+ const windowId = window.id || window._id;
330
+ allWindows.set(windowId, window);
331
+ // 按类型分类
332
+ if (window._type === 'BW') {
333
+ browserWindows.set(windowId, window);
334
+ }
335
+ else if (window._type === 'BV') {
336
+ browserViews.set(windowId, window);
337
+ }
263
338
  }
264
339
  }
340
+ // 根据类型返回对应的映射表
341
+ if (type === 'BW') {
342
+ return browserWindows;
343
+ }
344
+ if (type === 'BV') {
345
+ return browserViews;
346
+ }
347
+ return allWindows;
265
348
  }
266
- // 根据类型返回对应的映射表
267
- if (type === 'BW') {
268
- return browserWindows;
269
- }
270
- if (type === 'BV') {
271
- return browserViews;
349
+ catch (error) {
350
+ console.error('获取所有窗口失败:', error);
351
+ return new Map();
272
352
  }
273
- return allWindows;
274
353
  }
275
354
  /**
276
355
  * 关闭指定窗口
@@ -279,11 +358,14 @@ async function getAll(type) {
279
358
  * @returns Promise<boolean> 操作是否成功
280
359
  */
281
360
  const close = async (idOrName) => {
282
- await getIpc().invoke('__ELECTRON_WINDOW_MANAGER_IPC_CHANNEL__', {
283
- type: 'close',
284
- data: idOrName
285
- });
286
- return true;
361
+ try {
362
+ await invokeIpc('close', idOrName);
363
+ return true;
364
+ }
365
+ catch (error) {
366
+ console.error('关闭窗口失败:', error);
367
+ return false;
368
+ }
287
369
  };
288
370
  /**
289
371
  * 关闭所有窗口
@@ -291,11 +373,14 @@ const close = async (idOrName) => {
291
373
  * @returns Promise<boolean> 操作是否成功
292
374
  */
293
375
  const closeAll = async () => {
294
- await getIpc().invoke('__ELECTRON_WINDOW_MANAGER_IPC_CHANNEL__', {
295
- type: 'closeAll',
296
- data: undefined
297
- });
298
- return true;
376
+ try {
377
+ await invokeIpc('closeAll', undefined);
378
+ return true;
379
+ }
380
+ catch (error) {
381
+ console.error('关闭所有窗口失败:', error);
382
+ return false;
383
+ }
299
384
  };
300
385
  /**
301
386
  * 根据 WebContents ID 查找对应的窗口
@@ -303,12 +388,18 @@ const closeAll = async () => {
303
388
  * @param webContentId - WebContents ID
304
389
  * @returns Promise<BWItem | BVItem | undefined> 窗口实例
305
390
  */
306
- const getWindowForWebContentId = async (webContentId) => {
307
- const winId = await getIpc().invoke('__ELECTRON_WINDOW_MANAGER_IPC_CHANNEL__', {
308
- type: 'getWindowForWebContentId',
309
- data: webContentId
310
- });
311
- return get(winId);
391
+ const getWindowForWebContentsId = async (webContentId) => {
392
+ try {
393
+ const winId = await invokeIpc('getWindowForWebContentsId', webContentId);
394
+ if (!winId) {
395
+ return undefined;
396
+ }
397
+ return get(winId);
398
+ }
399
+ catch (error) {
400
+ console.error('根据 WebContents ID 查找窗口失败:', error);
401
+ return undefined;
402
+ }
312
403
  };
313
404
  /**
314
405
  * 重命名窗口
@@ -318,11 +409,17 @@ const getWindowForWebContentId = async (webContentId) => {
318
409
  * @returns Promise<BWItem | BVItem | undefined> 重命名后的窗口实例
319
410
  */
320
411
  const rename = async (idOrName, newName) => {
321
- const data = await getIpc().invoke('__ELECTRON_WINDOW_MANAGER_IPC_CHANNEL__', {
322
- type: 'rename',
323
- data: { idOrName, newName }
324
- });
325
- return get(data.winId);
412
+ try {
413
+ const data = await invokeIpc('rename', { idOrName, newName });
414
+ if (!data?.winId) {
415
+ return undefined;
416
+ }
417
+ return get(data.winId);
418
+ }
419
+ catch (error) {
420
+ console.error('重命名窗口失败:', error);
421
+ return undefined;
422
+ }
326
423
  };
327
424
  /**
328
425
  * 重置窗口初始化URL
@@ -332,22 +429,31 @@ const rename = async (idOrName, newName) => {
332
429
  * @returns Promise<BWItem | BVItem | undefined> 重置后的窗口实例
333
430
  */
334
431
  const reInitUrl = async (idOrName, url) => {
335
- const data = await getIpc().invoke('__ELECTRON_WINDOW_MANAGER_IPC_CHANNEL__', {
336
- type: 'reInitUrl',
337
- data: { idOrName, url }
338
- });
339
- return get(data.winId);
432
+ try {
433
+ const data = await invokeIpc('reInitUrl', { idOrName, url });
434
+ if (!data?.winId) {
435
+ return undefined;
436
+ }
437
+ return get(data.winId);
438
+ }
439
+ catch (error) {
440
+ console.error('重置窗口 URL 失败:', error);
441
+ return undefined;
442
+ }
340
443
  };
341
444
  /**
342
- * 设置预加载 WebContents URL
445
+ * 设置预加载 WebContents 配置
343
446
  *
344
- * @param preloadWebContentsUrl - 预加载 URL
447
+ * @param preloadWebContentsConfig - 预加载配置
345
448
  */
346
- const setPreloadWebContentsUrl = async (preloadWebContentsUrl) => {
347
- await getIpc().invoke('__ELECTRON_WINDOW_MANAGER_IPC_CHANNEL__', {
348
- type: 'setPreloadWebContentsUrl',
349
- data: preloadWebContentsUrl
350
- });
449
+ const setPreloadWebContentsConfig = async (preloadWebContentsConfig) => {
450
+ try {
451
+ await invokeIpc('setPreloadWebContentsConfig', preloadWebContentsConfig);
452
+ }
453
+ catch (error) {
454
+ console.error('设置预加载配置失败:', error);
455
+ throw error;
456
+ }
351
457
  };
352
458
  /**
353
459
  * 获取预加载脚本路径
@@ -356,24 +462,46 @@ const setPreloadWebContentsUrl = async (preloadWebContentsUrl) => {
356
462
  * @returns Promise<string | undefined> 预加载脚本路径
357
463
  */
358
464
  const getPreload = (() => {
359
- let cachedPreload = undefined;
465
+ let cachedPreload = null;
466
+ let isLoading = false;
467
+ let loadPromise = null;
360
468
  return async () => {
361
469
  // 如果已有缓存,直接返回
362
- if (cachedPreload !== undefined) {
470
+ if (cachedPreload !== null) {
363
471
  return cachedPreload;
364
472
  }
365
- // 通过 IPC 获取预加载脚本路径
366
- const data = await getIpc().invoke('__ELECTRON_WINDOW_MANAGER_IPC_CHANNEL__', {
367
- type: 'getPreload',
368
- data: undefined,
369
- });
370
- // 缓存结果
371
- cachedPreload = data;
372
- return data;
473
+ // 如果正在加载,返回同一个 Promise
474
+ if (isLoading && loadPromise) {
475
+ return loadPromise;
476
+ }
477
+ // 开始加载
478
+ isLoading = true;
479
+ loadPromise = (async () => {
480
+ try {
481
+ // 通过 IPC 获取预加载脚本路径
482
+ const data = await invokeIpc('getPreload', undefined);
483
+ // 缓存结果(即使是 undefined 也缓存,避免重复请求)
484
+ cachedPreload = data;
485
+ return data;
486
+ }
487
+ catch (error) {
488
+ console.error('获取预加载脚本路径失败:', error);
489
+ // 失败时也缓存 null,避免重复请求
490
+ cachedPreload = undefined;
491
+ return undefined;
492
+ }
493
+ finally {
494
+ isLoading = false;
495
+ loadPromise = null;
496
+ }
497
+ })();
498
+ return loadPromise;
373
499
  };
374
500
  })();
375
- // 初始化时获取预加载脚本
376
- getPreload();
501
+ // 初始化时异步获取预加载脚本(不阻塞)
502
+ getPreload().catch(() => {
503
+ // 静默处理初始化失败
504
+ });
377
505
  // ==================== 开发工具相关(已注释) ====================
378
506
  /*
379
507
  * 开发工具相关功能(已注释,可根据需要启用)
@@ -400,8 +528,8 @@ exports.get = get;
400
528
  exports.getAll = getAll;
401
529
  exports.getCurrentWindow = getCurrentWindow;
402
530
  exports.getPreload = getPreload;
403
- exports.getWindowForWebContentId = getWindowForWebContentId;
531
+ exports.getWindowForWebContentsId = getWindowForWebContentsId;
404
532
  exports.reInitUrl = reInitUrl;
405
533
  exports.rename = rename;
406
- exports.setPreloadWebContentsUrl = setPreloadWebContentsUrl;
534
+ exports.setPreloadWebContentsConfig = setPreloadWebContentsConfig;
407
535
  //# sourceMappingURL=index.js.map