nexfep 0.0.4 → 0.1.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.
Files changed (5) hide show
  1. package/README-CN.md +285 -240
  2. package/README.md +285 -240
  3. package/index.d.ts +45 -41
  4. package/index.js +43 -1
  5. package/package.json +36 -36
package/README-CN.md CHANGED
@@ -1,240 +1,285 @@
1
- # Nexfep
2
-
3
- 语言: [English](https://github.com/zhuxiaojt/Nexfep/blob/main/README.md) | 简体中文(当前)
4
-
5
- 基于 @webviewjs/webview 的桌面应用框架
6
-
7
- ## 项目状态
8
-
9
- **🚧 早期阶段**
10
-
11
- 本项目目前处于早期开发阶段,仍缺失大量桌面应用开发所需的核心能力。框架正在持续迭代中。
12
-
13
- ## 简介
14
-
15
- Nexfep 是一个基于 [@webviewjs/webview](https://github.com/webview/webview) 构建的桌面应用框架,使用 TypeScript 编写。它旨在为开发者提供一套简洁、高效的工具链,用于构建跨平台桌面应用。
16
-
17
- 框架采用窗口池管理机制,支持多窗口应用场景,如代码编辑器、聊天工具、仪表盘等。
18
-
19
- ## 特性
20
-
21
- - **窗口池管理** — 内置窗口池机制,自动复用和回收窗口资源,避免频繁创建销毁的开销
22
- - **IPC 通信** — 支持主进程与 WebView 之间的双向消息通信,通过注入的函数进行调用
23
- - **窗口控制** — 提供最大化、最小化、关闭、标题设置、开发者工具等完整窗口操作 API
24
- - **拖拽区域** — 内置 HTML 属性支持,方便定义窗口拖拽区域(`nexfep-area-drag` 等)
25
- - **TypeScript 支持** — 完整的类型定义,开发体验优秀
26
-
27
- ## 安装
28
-
29
- ```bash
30
- pnpm add nexfep
31
- ```
32
-
33
- ## 快速开始
34
-
35
- ```typescript
36
- import { WindowPool } from 'nexfep';
37
-
38
- const pool = new WindowPool();
39
-
40
- const window = await pool.createWindow(true, false);
41
-
42
- await window.loadHTML('<h1 nexfep-area-drag>Hello Nexfep!</h1>');
43
-
44
- pool.mainloop();
45
- ```
46
-
47
- ## 使用指南
48
-
49
- ### 窗口池
50
-
51
- `WindowPool` 是框架的核心管理类,负责窗口的创建和回收。
52
-
53
- ```typescript
54
- const pool = new WindowPool();
55
- ```
56
-
57
- **构造函数参数**
58
-
59
- - `WindowsWebview2UserDataFolder`(可选)— WebView2 用户数据目录,默认为 `%LOCALAPPDATA%\NexfepDevelopment.webview2-data`
60
-
61
- ### 窗口创建
62
-
63
- ```typescript
64
- const win = await pool.createWindow(true, false);
65
- ```
66
-
67
- **参数说明**
68
-
69
- - `isShow`(布尔值,默认 `true`)— 是否立即显示窗口
70
- - `isDecorated`(布尔值,默认 `true`)— 是否使用系统窗口装饰。设为 `false` 时,窗口无边框,需要自定义标题栏
71
-
72
- ### 窗口操作
73
-
74
- ```typescript
75
- window.show();
76
- window.hide();
77
- window.maximize();
78
- window.minimize();
79
- window.close();
80
- window.setTitle('新标题');
81
- window.openDevTools();
82
- ```
83
-
84
- ### IPC 通信
85
-
86
- 框架在 WebView 页面加载完成后会自动注入一系列控制函数,建议使用这些注入的函数进行 IPC 通信,而非直接使用 `@webviewjs/webview` 原生包装的 IPC。
87
-
88
- #### 发送自定义消息
89
-
90
- 在页面中通过 `window.postMessage` 发送消息:
91
-
92
- ```javascript
93
- window.postMessage({ hello: 'world' });
94
- ```
95
-
96
- **参数说明**
97
-
98
- - `data` — 任意类型的可序列化数据,会被序列化为 JSON 字符串后发送
99
-
100
- #### 监听消息
101
-
102
- 在主进程中通过 `onCustomMessage` 回调接收消息:
103
-
104
- ```typescript
105
- pool.onCustomMessage = (window, data) => {
106
- console.log(`来自窗口 ${window.id} 的消息:`, data);
107
- };
108
- ```
109
-
110
- **回调参数**
111
-
112
- - `window` — 发送消息的窗口对象
113
- - `data` — 消息内容,为对象类型(JSON 序列化后会自动通过 `JSON.parse` 转换为对象)
114
-
115
- #### 窗口控制函数
116
-
117
- 页面中可直接调用以下注入函数进行窗口控制:
118
-
119
- ```javascript
120
- window.close(); // 关闭窗口
121
- window.minimize(); // 最小化窗口
122
- window.unminimize(); // 还原最小化的窗口
123
- window.maximize(); // 最大化窗口
124
- window.unmaximize(); // 还原最大化的窗口
125
- window.setTitle('标题'); // 设置窗口标题
126
- window.openDevTools(); // 打开开发者工具
127
- window.closeDevTools(); // 关闭开发者工具
128
- ```
129
-
130
- ### 拖拽区域
131
-
132
- 通过 HTML 属性即可定义窗口拖拽区域,无需编写额外 JavaScript 代码。这些属性会自动应用 `-webkit-app-region` 和 `app-region` CSS 属性。
133
-
134
- #### `nexfep-area-drag`
135
-
136
- 使整个区域及其所有子元素均可拖拽。适用于自定义标题栏等需要整块区域可拖拽的场景。
137
-
138
- ```html
139
- <div nexfep-area-drag>
140
- <h1>标题栏</h1>
141
- <span>副标题</span>
142
- </div>
143
- ```
144
-
145
- #### `nexfep-element-drag`
146
-
147
- 仅使指定元素本身可拖拽,子元素不受影响。适用于需要精确控制拖拽区域的场景。
148
-
149
- ```html
150
- <div>
151
- <div nexfep-element-drag>拖拽手柄</div>
152
- <p>这部分不可拖拽</p>
153
- </div>
154
- ```
155
-
156
- #### `nexfep-no-drag`
157
-
158
- 使指定区域及其所有子元素不可拖拽,优先级最高,可覆盖父元素的拖拽属性。适用于按钮、输入框等交互元素。
159
-
160
- ```html
161
- <div nexfep-area-drag>
162
- <h1>标题栏</h1>
163
- <button nexfep-no-drag>点击按钮</button>
164
- </div>
165
- ```
166
-
167
- #### `nexfep-auto-drag`
168
-
169
- 自动判断拖拽区域:整个区域可拖拽,但常见交互元素(`button`、`input`、`select`、`textarea`、`a`)自动设为不可拖拽。适用于包含多种交互元素的复杂区域。
170
-
171
- ```html
172
- <div nexfep-auto-drag>
173
- <h1>标题栏</h1>
174
- <button>自动不可拖拽</button>
175
- <input placeholder="自动不可拖拽" />
176
- <a href="#">自动不可拖拽</a>
177
- </div>
178
- ```
179
-
180
- ### 加载完成事件
181
-
182
- WebView 窗口加载完成后会触发 `nexfep-load-done` 事件:
183
-
184
- ```javascript
185
- window.addEventListener('nexfep-load-done', () => {
186
- console.log('Nexfep 窗口加载完成');
187
- });
188
- ```
189
-
190
- 也可通过 `window.isNexfepLoadDone` 属性判断:
191
-
192
- ```javascript
193
- if (window.isNexfepLoadDone) {
194
- // 窗口已就绪
195
- }
196
- ```
197
-
198
- ## API
199
-
200
- ### WindowPool
201
-
202
- | 方法/属性 | 参数 | 返回值 | 说明 |
203
- | ------------------------------------- | ----------------------------------------------------------- | ---------------- | -------------------------- |
204
- | `constructor(userDataFolder?)` | `userDataFolder`: string(可选) | WindowPool | 创建窗口池,可选指定 WebView2 用户数据目录 |
205
- | `createWindow(isShow?, isDecorated?)` | `isShow`: boolean(默认 true), `isDecorated`: boolean(默认 true) | Promise\<Window> | 创建并获取一个窗口 |
206
- | `closeWindow(window)` | `window`: Window | Promise\<void> | 关闭指定窗口并回收至池中 |
207
- | `closePool()` | 无 | Promise\<void> | 关闭窗口池,退出应用 |
208
- | `mainloop()` | 无 | void | 启动应用主循环,阻塞直到应用退出 |
209
- | `onCustomMessage` | `(window: Window, data: string) => void` | 无 | 自定义消息回调函数,当收到页面发来的自定义消息时触发 |
210
-
211
- ### Window
212
-
213
- | 方法/属性 | 参数 | 返回值 | 说明 |
214
- | --------------------------- | --------------------------------- | -------------- | ------------- |
215
- | `loadURL(url)` | `url`: string — 要加载的网页地址 | Promise\<void> | 加载指定 URL |
216
- | `loadHTML(html)` | `html`: string — HTML 字符串 | Promise\<void> | 加载指定 HTML 内容 |
217
- | `show()` | 无 | void | 显示窗口 |
218
- | `hide()` | 无 | void | 隐藏窗口 |
219
- | `maximize()` | 无 | void | 最大化窗口 |
220
- | `unMaximize()` | 无 | void | 还原窗口(取消最大化) |
221
- | `minimize()` | 无 | void | 最小化窗口 |
222
- | `unMinimize()` | 无 | void | 还原窗口(取消最小化) |
223
- | `close()` | 无 | void | 关闭窗口并回收至池中 |
224
- | `setTitle(title)` | `title`: string — 窗口标题 | void | 设置窗口标题 |
225
- | `setDecorated(isDecorated)` | `isDecorated`: boolean — 是否使用系统装饰 | void | 设置窗口是否带边框和标题栏 |
226
- | `resizable(resizable)` | `resizable`: boolean — 是否可调整大小 | void | 设置窗口是否可调整大小 |
227
- | `openDevTools()` | 无 | void | 打开开发者工具 |
228
- | `closeDevTools()` | 无 | void | 关闭开发者工具 |
229
- | `id` | 无 | number | 窗口唯一标识,自增编号 |
230
-
231
- ## 开发
232
-
233
- ```bash
234
- pnpm install
235
- pnpm run compile
236
- ```
237
-
238
- ## 许可证
239
-
240
- MIT License
1
+ # Nexfep
2
+
3
+ 语言: [English](https://github.com/nexfteam/Nexfep/blob/main/README.md) | 简体中文(当前)
4
+
5
+ 基于 @webviewjs/webview 的桌面应用框架
6
+
7
+ ## 项目状态
8
+
9
+ **🚧 早期阶段**
10
+
11
+ 本项目目前处于早期开发阶段,仍缺失大量桌面应用开发所需的核心能力。框架正在持续迭代中。
12
+
13
+ ## 简介
14
+
15
+ Nexfep 是一个基于 [@webviewjs/webview](https://github.com/webviewjs/webview) 构建的桌面应用框架,使用 TypeScript 编写。它旨在为开发者提供一套简洁、高效的工具链,用于构建跨平台桌面应用。
16
+
17
+ 框架采用窗口池管理机制,支持多窗口应用场景,如代码编辑器、聊天工具、仪表盘等。
18
+
19
+ ## 特性
20
+
21
+ - **窗口池管理** — 内置窗口池机制,自动复用和回收窗口资源,避免频繁创建销毁的开销
22
+ - **IPC 通信** — 支持主进程与 WebView 之间的双向消息通信,通过注入的函数进行调用
23
+ - **窗口控制** — 提供最大化、最小化、关闭、标题设置、开发者工具等完整窗口操作 API
24
+ - **拖拽区域** — 内置 HTML 属性支持,方便定义窗口拖拽区域(`nexfep-area-drag` 等)
25
+ - **TypeScript 支持** — 完整的类型定义,开发体验优秀
26
+
27
+ ## 安装
28
+
29
+ ```bash
30
+ pnpm add nexfep
31
+ ```
32
+
33
+ ## 快速开始
34
+
35
+ ```typescript
36
+ import { WindowPool } from 'nexfep';
37
+
38
+ const pool = new WindowPool();
39
+
40
+ const window = await pool.createWindow(true, false);
41
+
42
+ await window.loadHTML('<h1 nexfep-area-drag>Hello Nexfep!</h1>');
43
+
44
+ pool.mainloop();
45
+ ```
46
+
47
+ ## 使用指南
48
+
49
+ ### 窗口池
50
+
51
+ `WindowPool` 是框架的核心管理类,负责窗口的创建和回收。
52
+
53
+ ```typescript
54
+ const pool = new WindowPool();
55
+ ```
56
+
57
+ **构造函数参数**
58
+
59
+ - `WindowsWebview2UserDataFolder`(可选)— WebView2 用户数据目录,默认为 `%LOCALAPPDATA%\NexfepDevelopment.webview2-data`
60
+
61
+ ### 窗口创建
62
+
63
+ ```typescript
64
+ const win = await pool.createWindow(true, false);
65
+ ```
66
+
67
+ **参数说明**
68
+
69
+ - `isShow`(布尔值,默认 `true`)— 是否立即显示窗口
70
+ - `isDecorated`(布尔值,默认 `true`)— 是否使用系统窗口装饰。设为 `false` 时,窗口无边框,需要自定义标题栏
71
+
72
+ ### 窗口操作
73
+
74
+ ```typescript
75
+ window.show();
76
+ window.hide();
77
+ window.maximize();
78
+ window.minimize();
79
+ window.close();
80
+ window.setTitle('新标题');
81
+ window.openDevTools();
82
+ ```
83
+
84
+ ### IPC 通信
85
+
86
+ 框架在 WebView 页面加载完成后会自动注入一系列控制函数,建议使用这些注入的函数进行 IPC 通信,而非直接使用 `@webviewjs/webview` 原生包装的 IPC。
87
+
88
+ #### 发送自定义消息
89
+
90
+ 在页面中通过 `window.postMessage` 发送消息:
91
+
92
+ ```javascript
93
+ window.postMessage({ hello: 'world' });
94
+ ```
95
+
96
+ **参数说明**
97
+
98
+ - `data` — 任意类型的可序列化数据,会被序列化为 JSON 字符串后发送
99
+
100
+ #### 监听消息
101
+
102
+ 在主进程中通过 `onCustomMessage` 回调接收消息:
103
+
104
+ ```typescript
105
+ pool.onCustomMessage = (window, data) => {
106
+ console.log(`来自窗口 ${window.id} 的消息:`, data);
107
+ };
108
+ ```
109
+
110
+ **回调参数**
111
+
112
+ - `window` — 发送消息的窗口对象
113
+ - `data` — 消息内容,为对象类型(JSON 序列化后会自动通过 `JSON.parse` 转换为对象)
114
+
115
+ #### 触发自定义事件
116
+
117
+ 在页面中通过 `window.invoke` 触发事件:
118
+
119
+ ```javascript
120
+ window.invoke('hello', 'world');
121
+ ```
122
+
123
+ **参数说明**
124
+
125
+ - `event` — 事件名称
126
+ - `data` — 任意类型的可序列化数据,会被序列化为 JSON 字符串后发送
127
+
128
+ #### 监听事件
129
+
130
+ 在主进程中通过 `pool.handle` 监听事件:
131
+
132
+ ```typescript
133
+ pool.handle('hello', (data) => {
134
+ console.log('收到事件 hello:', data);
135
+ });
136
+ ```
137
+
138
+ **参数说明**
139
+
140
+ - `event` — 事件名称,需要和触发事件时的事件名称一致
141
+ - `callback` — 事件处理函数,需要接收事件数据作为 `data` 参数。返回任意类型的可序列化数据,会被序列化为 JSON 字符串后发送至前端作为 `window.invoke` 的返回值(也可以不返回任何值)
142
+
143
+ #### 取消监听事件
144
+
145
+ 在主进程中通过 `pool.unhandle` 取消监听事件:
146
+
147
+ ```typescript
148
+ pool.unhandle('hello', (data) => {
149
+ console.log('收到事件 hello:', data);
150
+ });
151
+ ```
152
+
153
+ **参数说明**
154
+
155
+ - `event` — 事件名称,需要和触发事件时的事件名称一致
156
+ - `callback` — 事件处理函数,需要和监听事件时的回调函数一致
157
+
158
+ #### 窗口控制函数
159
+
160
+ 页面中可直接调用以下注入函数进行窗口控制:
161
+
162
+ ```javascript
163
+ window.close(); // 关闭窗口
164
+ window.minimize(); // 最小化窗口
165
+ window.unminimize(); // 还原最小化的窗口
166
+ window.maximize(); // 最大化窗口
167
+ window.unmaximize(); // 还原最大化的窗口
168
+ window.setTitle('标题'); // 设置窗口标题
169
+ window.openDevTools(); // 打开开发者工具
170
+ window.closeDevTools(); // 关闭开发者工具
171
+ ```
172
+
173
+ ### 拖拽区域
174
+
175
+ 通过 HTML 属性即可定义窗口拖拽区域,无需编写额外 JavaScript 代码。这些属性会自动应用 `-webkit-app-region` 和 `app-region` CSS 属性。
176
+
177
+ #### `nexfep-area-drag`
178
+
179
+ 使整个区域及其所有子元素均可拖拽。适用于自定义标题栏等需要整块区域可拖拽的场景。
180
+
181
+ ```html
182
+ <div nexfep-area-drag>
183
+ <h1>标题栏</h1>
184
+ <span>副标题</span>
185
+ </div>
186
+ ```
187
+
188
+ #### `nexfep-element-drag`
189
+
190
+ 仅使指定元素本身可拖拽,子元素不受影响。适用于需要精确控制拖拽区域的场景。
191
+
192
+ ```html
193
+ <div>
194
+ <div nexfep-element-drag>拖拽手柄</div>
195
+ <p>这部分不可拖拽</p>
196
+ </div>
197
+ ```
198
+
199
+ #### `nexfep-no-drag`
200
+
201
+ 使指定区域及其所有子元素不可拖拽,优先级最高,可覆盖父元素的拖拽属性。适用于按钮、输入框等交互元素。
202
+
203
+ ```html
204
+ <div nexfep-area-drag>
205
+ <h1>标题栏</h1>
206
+ <button nexfep-no-drag>点击按钮</button>
207
+ </div>
208
+ ```
209
+
210
+ #### `nexfep-auto-drag`
211
+
212
+ 自动判断拖拽区域:整个区域可拖拽,但常见交互元素(`button`、`input`、`select`、`textarea`、`a`)自动设为不可拖拽。适用于包含多种交互元素的复杂区域。
213
+
214
+ ```html
215
+ <div nexfep-auto-drag>
216
+ <h1>标题栏</h1>
217
+ <button>自动不可拖拽</button>
218
+ <input placeholder="自动不可拖拽" />
219
+ <a href="#">自动不可拖拽</a>
220
+ </div>
221
+ ```
222
+
223
+ ### 加载完成事件
224
+
225
+ WebView 窗口加载完成后会触发 `nexfep-load-done` 事件:
226
+
227
+ ```javascript
228
+ window.addEventListener('nexfep-load-done', () => {
229
+ console.log('Nexfep 窗口加载完成');
230
+ });
231
+ ```
232
+
233
+ 也可通过 `window.isNexfepLoadDone` 属性判断:
234
+
235
+ ```javascript
236
+ if (window.isNexfepLoadDone) {
237
+ // 窗口已就绪
238
+ }
239
+ ```
240
+
241
+ ## API
242
+
243
+ ### WindowPool
244
+
245
+ | 方法/属性 | 参数 | 返回值 | 说明 |
246
+ | ------------------------------------- | ----------------------------------------------------------- | ---------------- | -------------------------- |
247
+ | `constructor(userDataFolder?)` | `userDataFolder`: string(可选) | WindowPool | 创建窗口池,可选指定 WebView2 用户数据目录 |
248
+ | `createWindow(isShow?, isDecorated?)` | `isShow`: boolean(默认 true), `isDecorated`: boolean(默认 true) | Promise\<Window> | 创建并获取一个窗口 |
249
+ | `handle(event, callback)` | `event`: string, `callback`: (data: string) => void | 无 | 监听指定事件,当收到事件时触发回调函数 |
250
+ | `unhandle(event, callback)` | `event`: string, `callback`: (data: string) => void | 无 | 取消监听指定事件回调中的指定函数 |
251
+ | `closeWindow(window)` | `window`: Window | Promise\<void> | 关闭指定窗口并回收至池中 |
252
+ | `closePool()` | 无 | Promise\<void> | 关闭窗口池,退出应用 |
253
+ | `mainloop()` | 无 | void | 启动应用主循环,阻塞直到应用退出 |
254
+ | `onCustomMessage` | `(window: Window, data: string) => void` | 无 | 自定义消息回调函数,当收到页面发来的自定义消息时触发 |
255
+
256
+ ### Window
257
+
258
+ | 方法/属性 | 参数 | 返回值 | 说明 |
259
+ | --------------------------- | --------------------------------- | -------------- | ------------- |
260
+ | `loadURL(url)` | `url`: string — 要加载的网页地址 | Promise\<void> | 加载指定 URL |
261
+ | `loadHTML(html)` | `html`: string — HTML 字符串 | Promise\<void> | 加载指定 HTML 内容 |
262
+ | `show()` | 无 | void | 显示窗口 |
263
+ | `hide()` | 无 | void | 隐藏窗口 |
264
+ | `maximize()` | 无 | void | 最大化窗口 |
265
+ | `unMaximize()` | 无 | void | 还原窗口(取消最大化) |
266
+ | `minimize()` | 无 | void | 最小化窗口 |
267
+ | `unMinimize()` | 无 | void | 还原窗口(取消最小化) |
268
+ | `close()` | 无 | void | 关闭窗口并回收至池中 |
269
+ | `setTitle(title)` | `title`: string — 窗口标题 | void | 设置窗口标题 |
270
+ | `setDecorated(isDecorated)` | `isDecorated`: boolean — 是否使用系统装饰 | void | 设置窗口是否带边框和标题栏 |
271
+ | `resizable(resizable)` | `resizable`: boolean — 是否可调整大小 | void | 设置窗口是否可调整大小 |
272
+ | `openDevTools()` | 无 | void | 打开开发者工具 |
273
+ | `closeDevTools()` | 无 | void | 关闭开发者工具 |
274
+ | `id` | 无 | number | 窗口唯一标识,自增编号 |
275
+
276
+ ## 开发
277
+
278
+ ```bash
279
+ pnpm install
280
+ pnpm run compile
281
+ ```
282
+
283
+ ## 许可证
284
+
285
+ MIT License
package/README.md CHANGED
@@ -1,240 +1,285 @@
1
- # Nexfep
2
-
3
- Language: English(now) | [简体中文](https://github.com/zhuxiaojt/Nexfep/blob/main/README-CN.md)
4
-
5
- A desktop application framework based on @webviewjs/webview
6
-
7
- ## Project Status
8
-
9
- **🚧 Early Stage**
10
-
11
- This project is currently in early development, with many core capabilities for desktop application development still missing. The framework is being continuously iterated.
12
-
13
- ## Introduction
14
-
15
- Nexfep is a desktop application framework built on [@webviewjs/webview](https://github.com/webview/webview), written in TypeScript. It aims to provide developers with a concise and efficient toolchain for building cross-platform desktop applications.
16
-
17
- The framework uses a window pool management mechanism, supporting multi-window application scenarios such as code editors, chat tools, dashboards, etc.
18
-
19
- ## Features
20
-
21
- - **Window Pool Management** — Built-in window pool mechanism for automatic reuse and recycling of window resources, avoiding the overhead of frequent creation and destruction
22
- - **IPC Communication** — Supports bidirectional message communication between the main process and WebView, via injected functions
23
- - **Window Control** — Provides complete window operation APIs including maximize, minimize, close, title setting, and developer tools
24
- - **Drag Regions** — Built-in HTML attribute support for defining window drag regions (`nexfep-area-drag`, etc.)
25
- - **TypeScript Support** — Complete type definitions for excellent development experience
26
-
27
- ## Installation
28
-
29
- ```bash
30
- pnpm add nexfep
31
- ```
32
-
33
- ## Quick Start
34
-
35
- ```typescript
36
- import { WindowPool } from 'nexfep';
37
-
38
- const pool = new WindowPool();
39
-
40
- const window = await pool.createWindow(true, false);
41
-
42
- await window.loadHTML('<h1 nexfep-area-drag>Hello Nexfep!</h1>');
43
-
44
- pool.mainloop();
45
- ```
46
-
47
- ## Usage Guide
48
-
49
- ### Window Pool
50
-
51
- `WindowPool` is the core management class of the framework, responsible for window creation and recycling.
52
-
53
- ```typescript
54
- const pool = new WindowPool();
55
- ```
56
-
57
- **Constructor Parameters**
58
-
59
- - `WindowsWebview2UserDataFolder` (optional) — WebView2 user data directory, defaults to `%LOCALAPPDATA%\NexfepDevelopment.webview2-data`
60
-
61
- ### Window Creation
62
-
63
- ```typescript
64
- const win = await pool.createWindow(true, false);
65
- ```
66
-
67
- **Parameters**
68
-
69
- - `isShow` (boolean, default `true`) — Whether to immediately show the window
70
- - `isDecorated` (boolean, default `true`) — Whether to use system window decorations. When set to `false`, the window has no border and requires a custom title bar
71
-
72
- ### Window Operations
73
-
74
- ```typescript
75
- window.show();
76
- window.hide();
77
- window.maximize();
78
- window.minimize();
79
- window.close();
80
- window.setTitle('New Title');
81
- window.openDevTools();
82
- ```
83
-
84
- ### IPC Communication
85
-
86
- The framework automatically injects a series of control functions after WebView page loading is complete. It is recommended to use these injected functions for IPC communication, rather than the native IPC wrapped by `@webviewjs/webview`.
87
-
88
- #### Send Custom Messages
89
-
90
- Send messages via `window.postMessage` in the page:
91
-
92
- ```javascript
93
- window.postMessage({ hello: 'world' });
94
- ```
95
-
96
- **Parameters**
97
-
98
- - `data` — Any serializable data, will be serialized to JSON string before sending
99
-
100
- #### Listen for Messages
101
-
102
- Receive messages via `onCustomMessage` callback in the main process:
103
-
104
- ```typescript
105
- pool.onCustomMessage = (window, data) => {
106
- console.log(`Message from window ${window.id}:`, data);
107
- };
108
- ```
109
-
110
- **Callback Parameters**
111
-
112
- - `window` — The window object that sent the message
113
- - `data` — Message content, an object type (automatically converted from JSON string via `JSON.parse`)
114
-
115
- #### Window Control Functions
116
-
117
- The following injected functions can be directly called in the page for window control:
118
-
119
- ```javascript
120
- window.close(); // Close window
121
- window.minimize(); // Minimize window
122
- window.unminimize(); // Restore minimized window
123
- window.maximize(); // Maximize window
124
- window.unmaximize(); // Restore maximized window
125
- window.setTitle('Title'); // Set window title
126
- window.openDevTools(); // Open developer tools
127
- window.closeDevTools(); // Close developer tools
128
- ```
129
-
130
- ### Drag Regions
131
-
132
- Define window drag regions via HTML attributes without writing additional JavaScript code. These attributes automatically apply `-webkit-app-region` and `app-region` CSS properties.
133
-
134
- #### `nexfep-area-drag`
135
-
136
- Makes the entire region and all its child elements draggable. Suitable for scenarios like custom title bars where the entire region needs to be draggable.
137
-
138
- ```html
139
- <div nexfep-area-drag>
140
- <h1>Title Bar</h1>
141
- <span>Subtitle</span>
142
- </div>
143
- ```
144
-
145
- #### `nexfep-element-drag`
146
-
147
- Makes only the specified element itself draggable; child elements are not affected. Suitable for scenarios requiring precise control over the drag region.
148
-
149
- ```html
150
- <div>
151
- <div nexfep-element-drag>Drag Handle</div>
152
- <p>This part is not draggable</p>
153
- </div>
154
- ```
155
-
156
- #### `nexfep-no-drag`
157
-
158
- Makes the specified region and all its child elements non-draggable. Highest priority, can override parent element's drag attributes. Suitable for interactive elements like buttons and input fields.
159
-
160
- ```html
161
- <div nexfep-area-drag>
162
- <h1>Title Bar</h1>
163
- <button nexfep-no-drag>Click Button</button>
164
- </div>
165
- ```
166
-
167
- #### `nexfep-auto-drag`
168
-
169
- Automatically determines drag regions: the entire region is draggable, but common interactive elements (`button`, `input`, `select`, `textarea`, `a`) are automatically set to non-draggable. Suitable for complex regions containing multiple interactive elements.
170
-
171
- ```html
172
- <div nexfep-auto-drag>
173
- <h1>Title Bar</h1>
174
- <button>Automatically non-draggable</button>
175
- <input placeholder="Automatically non-draggable" />
176
- <a href="#">Automatically non-draggable</a>
177
- </div>
178
- ```
179
-
180
- ### Load Complete Event
181
-
182
- The `nexfep-load-done` event is triggered after the WebView window finishes loading:
183
-
184
- ```javascript
185
- window.addEventListener('nexfep-load-done', () => {
186
- console.log('Nexfep window loaded');
187
- });
188
- ```
189
-
190
- It can also be checked via the `window.isNexfepLoadDone` property:
191
-
192
- ```javascript
193
- if (window.isNexfepLoadDone) {
194
- // Window is ready
195
- }
196
- ```
197
-
198
- ## API
199
-
200
- ### WindowPool
201
-
202
- | Method/Property | Parameters | Return Value | Description |
203
- | ------------------------------------- | -------------------------------------------------------------------------- | ---------------- | ------------------------------------------------------------------------ |
204
- | `constructor(userDataFolder?)` | `userDataFolder`: string (optional) | WindowPool | Creates a window pool, optionally specifying the WebView2 user data directory |
205
- | `createWindow(isShow?, isDecorated?)` | `isShow`: boolean (default true), `isDecorated`: boolean (default true) | Promise\<Window> | Creates and returns a window |
206
- | `closeWindow(window)` | `window`: Window | Promise\<void> | Closes the specified window and returns it to the pool |
207
- | `closePool()` | None | Promise\<void> | Closes the window pool and exits the application |
208
- | `mainloop()` | None | void | Starts the application main loop, blocking until the application exits |
209
- | `onCustomMessage` | `(window: Window, data: string) => void` | None | Custom message callback, triggered when receiving custom messages from pages |
210
-
211
- ### Window
212
-
213
- | Method/Property | Parameters | Return Value | Description |
214
- | ------------------------------------- | ------------------------------------------- | ---------------- | ---------------------------------------- |
215
- | `loadURL(url)` | `url`: string — URL to load | Promise\<void> | Loads the specified URL |
216
- | `loadHTML(html)` | `html`: string — HTML string | Promise\<void> | Loads the specified HTML content |
217
- | `show()` | None | void | Shows the window |
218
- | `hide()` | None | void | Hides the window |
219
- | `maximize()` | None | void | Maximizes the window |
220
- | `unMaximize()` | None | void | Restores the window (cancels maximize) |
221
- | `minimize()` | None | void | Minimizes the window |
222
- | `unMinimize()` | None | void | Restores the window (cancels minimize) |
223
- | `close()` | None | void | Closes the window and returns to pool |
224
- | `setTitle(title)` | `title`: string — Window title | void | Sets the window title |
225
- | `setDecorated(isDecorated)` | `isDecorated`: boolean Use system decorations | void | Sets whether the window has borders and title bar |
226
- | `resizable(resizable)` | `resizable`: boolean — Resizable | void | Sets whether the window is resizable |
227
- | `openDevTools()` | None | void | Opens developer tools |
228
- | `closeDevTools()` | None | void | Closes developer tools |
229
- | `id` | None | number | Unique window identifier, auto-incrementing |
230
-
231
- ## Development
232
-
233
- ```bash
234
- pnpm install
235
- pnpm run compile
236
- ```
237
-
238
- ## License
239
-
240
- MIT License
1
+ # Nexfep
2
+
3
+ Language: English(now) | [简体中文](https://github.com/nexfteam/Nexfep/blob/main/README-CN.md)
4
+
5
+ A desktop application framework based on @webviewjs/webview
6
+
7
+ ## Project Status
8
+
9
+ **🚧 Early Stage**
10
+
11
+ This project is currently in early development, with many core capabilities for desktop application development still missing. The framework is being continuously iterated.
12
+
13
+ ## Introduction
14
+
15
+ Nexfep is a desktop application framework built on [@webviewjs/webview](https://github.com/webviewjs/webview), written in TypeScript. It aims to provide developers with a concise and efficient toolchain for building cross-platform desktop applications.
16
+
17
+ The framework uses a window pool management mechanism, supporting multi-window application scenarios such as code editors, chat tools, dashboards, etc.
18
+
19
+ ## Features
20
+
21
+ - **Window Pool Management** — Built-in window pool mechanism for automatic reuse and recycling of window resources, avoiding the overhead of frequent creation and destruction
22
+ - **IPC Communication** — Supports bidirectional message communication between the main process and WebView, via injected functions
23
+ - **Window Control** — Provides complete window operation APIs including maximize, minimize, close, title setting, and developer tools
24
+ - **Drag Regions** — Built-in HTML attribute support for defining window drag regions (`nexfep-area-drag`, etc.)
25
+ - **TypeScript Support** — Complete type definitions for excellent development experience
26
+
27
+ ## Installation
28
+
29
+ ```bash
30
+ pnpm add nexfep
31
+ ```
32
+
33
+ ## Quick Start
34
+
35
+ ```typescript
36
+ import { WindowPool } from 'nexfep';
37
+
38
+ const pool = new WindowPool();
39
+
40
+ const window = await pool.createWindow(true, false);
41
+
42
+ await window.loadHTML('<h1 nexfep-area-drag>Hello Nexfep!</h1>');
43
+
44
+ pool.mainloop();
45
+ ```
46
+
47
+ ## Usage Guide
48
+
49
+ ### Window Pool
50
+
51
+ `WindowPool` is the core management class of the framework, responsible for window creation and recycling.
52
+
53
+ ```typescript
54
+ const pool = new WindowPool();
55
+ ```
56
+
57
+ **Constructor Parameters**
58
+
59
+ - `WindowsWebview2UserDataFolder` (optional) — WebView2 user data directory, defaults to `%LOCALAPPDATA%\NexfepDevelopment.webview2-data`
60
+
61
+ ### Window Creation
62
+
63
+ ```typescript
64
+ const win = await pool.createWindow(true, false);
65
+ ```
66
+
67
+ **Parameters**
68
+
69
+ - `isShow` (boolean, default `true`) — Whether to immediately show the window
70
+ - `isDecorated` (boolean, default `true`) — Whether to use system window decorations. When set to `false`, the window has no border and requires a custom title bar
71
+
72
+ ### Window Operations
73
+
74
+ ```typescript
75
+ window.show();
76
+ window.hide();
77
+ window.maximize();
78
+ window.minimize();
79
+ window.close();
80
+ window.setTitle('New Title');
81
+ window.openDevTools();
82
+ ```
83
+
84
+ ### IPC Communication
85
+
86
+ The framework automatically injects a series of control functions after WebView page loading is complete. It is recommended to use these injected functions for IPC communication, rather than the native IPC wrapped by `@webviewjs/webview`.
87
+
88
+ #### Send Custom Messages
89
+
90
+ Send messages via `window.postMessage` in the page:
91
+
92
+ ```javascript
93
+ window.postMessage({ hello: 'world' });
94
+ ```
95
+
96
+ **Parameters**
97
+
98
+ - `data` — Any serializable data, will be serialized to JSON string before sending
99
+
100
+ #### Listen for Messages
101
+
102
+ Receive messages via `onCustomMessage` callback in the main process:
103
+
104
+ ```typescript
105
+ pool.onCustomMessage = (window, data) => {
106
+ console.log(`Message from window ${window.id}:`, data);
107
+ };
108
+ ```
109
+
110
+ **Callback Parameters**
111
+
112
+ - `window` — The window object that sent the message
113
+ - `data` — Message content, an object type (automatically converted from JSON string via `JSON.parse`)
114
+
115
+ #### Invoke Custom Events
116
+
117
+ Invoke events via `window.invoke` in the page:
118
+
119
+ ```javascript
120
+ window.invoke('hello', 'world');
121
+ ```
122
+
123
+ **Parameters**
124
+
125
+ - `event` Event name
126
+ - `data` Any serializable data, will be serialized to JSON string before sending
127
+
128
+ #### Listen for Events
129
+
130
+ Listen for events via `pool.handle` in the main process:
131
+
132
+ ```typescript
133
+ pool.handle('hello', (data) => {
134
+ console.log('Received event hello:', data);
135
+ });
136
+ ```
137
+
138
+ **Parameters**
139
+
140
+ - `event` — Event name, must match the event name when invoking
141
+ - `callback` — Event handler function, receives event data as `data` parameter. Can return any serializable data, which will be serialized to JSON string and sent back to the frontend as the return value of `window.invoke` (can also return nothing)
142
+
143
+ #### Remove Event Listener
144
+
145
+ Remove event listener via `pool.unhandle` in the main process:
146
+
147
+ ```typescript
148
+ pool.unhandle('hello', (data) => {
149
+ console.log('Received event hello:', data);
150
+ });
151
+ ```
152
+
153
+ **Parameters**
154
+
155
+ - `event` — Event name, must match the event name when listening
156
+ - `callback` — Event handler function, must match the callback function when listening
157
+
158
+ #### Window Control Functions
159
+
160
+ The following injected functions can be directly called in the page for window control:
161
+
162
+ ```javascript
163
+ window.close(); // Close window
164
+ window.minimize(); // Minimize window
165
+ window.unminimize(); // Restore minimized window
166
+ window.maximize(); // Maximize window
167
+ window.unmaximize(); // Restore maximized window
168
+ window.setTitle('Title'); // Set window title
169
+ window.openDevTools(); // Open developer tools
170
+ window.closeDevTools(); // Close developer tools
171
+ ```
172
+
173
+ ### Drag Regions
174
+
175
+ Define window drag regions via HTML attributes without writing additional JavaScript code. These attributes automatically apply `-webkit-app-region` and `app-region` CSS properties.
176
+
177
+ #### `nexfep-area-drag`
178
+
179
+ Makes the entire region and all its child elements draggable. Suitable for scenarios like custom title bars where the entire region needs to be draggable.
180
+
181
+ ```html
182
+ <div nexfep-area-drag>
183
+ <h1>Title Bar</h1>
184
+ <span>Subtitle</span>
185
+ </div>
186
+ ```
187
+
188
+ #### `nexfep-element-drag`
189
+
190
+ Makes only the specified element itself draggable; child elements are not affected. Suitable for scenarios requiring precise control over the drag region.
191
+
192
+ ```html
193
+ <div>
194
+ <div nexfep-element-drag>Drag Handle</div>
195
+ <p>This part is not draggable</p>
196
+ </div>
197
+ ```
198
+
199
+ #### `nexfep-no-drag`
200
+
201
+ Makes the specified region and all its child elements non-draggable. Highest priority, can override parent element's drag attributes. Suitable for interactive elements like buttons and input fields.
202
+
203
+ ```html
204
+ <div nexfep-area-drag>
205
+ <h1>Title Bar</h1>
206
+ <button nexfep-no-drag>Click Button</button>
207
+ </div>
208
+ ```
209
+
210
+ #### `nexfep-auto-drag`
211
+
212
+ Automatically determines drag regions: the entire region is draggable, but common interactive elements (`button`, `input`, `select`, `textarea`, `a`) are automatically set to non-draggable. Suitable for complex regions containing multiple interactive elements.
213
+
214
+ ```html
215
+ <div nexfep-auto-drag>
216
+ <h1>Title Bar</h1>
217
+ <button>Automatically non-draggable</button>
218
+ <input placeholder="Automatically non-draggable" />
219
+ <a href="#">Automatically non-draggable</a>
220
+ </div>
221
+ ```
222
+
223
+ ### Load Complete Event
224
+
225
+ The `nexfep-load-done` event is triggered after the WebView window finishes loading:
226
+
227
+ ```javascript
228
+ window.addEventListener('nexfep-load-done', () => {
229
+ console.log('Nexfep window loaded');
230
+ });
231
+ ```
232
+
233
+ It can also be checked via the `window.isNexfepLoadDone` property:
234
+
235
+ ```javascript
236
+ if (window.isNexfepLoadDone) {
237
+ // Window is ready
238
+ }
239
+ ```
240
+
241
+ ## API
242
+
243
+ ### WindowPool
244
+
245
+ | Method/Property | Parameters | Return Value | Description |
246
+ | ------------------------------------- | -------------------------------------------------------------------------- | ---------------- | ------------------------------------------------------------------------ |
247
+ | `constructor(userDataFolder?)` | `userDataFolder`: string (optional) | WindowPool | Creates a window pool, optionally specifying the WebView2 user data directory |
248
+ | `createWindow(isShow?, isDecorated?)` | `isShow`: boolean (default true), `isDecorated`: boolean (default true) | Promise\<Window> | Creates and returns a window |
249
+ | `handle(event, callback)` | `event`: string, `callback`: (data: string) => void | None | Listens for the specified event, triggers callback when event is received |
250
+ | `unhandle(event, callback)` | `event`: string, `callback`: (data: string) => void | None | Removes the specified callback from the event listener |
251
+ | `closeWindow(window)` | `window`: Window | Promise\<void> | Closes the specified window and returns it to the pool |
252
+ | `closePool()` | None | Promise\<void> | Closes the window pool and exits the application |
253
+ | `mainloop()` | None | void | Starts the application main loop, blocking until the application exits |
254
+ | `onCustomMessage` | `(window: Window, data: string) => void` | None | Custom message callback, triggered when receiving custom messages from pages |
255
+
256
+ ### Window
257
+
258
+ | Method/Property | Parameters | Return Value | Description |
259
+ | ------------------------------------- | ------------------------------------------- | ---------------- | ---------------------------------------- |
260
+ | `loadURL(url)` | `url`: string — URL to load | Promise\<void> | Loads the specified URL |
261
+ | `loadHTML(html)` | `html`: string — HTML string | Promise\<void> | Loads the specified HTML content |
262
+ | `show()` | None | void | Shows the window |
263
+ | `hide()` | None | void | Hides the window |
264
+ | `maximize()` | None | void | Maximizes the window |
265
+ | `unMaximize()` | None | void | Restores the window (cancels maximize) |
266
+ | `minimize()` | None | void | Minimizes the window |
267
+ | `unMinimize()` | None | void | Restores the window (cancels minimize) |
268
+ | `close()` | None | void | Closes the window and returns to pool |
269
+ | `setTitle(title)` | `title`: string — Window title | void | Sets the window title |
270
+ | `setDecorated(isDecorated)` | `isDecorated`: boolean — Use system decorations | void | Sets whether the window has borders and title bar |
271
+ | `resizable(resizable)` | `resizable`: boolean — Resizable | void | Sets whether the window is resizable |
272
+ | `openDevTools()` | None | void | Opens developer tools |
273
+ | `closeDevTools()` | None | void | Closes developer tools |
274
+ | `id` | None | number | Unique window identifier, auto-incrementing |
275
+
276
+ ## Development
277
+
278
+ ```bash
279
+ pnpm install
280
+ pnpm run compile
281
+ ```
282
+
283
+ ## License
284
+
285
+ MIT License
package/index.d.ts CHANGED
@@ -1,41 +1,45 @@
1
- import { BrowserWindow, Webview } from "@webviewjs/webview";
2
- declare class Window {
3
- window: BrowserWindow;
4
- webview: Webview;
5
- isOpen: boolean;
6
- isShow: boolean;
7
- isDecorated: boolean;
8
- id: number;
9
- private myPool;
10
- constructor(window: BrowserWindow, webview: Webview, id: number, myPool: WindowPool);
11
- setDecorated(isDecorated: boolean): void;
12
- setTitle(title: string): void;
13
- resizable(resizable: boolean): void;
14
- maximize(): void;
15
- minimize(): void;
16
- unMaximize(): void;
17
- unMinimize(): void;
18
- openDevTools(): void;
19
- closeDevTools(): void;
20
- hide(): void;
21
- show(): void;
22
- close(): void;
23
- loadURL(url: string): Promise<void>;
24
- loadHTML(html: string): Promise<void>;
25
- }
26
- declare class WindowPool {
27
- onCustomMessage: (window: Window, data: string) => void;
28
- private app;
29
- private windows;
30
- private windowCount;
31
- private freeWindowCount;
32
- constructor(WindowsWebview2UserDataFolder?: string);
33
- __injectCode(window: Window, code: string): Promise<void>;
34
- __injectControlFunctions(windowObj: Window): Promise<void>;
35
- __createNewWindowObj(): Promise<Window>;
36
- createWindow(isShow?: boolean, isDecorated?: boolean): Promise<Window>;
37
- closeWindow(window: Window): Promise<void>;
38
- closePool(): Promise<void>;
39
- mainloop(): void;
40
- }
41
- export { WindowPool, Window };
1
+ import { BrowserWindow, Webview } from "@webviewjs/webview";
2
+ declare class Window {
3
+ window: BrowserWindow;
4
+ webview: Webview;
5
+ isOpen: boolean;
6
+ isShow: boolean;
7
+ isDecorated: boolean;
8
+ id: number;
9
+ private myPool;
10
+ constructor(window: BrowserWindow, webview: Webview, id: number, myPool: WindowPool);
11
+ setDecorated(isDecorated: boolean): void;
12
+ setTitle(title: string): void;
13
+ resizable(resizable: boolean): void;
14
+ maximize(): void;
15
+ minimize(): void;
16
+ unMaximize(): void;
17
+ unMinimize(): void;
18
+ openDevTools(): void;
19
+ closeDevTools(): void;
20
+ hide(): void;
21
+ show(): void;
22
+ close(): void;
23
+ loadURL(url: string): Promise<void>;
24
+ loadHTML(html: string): Promise<void>;
25
+ }
26
+ declare class WindowPool {
27
+ onCustomMessage: (window: Window, data: string) => void;
28
+ private app;
29
+ private windows;
30
+ private handlers;
31
+ private injectCount;
32
+ private windowCount;
33
+ private freeWindowCount;
34
+ constructor(WindowsWebview2UserDataFolder?: string);
35
+ __injectCode(window: Window, code: string): Promise<void>;
36
+ __injectControlFunctions(windowObj: Window): Promise<void>;
37
+ __createNewWindowObj(): Promise<Window>;
38
+ createWindow(isShow?: boolean, isDecorated?: boolean): Promise<Window>;
39
+ closeWindow(window: Window): Promise<void>;
40
+ closePool(): Promise<void>;
41
+ handle(event: string, callback: (data: any) => any): Promise<void>;
42
+ unhandle(event: string, callback: (data: any) => any): Promise<void>;
43
+ mainloop(): void;
44
+ }
45
+ export { WindowPool, Window };
package/index.js CHANGED
@@ -73,6 +73,8 @@ class WindowPool {
73
73
  onCustomMessage;
74
74
  app;
75
75
  windows;
76
+ handlers;
77
+ injectCount;
76
78
  windowCount;
77
79
  freeWindowCount;
78
80
  constructor(WindowsWebview2UserDataFolder = path.join(process.env.LOCALAPPDATA || os.homedir(), 'NexfepDevelopment.webview2-data')) {
@@ -88,7 +90,9 @@ class WindowPool {
88
90
  this.onCustomMessage = (window, data) => {
89
91
  console.log('Get Custom Message:', data, "from window", window.id);
90
92
  };
93
+ this.handlers = new Map();
91
94
  this.app = new Application();
95
+ this.injectCount = 0;
92
96
  this.windows = [];
93
97
  this.windowCount = 0;
94
98
  this.freeWindowCount = 0;
@@ -182,6 +186,23 @@ class WindowPool {
182
186
  const MessageBody = { type: 'CustomMessage', data: data }
183
187
  window.ipc.postMessage(JSON.stringify(MessageBody));
184
188
  };
189
+
190
+ window.eventCount = 0;
191
+
192
+ window.invoke = async (event, data) => {
193
+ const MessageBody = { type: 'NexfepInvoke', eventId: [${this.injectCount}, ++window.eventCount], event: event, data: data }
194
+ window.ipc.postMessage(JSON.stringify(MessageBody));
195
+ return new Promise((resolve, reject) => {
196
+ window.addEventListener("nexfep-invoke-result-"+${this.injectCount}+"-"+window.eventCount, (event) => {
197
+ window.removeEventListener("nexfep-invoke-result-"+${this.injectCount}+"-"+window.eventCount, event);
198
+ if(event.detail){
199
+ resolve(event.detail);
200
+ }else{
201
+ resolve();
202
+ }
203
+ });
204
+ });
205
+ }
185
206
 
186
207
  // 注入 CSS 样式
187
208
  const style = document.createElement('style');
@@ -247,6 +268,22 @@ class WindowPool {
247
268
  else if (dataObj.type == 'CustomMessage') {
248
269
  this.onCustomMessage(windowObj, dataObj.data);
249
270
  }
271
+ else if (dataObj.type == 'NexfepInvoke') {
272
+ const handlers = this.handlers.get(dataObj.event) || [];
273
+ handlers.forEach(async (handler) => {
274
+ const result = await handler(dataObj.data);
275
+ if (result) {
276
+ webview.evaluateScript(`
277
+ window.dispatchEvent(new Event('nexfep-invoke-result-${dataObj.eventId[0]}-${dataObj.eventId[1]}', { detail: ${JSON.stringify(result)} }));
278
+ `);
279
+ }
280
+ else {
281
+ webview.evaluateScript(`
282
+ window.dispatchEvent(new Event('nexfep-invoke-result-${dataObj.eventId[0]}-${dataObj.eventId[1]}', { detail: undefined }));
283
+ `);
284
+ }
285
+ });
286
+ }
250
287
  });
251
288
  return windowObj;
252
289
  }
@@ -282,9 +319,14 @@ class WindowPool {
282
319
  async closePool() {
283
320
  this.app.exit();
284
321
  }
322
+ async handle(event, callback) {
323
+ this.handlers.set(event, [...this.handlers.get(event) || [], callback]);
324
+ }
325
+ async unhandle(event, callback) {
326
+ this.handlers.set(event, (this.handlers.get(event) || []).filter(c => c !== callback));
327
+ }
285
328
  mainloop() {
286
329
  this.app.run();
287
330
  }
288
331
  }
289
332
  export { WindowPool, Window };
290
- //# sourceMappingURL=index.js.map
package/package.json CHANGED
@@ -1,37 +1,37 @@
1
- {
2
- "name": "nexfep",
3
- "description": "A desktop application framework based on @webviewjs/webview",
4
- "repository": "https://github.com/zhuxiaojt/Nexfep",
5
- "homepage": "https://github.com/zhuxiaojt/Nexfep#readme",
6
- "bugs": {
7
- "url": "https://github.com/zhuxiaojt/Nexfep/issues"
8
- },
9
- "keywords": [
10
- "desktop",
11
- "application",
12
- "framework",
13
- "@webviewjs/webview",
14
- "webview",
15
- "typescript"
16
- ],
17
- "version": "0.0.4",
18
- "type": "module",
19
- "packageManager": "pnpm@9.15.9",
20
- "main": "./index.js",
21
- "scripts": {
22
- "compile": "tsc"
23
- },
24
- "author": "nexfteam",
25
- "license": "MIT",
26
- "engines": {
27
- "node": ">=20.11.0"
28
- },
29
- "dependencies": {
30
- "@webviewjs/webview": "^0.1.0"
31
- },
32
- "devDependencies": {
33
- "@types/node": "^22.0.0",
34
- "tsx": "^4.0.0",
35
- "typescript": "^5.0.0"
36
- }
1
+ {
2
+ "name": "nexfep",
3
+ "description": "A desktop application framework based on @webviewjs/webview",
4
+ "repository": "https://github.com/nexfteam/Nexfep",
5
+ "homepage": "https://github.com/nexfteam/Nexfep#readme",
6
+ "bugs": {
7
+ "url": "https://github.com/nexfteam/Nexfep/issues"
8
+ },
9
+ "keywords": [
10
+ "desktop",
11
+ "application",
12
+ "framework",
13
+ "@webviewjs/webview",
14
+ "webview",
15
+ "typescript"
16
+ ],
17
+ "version": "0.1.1",
18
+ "type": "module",
19
+ "packageManager": "pnpm@9.15.9",
20
+ "main": "./index.js",
21
+ "scripts": {
22
+ "compile": "tsc"
23
+ },
24
+ "author": "nexfteam",
25
+ "license": "MIT",
26
+ "engines": {
27
+ "node": ">=20.11.0"
28
+ },
29
+ "dependencies": {
30
+ "@webviewjs/webview": "^0.1.0"
31
+ },
32
+ "devDependencies": {
33
+ "@types/node": "^22.0.0",
34
+ "tsx": "^4.0.0",
35
+ "typescript": "^5.0.0"
36
+ }
37
37
  }