nexfep 0.6.0 → 0.6.1

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/README-CN.md CHANGED
@@ -148,15 +148,22 @@ const locker = app.createLocker("my-app");
148
148
  try {
149
149
  // 尝试获取应用实例锁
150
150
  await locker.lock();
151
+ // 也可以带参数获取锁,例如:
152
+ // await locker.lock(process.argv[2]);
151
153
  } catch {
152
154
  // 应用实例已存在,退出应用
153
155
  app.exit();
154
156
  }
155
- // 在其它实例抢锁时聚焦当前实例
156
- locker.whenLost(() => {
157
+ // 你可以在其它实例抢锁时聚焦当前实例
158
+ locker.whenLost((data) => {
157
159
  if (!win.isFocused()) {
158
160
  win.focus();
159
161
  }
162
+ // 如果对方实例在获取锁时传递了参数,你可以使用它来执行特定操作
163
+ // 若没有传递,data 字段将会是 null
164
+ if (data) {
165
+ console.log("传递了参数:", data);
166
+ }
160
167
  });
161
168
  // 释放锁
162
169
  locker.unlock();
@@ -166,7 +173,7 @@ locker.unlock();
166
173
 
167
174
  | 方法 | 描述 |
168
175
  | -------------------- | ------------------------ |
169
- | `lock()` | 尝试获取应用实例锁 |
176
+ | `lock(data?)` | 尝试获取应用实例锁 |
170
177
  | `whenLost(callback)` | 当其它实例抢锁时执行回调 |
171
178
  | `unlock()` | 释放锁 |
172
179
 
@@ -404,6 +411,12 @@ window.addEventListener("user-login", (event) => {
404
411
  });
405
412
  ```
406
413
 
414
+ 特别地,主进程可以通过 `pool.broadcast` 向所有打开的窗口发送事件,参数与页面中的 `window.broadcast` 相同:
415
+
416
+ ```typescript
417
+ pool.broadcast("user-login", { userId: 123 });
418
+ ```
419
+
407
420
  #### 定向发送
408
421
 
409
422
  通过 `window.tell` 向指定 ID 的窗口发送消息:
@@ -432,6 +445,12 @@ window.addEventListener("custom-message", (event) => {
432
445
  console.log("当前窗口 ID:", window.id);
433
446
  ```
434
447
 
448
+ 主进程也可通过 `win.tell` 向该窗口发送消息:
449
+
450
+ ```typescript
451
+ win.tell("custom-message", { text: `你好,窗口 ${win.id}` });
452
+ ```
453
+
435
454
  ### 自定义消息
436
455
 
437
456
  #### 发送消息
package/README.md CHANGED
@@ -148,15 +148,22 @@ const locker = app.createLocker("my-app");
148
148
  try {
149
149
  // Try to acquire the lock
150
150
  await locker.lock();
151
+ // You can also pass data to the other instance when acquiring the lock
152
+ // await locker.lock(process.argv[2]);
151
153
  } catch {
152
154
  // Instance already exists, exit the application
153
155
  app.exit();
154
156
  }
155
157
  // Focus the current instance when other instances acquire the lock
156
- locker.whenLost(() => {
158
+ locker.whenLost((data) => {
157
159
  if (!win.isFocused()) {
158
160
  win.focus();
159
161
  }
162
+ // If the other instance passed data, you can use it to perform specific actions
163
+ // If no data was passed, data will be null
164
+ if (data) {
165
+ console.log("Other instance passed data:", data);
166
+ }
160
167
  });
161
168
  // Release the lock
162
169
  locker.unlock();
@@ -164,7 +171,7 @@ locker.unlock();
164
171
 
165
172
  **Methods**
166
173
 
167
- - `lock()` — Try to acquire the lock
174
+ - `lock(data?)` — Try to acquire the lock
168
175
  - `whenLost(callback)` — Register a callback to be called when other instances acquire the lock
169
176
  - `unlock()` — Release the lock
170
177
 
@@ -402,6 +409,12 @@ window.addEventListener("user-login", (event) => {
402
409
  });
403
410
  ```
404
411
 
412
+ The main process can send events to all open windows via `pool.broadcast`, with parameters identical to those of `window.broadcast` in the page:
413
+
414
+ ```typescript
415
+ pool.broadcast("user-login", { userId: 123 });
416
+ ```
417
+
405
418
  #### Tell
406
419
 
407
420
  Send a message to a specific window by its ID via `window.tell`:
@@ -430,6 +443,12 @@ Each window's ID can be accessed via `window.id`:
430
443
  console.log("This window ID:", window.id);
431
444
  ```
432
445
 
446
+ The main process can also send messages to this window through `win.tell`:
447
+
448
+ ```typescript
449
+ win.tell("custom-message", { text: `Hello Window ${win.id}` });
450
+ ```
451
+
433
452
  ### Custom Messages
434
453
 
435
454
  #### Send Messages
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nexfep",
3
- "version": "0.6.0",
3
+ "version": "0.6.1",
4
4
  "description": "A desktop application framework based on @webviewjs/webview",
5
5
  "keywords": [
6
6
  "@webviewjs/webview",
@@ -65,7 +65,7 @@
65
65
  "lint:fix": "oxlint --fix"
66
66
  },
67
67
  "dependencies": {
68
- "@nexfteam/single-instance": "^0.0.7",
68
+ "@nexfteam/single-instance": "0.0.8",
69
69
  "@webviewjs/webview": "0.4.1"
70
70
  },
71
71
  "devDependencies": {
@@ -2,8 +2,8 @@ import { SingleInstance } from "@nexfteam/single-instance";
2
2
  declare class Locker {
3
3
  locker: SingleInstance;
4
4
  constructor(appName: string);
5
- lock(): Promise<void>;
5
+ lock(data?: string): Promise<void>;
6
6
  unlock(): Promise<void>;
7
- whenLost(callback: () => void): void;
7
+ whenLost(callback: (data?: string) => void): void;
8
8
  }
9
9
  export { Locker };
@@ -4,8 +4,8 @@ class Locker {
4
4
  constructor(appName) {
5
5
  this.locker = new SingleInstance(appName);
6
6
  }
7
- lock() {
8
- return this.locker.lock();
7
+ lock(data) {
8
+ return this.locker.lock(data);
9
9
  }
10
10
  unlock() {
11
11
  return this.locker.unlock();
@@ -34,6 +34,7 @@ declare class Window {
34
34
  getPosition(): import("@webviewjs/webview").Position;
35
35
  isFocused(): boolean;
36
36
  focus(): void;
37
+ tell(message: string, data: any): void;
37
38
  hide(): void;
38
39
  show(): void;
39
40
  close(): void;
@@ -69,5 +70,6 @@ declare class WindowPool {
69
70
  closeWindow(window: Window): Promise<void>;
70
71
  handle(event: string, callback: (data: any) => any): Promise<void>;
71
72
  unhandle(event: string, callback: (data: any) => any): Promise<void>;
73
+ broadcast(event: string, data: any): Promise<void>;
72
74
  }
73
75
  export { WindowPool, Window };
@@ -121,6 +121,9 @@ class Window {
121
121
  this.unMinimize();
122
122
  this.window.focus();
123
123
  }
124
+ tell(message, data) {
125
+ this.webview.evaluateScript(`window.dispatchEvent(new CustomEvent('${message}', { detail: ${JSON.stringify(data)} }));`);
126
+ }
124
127
  hide() {
125
128
  this.window.hide();
126
129
  this.isShow = false;
@@ -370,13 +373,14 @@ class WindowPool {
370
373
  const dataText = data.body.toString();
371
374
  const dataObj = JSON.parse(dataText);
372
375
  if (dataObj.type == "NexfepBeforeUnload") {
373
- webview.evaluateScript(`if(window?.isNexfepLoadDone){
374
- const MessageBody = { type: 'NexfepBeforeUnload' }
375
- window.ipc.postMessage(JSON.stringify(MessageBody));
376
- }else{
377
- const MessageBody = { type: 'NexfepLoadFalse' }
378
- window.ipc.postMessage(JSON.stringify(MessageBody));
379
- }`);
376
+ webview.evaluateScript(`
377
+ if(window?.isNexfepLoadDone){
378
+ const MessageBody = { type: 'NexfepBeforeUnload' }
379
+ window.ipc.postMessage(JSON.stringify(MessageBody));
380
+ }else{
381
+ const MessageBody = { type: 'NexfepLoadFalse' }
382
+ window.ipc.postMessage(JSON.stringify(MessageBody));
383
+ }`);
380
384
  }
381
385
  else if (dataObj.type == "NexfepLoadFalse") {
382
386
  this.__injectControlFunctions(windowObj);
@@ -416,14 +420,10 @@ class WindowPool {
416
420
  handlers.forEach(async (handler) => {
417
421
  const result = await handler(dataObj.data);
418
422
  if (result) {
419
- webview.evaluateScript(`
420
- window.dispatchEvent(new CustomEvent('nexfep-invoke-result-${dataObj.eventId[0]}-${dataObj.eventId[1]}', { detail: ${JSON.stringify(result)} }));
421
- `);
423
+ webview.evaluateScript(`window.dispatchEvent(new CustomEvent('nexfep-invoke-result-${dataObj.eventId[0]}-${dataObj.eventId[1]}', { detail: ${JSON.stringify(result)} }));`);
422
424
  }
423
425
  else {
424
- webview.evaluateScript(`
425
- window.dispatchEvent(new CustomEvent('nexfep-invoke-result-${dataObj.eventId[0]}-${dataObj.eventId[1]}', { detail: undefined }));
426
- `);
426
+ webview.evaluateScript(`window.dispatchEvent(new CustomEvent('nexfep-invoke-result-${dataObj.eventId[0]}-${dataObj.eventId[1]}', { detail: undefined }));`);
427
427
  }
428
428
  });
429
429
  }
@@ -432,16 +432,12 @@ class WindowPool {
432
432
  }
433
433
  else if (dataObj.type == "NexfepGetGlobal") {
434
434
  const value = this.global.get(dataObj.name);
435
- webview.evaluateScript(`
436
- window.dispatchEvent(new CustomEvent('nexfep-get-global-result-${dataObj.eventId[0]}-${dataObj.eventId[1]}', { detail: ${JSON.stringify(value)} }));
437
- `);
435
+ webview.evaluateScript(`window.dispatchEvent(new CustomEvent('nexfep-get-global-result-${dataObj.eventId[0]}-${dataObj.eventId[1]}', { detail: ${JSON.stringify(value)} }));`);
438
436
  }
439
437
  else if (dataObj.type == "NexfepBroadcast") {
440
438
  this.windows.forEach(async (w) => {
441
439
  if (w != windowObj && w.isOpen) {
442
- w.webview.evaluateScript(`
443
- window.dispatchEvent(new CustomEvent('${dataObj.name}', { detail: ${JSON.stringify(dataObj.data)} }));
444
- `);
440
+ w.webview.evaluateScript(`window.dispatchEvent(new CustomEvent('${dataObj.name}', { detail: ${JSON.stringify(dataObj.data)} }));`);
445
441
  }
446
442
  });
447
443
  }
@@ -451,9 +447,7 @@ class WindowPool {
451
447
  }
452
448
  this.windows.forEach(async (w) => {
453
449
  if (w.id == dataObj.to) {
454
- w.webview.evaluateScript(`
455
- window.dispatchEvent(new CustomEvent('${dataObj.message}', { detail: ${JSON.stringify(dataObj.data)} }));
456
- `);
450
+ w.webview.evaluateScript(`window.dispatchEvent(new CustomEvent('${dataObj.message}', { detail: ${JSON.stringify(dataObj.data)} }));`);
457
451
  }
458
452
  });
459
453
  }
@@ -518,5 +512,12 @@ class WindowPool {
518
512
  async unhandle(event, callback) {
519
513
  this.handlers.set(event, (this.handlers.get(event) || []).filter((c) => c !== callback));
520
514
  }
515
+ async broadcast(event, data) {
516
+ this.windows.forEach(async (w) => {
517
+ if (w.isOpen) {
518
+ w.webview.evaluateScript(`window.dispatchEvent(new CustomEvent('${event}', { detail: ${JSON.stringify(data)} }));`);
519
+ }
520
+ });
521
+ }
521
522
  }
522
523
  export { WindowPool, Window };