nexfep 0.5.5 → 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
@@ -41,7 +41,10 @@ import { Application } from "nexfep";
41
41
 
42
42
  const app = new Application();
43
43
 
44
- const window = await app.windows.createWindow(true, false);
44
+ const window = await app.windows.createWindow({
45
+ visible: true,
46
+ decoration: false,
47
+ });
45
48
 
46
49
  await window.loadHTML("<h1 nexfep-area-drag>Hello Nexfep!</h1>");
47
50
  ```
@@ -81,11 +84,37 @@ const app = new Application({ LogFilePath: "./app.log" });
81
84
  - `createLocker(appName)` — 创建应用实例锁,防止多个实例运行
82
85
  - `exit()` — 退出应用
83
86
 
87
+ ### Icon
88
+
89
+ `Icon` 用于表示图片资源,可被用作窗口图标、托盘图标等。
90
+
91
+ ```typescript
92
+ import { Icon } from "nexfep";
93
+
94
+ // 从文件路径创建
95
+ const icon = Icon.from("./icon.png");
96
+
97
+ // 从 Buffer 或 Uint8Array 创建
98
+ const icon = Icon.from(buffer);
99
+ const icon = Icon.from(uint8Array);
100
+
101
+ // 从包含 data/width/height 的对象创建
102
+ const icon = Icon.from({ data: buffer, width: 64, height: 64 });
103
+ const icon = Icon.from({ data: uint8Array, width: 64, height: 64 });
104
+ ```
105
+
106
+ **静态方法**
107
+
108
+ | 方法 | 参数 | 返回值 | 说明 |
109
+ | ------------------ | ----------------------------------------------------------------------------------------- | ------ | ---------------- |
110
+ | `Icon.from(input)` | `string` \| `Buffer` \| `Uint8Array` \| `{ data: Uint8Array \| Buffer, width?, height? }` | `Icon` | 创建一个图标实例 |
111
+
84
112
  ### Logger
85
113
 
86
114
  Logger 支持文件输出和彩色控制台输出,可通过 `app.logger` 访问。
87
115
 
88
116
  ```typescript
117
+ app.logger.clear();
89
118
  app.logger.log("Hello World");
90
119
  app.logger.error("发生错误");
91
120
  app.logger.warn("警告信息");
@@ -95,13 +124,14 @@ app.logger.debug("调试信息");
95
124
 
96
125
  **方法**
97
126
 
98
- | 方法 | 说明 |
99
- | ---------------- | -------------------- |
100
- | `log(message)` | 记录日志 |
101
- | `error(message)` | 记录错误日志(红色) |
102
- | `warn(message)` | 记录警告日志(黄色) |
103
- | `info(message)` | 记录提示日志(蓝色) |
104
- | `debug(message)` | 记录调试日志(灰色) |
127
+ | 方法 | 说明 |
128
+ | ---------------- | ------------------------------------------------- |
129
+ | `clear()` | 清空日志文件(仅在设置了`LogFilePath`参数时生效) |
130
+ | `log(message)` | 记录日志 |
131
+ | `error(message)` | 记录错误日志(红色) |
132
+ | `warn(message)` | 记录警告日志(黄色) |
133
+ | `info(message)` | 记录提示日志(蓝色) |
134
+ | `debug(message)` | 记录调试日志(灰色) |
105
135
 
106
136
  每个方法接受字符串或字符串数组作为参数。
107
137
 
@@ -118,15 +148,22 @@ const locker = app.createLocker("my-app");
118
148
  try {
119
149
  // 尝试获取应用实例锁
120
150
  await locker.lock();
151
+ // 也可以带参数获取锁,例如:
152
+ // await locker.lock(process.argv[2]);
121
153
  } catch {
122
154
  // 应用实例已存在,退出应用
123
155
  app.exit();
124
156
  }
125
- // 在其它实例抢锁时聚焦当前实例
126
- locker.whenLost(() => {
157
+ // 你可以在其它实例抢锁时聚焦当前实例
158
+ locker.whenLost((data) => {
127
159
  if (!win.isFocused()) {
128
160
  win.focus();
129
161
  }
162
+ // 如果对方实例在获取锁时传递了参数,你可以使用它来执行特定操作
163
+ // 若没有传递,data 字段将会是 null
164
+ if (data) {
165
+ console.log("传递了参数:", data);
166
+ }
130
167
  });
131
168
  // 释放锁
132
169
  locker.unlock();
@@ -136,7 +173,7 @@ locker.unlock();
136
173
 
137
174
  | 方法 | 描述 |
138
175
  | -------------------- | ------------------------ |
139
- | `lock()` | 尝试获取应用实例锁 |
176
+ | `lock(data?)` | 尝试获取应用实例锁 |
140
177
  | `whenLost(callback)` | 当其它实例抢锁时执行回调 |
141
178
  | `unlock()` | 释放锁 |
142
179
 
@@ -145,16 +182,14 @@ locker.unlock();
145
182
  通过 `app.createTray()` 创建和管理系统托盘图标及右键菜单。
146
183
 
147
184
  ```typescript
148
- import { readFileSync } from "fs";
185
+ import { Icon } from "nexfep";
186
+
187
+ const icon = Icon.from("./icon.png");
149
188
 
150
189
  const tray = app.createTray({
151
190
  id: "my-tray",
152
191
  tooltip: "我的应用",
153
- icon: {
154
- data: readFileSync("./icon.png"),
155
- width: 32,
156
- height: 32,
157
- },
192
+ icon: icon, // Icon 实例
158
193
  menuItems: [
159
194
  { id: "show", label: "显示窗口" },
160
195
  { id: "quit", label: "退出" },
@@ -162,29 +197,19 @@ const tray = app.createTray({
162
197
  });
163
198
  ```
164
199
 
165
- `icon` 字段接受 `TrayIconImage` 对象:
166
-
167
- ```typescript
168
- interface TrayIconImage {
169
- data: Buffer; // 图片二进制数据
170
- width?: number; // 可选宽度
171
- height?: number; // 可选高度
172
- }
173
- ```
174
-
175
200
  **方法**
176
201
 
177
- | 方法 | 描述 |
178
- | -------------------------------- | ------------------------------------------------------ |
179
- | `addMenuItem(item)` | 添加菜单项 |
180
- | `removeMenuItem(id)` | 按 ID 删除菜单项 |
181
- | `setMenuItems(items)` | 替换所有菜单项 |
182
- | `setIcon(icon, width?, height?)` | 更改托盘图标(原始像素数据 `Uint8Array` / `number[]`) |
183
- | `setTooltip(tooltip)` | 更改悬停提示文本 |
184
- | `on(event, callback)` | 监听托盘事件(如 `'click'`) |
185
- | `show()` | 显示托盘图标 |
186
- | `hide()` | 隐藏托盘图标 |
187
- | `destroy()` | 销毁托盘图标 |
202
+ | 方法 | 描述 |
203
+ | --------------------- | ------------------------------ |
204
+ | `addMenuItem(item)` | 添加菜单项 |
205
+ | `removeMenuItem(id)` | 按 ID 删除菜单项 |
206
+ | `setMenuItems(items)` | 替换所有菜单项 |
207
+ | `setIcon(icon)` | 更改托盘图标,接受 `Icon` 实例 |
208
+ | `setTooltip(tooltip)` | 更改悬停提示文本 |
209
+ | `on(event, callback)` | 监听托盘事件(如 `'click'`) |
210
+ | `show()` | 显示托盘图标 |
211
+ | `hide()` | 隐藏托盘图标 |
212
+ | `destroy()` | 销毁托盘图标 |
188
213
 
189
214
  ```typescript
190
215
  tray.on("click", () => {
@@ -199,13 +224,14 @@ tray.setTooltip("Nexfep 应用");
199
224
  通过 `app.utils.notify()` 发送桌面通知。
200
225
 
201
226
  ```typescript
202
- const notification = app.utils.notify("标题", "通知内容");
227
+ const notification = app.utils.notify("标题", { body: "通知内容" });
203
228
  ```
204
229
 
205
230
  **参数**
206
231
 
207
232
  - `title` — 通知标题
208
- - `body`(可选)— 通知正文
233
+ - `options`(可选)— 配置对象
234
+ - `body` — 通知正文
209
235
 
210
236
  ### 窗口池
211
237
 
@@ -218,13 +244,38 @@ const pool = app.windows;
218
244
  ### 窗口创建
219
245
 
220
246
  ```typescript
221
- const win = await pool.createWindow(true, false);
247
+ // 不传参数使用全部默认值
248
+ const win = await pool.createWindow();
249
+
250
+ // 传入部分参数
251
+ const win = await pool.createWindow({
252
+ visible: true,
253
+ title: "我的应用",
254
+ });
255
+
256
+ // 全部参数
257
+ const win = await pool.createWindow({
258
+ visible: true, // 是否立即显示,默认 true
259
+ decoration: true, // 是否使用系统装饰,默认 true
260
+ title: "我的应用", // 窗口标题,默认 "Nexfep Window"
261
+ icon: iconInstance, // 窗口图标,Icon 实例,可选
262
+ resizable: true, // 是否可调整大小,默认 true
263
+ width: 800, // 窗口宽度,默认 800
264
+ height: 600, // 窗口高度,默认 600
265
+ });
222
266
  ```
223
267
 
224
268
  **参数说明**
225
269
 
226
- - `isShow`(布尔值,默认 `true`)— 是否立即显示窗口
227
- - `isDecorated`(布尔值,默认 `true`)— 是否使用系统窗口装饰。设为 `false` 时,窗口无边框,需要自定义标题栏
270
+ | 选项 | 类型 | 默认值 | 说明 |
271
+ | ------------ | --------- | ----------------- | ------------------------------------------------------------------- |
272
+ | `visible` | `boolean` | `true` | 是否立即显示窗口 |
273
+ | `decoration` | `boolean` | `true` | 是否使用系统窗口装饰。设为 `false` 时,窗口无边框,需要自定义标题栏 |
274
+ | `title` | `string` | `"Nexfep Window"` | 窗口标题 |
275
+ | `icon` | `Icon` | 无 | 窗口图标 |
276
+ | `resizable` | `boolean` | `true` | 窗口是否可调整大小 |
277
+ | `width` | `number` | `800` | 窗口宽度(像素) |
278
+ | `height` | `number` | `600` | 窗口高度(像素) |
228
279
 
229
280
  ### 窗口操作
230
281
 
@@ -360,6 +411,12 @@ window.addEventListener("user-login", (event) => {
360
411
  });
361
412
  ```
362
413
 
414
+ 特别地,主进程可以通过 `pool.broadcast` 向所有打开的窗口发送事件,参数与页面中的 `window.broadcast` 相同:
415
+
416
+ ```typescript
417
+ pool.broadcast("user-login", { userId: 123 });
418
+ ```
419
+
363
420
  #### 定向发送
364
421
 
365
422
  通过 `window.tell` 向指定 ID 的窗口发送消息:
@@ -388,6 +445,12 @@ window.addEventListener("custom-message", (event) => {
388
445
  console.log("当前窗口 ID:", window.id);
389
446
  ```
390
447
 
448
+ 主进程也可通过 `win.tell` 向该窗口发送消息:
449
+
450
+ ```typescript
451
+ win.tell("custom-message", { text: `你好,窗口 ${win.id}` });
452
+ ```
453
+
391
454
  ### 自定义消息
392
455
 
393
456
  #### 发送消息
@@ -586,44 +649,47 @@ nexfep build -u 7
586
649
 
587
650
  ### WindowPool
588
651
 
589
- | 方法/属性 | 参数 | 返回值 | 说明 |
590
- | ------------------------------------- | ------------------------------------------------------------------- | ----------------- | ------------------------ |
591
- | `createWindow(isShow?, isDecorated?)` | `isShow`: boolean(默认 true), `isDecorated`: boolean(默认 true) | Promise\<Window> | 创建并获取一个窗口 |
592
- | `handle(event, callback)` | `event`: string, `callback`: (data: any) => any | 无 | 监听指定事件 |
593
- | `unhandle(event, callback)` | `event`: string, `callback`: (data: any) => any | 无 | 取消监听指定事件 |
594
- | `global` | / | Map\<string, any> | 全局变量 Map |
595
- | `closeWindow(window)` | `window`: Window | Promise\<void> | 关闭指定窗口并回收至池中 |
596
- | `onCustomMessage` | `(window: Window, data: string) => void` | 无 | 自定义消息回调函数 |
652
+ | 方法/属性 | 参数 | 返回值 | 说明 |
653
+ | --------------------------- | ----------------------------------------------- | ----------------- | ------------------------ |
654
+ | `createWindow(options?)` | 可选参数,见上文窗口创建参数说明 | Promise\<Window> | 创建并获取一个窗口 |
655
+ | `handle(event, callback)` | `event`: string, `callback`: (data: any) => any | 无 | 监听指定事件 |
656
+ | `unhandle(event, callback)` | `event`: string, `callback`: (data: any) => any | 无 | 取消监听指定事件 |
657
+ | `global` | / | Map\<string, any> | 全局变量 Map |
658
+ | `closeWindow(window)` | `window`: Window | Promise\<void> | 关闭指定窗口并回收至池中 |
659
+ | `onCustomMessage` | `(window: Window, data: string) => void` | 无 | 自定义消息回调函数 |
597
660
 
598
661
  ### Window
599
662
 
600
- | 方法/属性 | 参数 | 返回值 | 说明 |
601
- | --------------------------- | --------------------------------- | --------------------------------- | -------------------------- |
602
- | `loadURL(url)` | `url`: string — 要加载的网页地址 | Promise\<void> | 加载指定 URL |
603
- | `loadHTML(html)` | `html`: string — HTML 字符串 | Promise\<void> | 加载指定 HTML 内容 |
604
- | `show()` | 无 | void | 显示窗口 |
605
- | `hide()` | 无 | void | 隐藏窗口 |
606
- | `maximize()` | 无 | void | 最大化窗口 |
607
- | `unMaximize()` | 无 | void | 还原窗口(取消最大化) |
608
- | `minimize()` | 无 | void | 最小化窗口 |
609
- | `unMinimize()` | 无 | void | 还原窗口(取消最小化) |
610
- | `close()` | 无 | void | 关闭窗口并回收至池中 |
611
- | `setTitle(title)` | `title`: string | void | 设置窗口标题 |
612
- | `setDecorated(isDecorated)` | `isDecorated`: boolean | void | 设置窗口是否带边框和标题栏 |
613
- | `resizable(resizable)` | `resizable`: boolean | void | 设置窗口是否可调整大小 |
614
- | `setSize(width, height)` | `width`: number, `height`: number | void | 设置窗口尺寸(像素) |
615
- | `getSize()` | 无 | { width: number, height: number } | 获取窗口尺寸(像素) |
616
- | `setPosition(x, y)` | `x`: number, `y`: number | void | 设置窗口位置(像素) |
617
- | `getPosition()` | 无 | { x: number, y: number } | 获取窗口位置(像素) |
618
- | `focus()` | 无 | void | 窗口获取焦点 |
619
- | `isFocused()` | 无 | boolean | 是否有焦点 |
620
- | `isMaximized()` | 无 | boolean | 是否最大化 |
621
- | `isMinimized()` | 无 | boolean | 是否最小化 |
622
- | `toggleMaximize()` | 无 | void | 切换最大化状态 |
623
- | `toggleMinimize()` | 无 | void | 切换最小化状态 |
624
- | `openDevTools()` | 无 | void | 打开开发者工具 |
625
- | `closeDevTools()` | 无 | void | 关闭开发者工具 |
626
- | `id` | 无 | number | 窗口唯一标识,自增编号 |
663
+ | 方法/属性 | 参数 | 返回值 | 说明 |
664
+ | --------------------------------------- | ----------------------------------------------------------------- | --------------------------------- | ------------------------------------------------------------- |
665
+ | `loadURL(url)` | `url`: string — 要加载的网页地址 | Promise\<void> | 加载指定 URL |
666
+ | `loadHTML(html)` | `html`: string — HTML 字符串 | Promise\<void> | 加载指定 HTML 内容 |
667
+ | `show()` | 无 | void | 显示窗口 |
668
+ | `hide()` | 无 | void | 隐藏窗口 |
669
+ | `maximize()` | 无 | void | 最大化窗口 |
670
+ | `unMaximize()` | 无 | void | 还原窗口(取消最大化) |
671
+ | `minimize()` | 无 | void | 最小化窗口 |
672
+ | `unMinimize()` | 无 | void | 还原窗口(取消最小化) |
673
+ | `close()` | 无 | void | 关闭窗口并回收至池中 |
674
+ | `setTitle(title)` | `title`: string | void | 设置窗口标题 |
675
+ | `setDecorated(isDecorated)` | `isDecorated`: boolean | void | 设置窗口是否带边框和标题栏 |
676
+ | `setResizable(resizable)` | `resizable`: boolean | void | 设置窗口是否可调整大小 |
677
+ | `setLevel(level)` | `level`: `-1` \| `0` \| `1` | void | 设置窗口层级:-1=置底,0=正常,1=置顶 |
678
+ | `setFullScreen(isFullScreen, options?)` | `isFullScreen`: `boolean`, `options?`: `{ borderless?: boolean }` | void | 设置全屏模式。`borderless: true` 为无边框全屏,否则为独占全屏 |
679
+ | `setIcon(icon)` | `icon`: `Icon` | void | 设置窗口图标 |
680
+ | `setSize(width, height)` | `width`: number, `height`: number | void | 设置窗口尺寸(像素) |
681
+ | `getSize()` | 无 | { width: number, height: number } | 获取窗口尺寸(像素) |
682
+ | `setPosition(x, y)` | `x`: number, `y`: number | void | 设置窗口位置(像素) |
683
+ | `getPosition()` | 无 | { x: number, y: number } | 获取窗口位置(像素) |
684
+ | `focus()` | 无 | void | 窗口获取焦点 |
685
+ | `isFocused()` | 无 | boolean | 是否有焦点 |
686
+ | `isMaximized()` | 无 | boolean | 是否最大化 |
687
+ | `isMinimized()` | 无 | boolean | 是否最小化 |
688
+ | `toggleMaximize()` | 无 | void | 切换最大化状态 |
689
+ | `toggleMinimize()` | 无 | void | 切换最小化状态 |
690
+ | `openDevTools()` | 无 | void | 打开开发者工具 |
691
+ | `closeDevTools()` | 无 | void | 关闭开发者工具 |
692
+ | `id` | 无 | number | 窗口唯一标识,自增编号 |
627
693
 
628
694
  ## 开发
629
695