rust-rpa 0.2.2 → 0.2.4

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.md CHANGED
@@ -10,7 +10,8 @@
10
10
  - ⚡ **非阻塞**: 异步操作不会阻塞 Node.js 事件循环
11
11
  - 🔒 **类型安全**: 完整的 TypeScript 类型定义
12
12
  - 🖱️ **输入自动化**: Mouse 和 Keyboard 类,完整的输入控制
13
- - 🪟 **窗口管理**: 基于 XCap 实现窗口枚举和信息获取
13
+ - 📑 **窗口管理**: 基于 XCap 实现窗口枚举和信息获取
14
+ - 👁️ **窗口内容监听**: `Window.watchChanges()` 降采样差异检测,内容变化时再截图,低开销监听 UI 变化
14
15
  - 🖥️ **多显示器支持**: Monitor 类,支持多显示器设置
15
16
  - 📸 **屏幕截图**: 基于 XCap 实现全屏和窗口截图,多种图片格式(PNG/JPEG/BMP)
16
17
  - 🔑 **权限管理**: Permission 类,自动检测并弹出系统权限授权对话框
@@ -121,11 +122,13 @@ rpa pause 1000
121
122
  - `image-processing-demo.js` - 图像处理功能演示
122
123
  - `find-icon-demo.js` - 完整的 findIcon 功能演示
123
124
  - `find-icon-basic.js` - findIcon 基础用法示例
125
+ - `window-watch-changes-demo.js` - 监听窗口内容变化(`watchChanges`),可选 `chrome` / `ding` / `qianniu`
124
126
 
125
127
  运行示例:
126
128
  ```bash
127
129
  node examples/permission-demo.js
128
130
  node examples/list-windows.js
131
+ node examples/window-watch-changes-demo.js chrome
129
132
  ```
130
133
 
131
134
  ## 使用方法
@@ -202,6 +205,7 @@ main();
202
205
  - `setBounds(bounds)` - 设置窗口边界
203
206
  - `toJSON()` - 转为 JSON 对象
204
207
  - `captureImage(options?)` - 截图
208
+ - `watchChanges(options?, callback)` - 监听窗口内容变化;返回 `WindowWatcher`(`stop()` / `isRunning()`),回调收到变化后的 `ImageData` 或 `null`(见 `sendImage` 选项)
205
209
  - `recognizeText(options?)` - OCR 识别文字
206
210
  - `findText(text, options?)` - 查找文字
207
211
  - `findIcon(template, options?)` - 查找图标
@@ -587,6 +591,18 @@ if (targetWindow) {
587
591
 
588
592
  ## 更新日志
589
593
 
594
+ ### 0.2.4
595
+
596
+ #### 新功能
597
+
598
+ - **Window.watchChanges(窗口内容变化监听)**: 后台线程降采样对比相邻帧,超过阈值才截取完整窗口图并回调;支持 `threshold`、`from`(`window`/`screen`)、`region`、`captureSize`、`sendImage`;返回 `WindowWatcher` 可 `stop()`。
599
+
600
+ ### 0.2.3
601
+
602
+ #### 修复
603
+
604
+ - **OCR `recognizeText` 多区域识别修复**: 修复了 `recognizeText` 在指定多个 `regions` 时坐标转换错误的问题
605
+
590
606
  ### 0.2.2
591
607
 
592
608
  #### 新功能
package/index.d.ts CHANGED
@@ -237,6 +237,35 @@ export interface CaptureImageOptions {
237
237
  */
238
238
  writeFilePath?: string | null
239
239
  }
240
+ /** 截图目标尺寸(用于窗口变化监听) */
241
+ export interface CaptureSizeJs {
242
+ /** 目标宽度(像素) */
243
+ width: number
244
+ /** 目标高度(像素) */
245
+ height: number
246
+ }
247
+ /** 窗口变化监听的选项 */
248
+ export interface WindowWatchOptionsJs {
249
+ /** 变化检测的灵敏度阈值 (0.0-1.0),默认 0.02 */
250
+ threshold?: number
251
+ /** 图片来源:'window'(默认)或 'screen' */
252
+ from?: 'window' | 'screen'
253
+ /** 仅在指定区域检测变化(逻辑像素) */
254
+ region?: CaptureRegion | null
255
+ /** 检测到变化后传递给回调的截图目标尺寸 */
256
+ captureSize?: CaptureSizeJs | null
257
+ /** 是否在回调中传递截图图像,默认 true */
258
+ sendImage?: boolean
259
+ }
260
+ /** 窗口内容变化监听的回调函数签名 */
261
+ export type WindowChangeCallback = (image: ImageData | null) => void
262
+ /** 窗口变化监听器句柄,用于停止监听 */
263
+ export interface WindowWatcher {
264
+ /** 停止监听,释放底层资源 */
265
+ stop(): void
266
+ /** 检查是否仍在运行 */
267
+ isRunning(): boolean
268
+ }
240
269
  /** 窗口尺寸信息 */
241
270
  export interface WindowSize {
242
271
  /** 窗口宽度 */
@@ -1248,6 +1277,64 @@ export declare class Window {
1248
1277
  * ```
1249
1278
  */
1250
1279
  clickIcon(template: ImageData, options?: WindowWaitOptions | null): Promise<ClickResult>
1280
+ /**
1281
+ * 监听窗口内容变化,当检测到变化时自动截取最新截图并传递给回调函数
1282
+ *
1283
+ * 底层使用降采样差异检测,仅在窗口内容发生变化时才截取完整图像,
1284
+ * 资源开销远低于定时轮询截图。
1285
+ *
1286
+ * @param options 监听选项(可选)
1287
+ * @param callback 变化时的回调函数,sendImage=true 时接收 ImageData,否则接收 null
1288
+ * @returns WindowWatcher 句柄,调用 stop() 可停止监听
1289
+ *
1290
+ * @example
1291
+ * ```javascript
1292
+ * // 场景 1:需要获取变化后的截图
1293
+ * const watcher = targetWindow.watchChanges(
1294
+ * { threshold: 0.02, from: 'window' },
1295
+ * (image) => {
1296
+ * console.log(`窗口变化,新截图: ${image.width}x${image.height}`);
1297
+ * sendToExternalService(image);
1298
+ * }
1299
+ * );
1300
+ * ```
1301
+ *
1302
+ * @example
1303
+ * ```javascript
1304
+ * // 场景 2:只需要知道窗口有变化,不需要截图(更低开销)
1305
+ * const watcher = targetWindow.watchChanges(
1306
+ * { sendImage: false },
1307
+ * (image) => {
1308
+ * console.log('窗口内容发生了变化');
1309
+ * onWindowChanged();
1310
+ * }
1311
+ * );
1312
+ * ```
1313
+ *
1314
+ * @example
1315
+ * ```javascript
1316
+ * // 场景 3:仅监听窗口的特定区域
1317
+ * const watcher = targetWindow.watchChanges(
1318
+ * {
1319
+ * region: { x: 100, y: 200, width: 400, height: 300 },
1320
+ * captureSize: { width: 800, height: 600 },
1321
+ * sendImage: true
1322
+ * },
1323
+ * (image) => {
1324
+ * processScreenshot(image);
1325
+ * }
1326
+ * );
1327
+ *
1328
+ * // 停止监听
1329
+ * setTimeout(() => {
1330
+ * watcher.stop();
1331
+ * }, 60000);
1332
+ * ```
1333
+ */
1334
+ watchChanges(
1335
+ options: WindowWatchOptionsJs | null | undefined,
1336
+ callback: WindowChangeCallback
1337
+ ): WindowWatcher
1251
1338
  }
1252
1339
  /** Clipboard 类 - 剪贴板控制 */
1253
1340
  export declare class Clipboard {
package/index.js CHANGED
@@ -10,12 +10,24 @@ const { join } = require('path')
10
10
  // 自动设置 OCR 模型路径,指向包内的 models/ 目录
11
11
  // 优先使用用户自定义路径(通过环境变量 RPA_OCR_MODELS),否则使用包内路径
12
12
  if (!process.env.RPA_OCR_MODELS) {
13
- const packageModelsDir = join(__dirname, 'models')
14
- if (existsSync(packageModelsDir)) {
15
- process.env.RPA_OCR_MODELS = packageModelsDir
13
+ // electron打包后路径
14
+ const dirs = process.resourcesPath ? [
15
+ join(process.resourcesPath, 'app.asar.unpacked', 'node_modules', 'rust-rpa', 'models'),
16
+ // 备用路径:app/node_modules/rust-rpa/models
17
+ join(process.resourcesPath, 'app', 'node_modules', 'rust-rpa', 'models'),
18
+ join(process.resourcesPath, 'node_modules', 'rust-rpa', 'models'),
19
+ ] : [];
20
+ dirs.push(join(process.cwd(), 'node_modules', 'rust-rpa', 'models'))
21
+ dirs.push(join(__dirname, 'models'));
22
+ for (const dir of dirs) {
23
+ if (existsSync(dir)) {
24
+ process.env.RPA_OCR_MODELS = dir
25
+ break
26
+ }
16
27
  }
17
28
  }
18
29
 
30
+
19
31
  const { platform, arch } = process
20
32
 
21
33
  let nativeBinding = null
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rust-rpa",
3
- "version": "0.2.2",
3
+ "version": "0.2.4",
4
4
  "description": "Rust-based RPA automation library for Node.js",
5
5
  "type": "commonjs",
6
6
  "main": "index.js",
@@ -67,9 +67,9 @@
67
67
  "commander": "^14.0.3"
68
68
  },
69
69
  "optionalDependencies": {
70
- "@alibot/rust-rpa-win32-x64-msvc": "0.2.2",
71
- "@alibot/rust-rpa-win32-ia32-msvc": "0.2.2",
72
- "@alibot/rust-rpa-darwin-x64": "0.2.2",
73
- "@alibot/rust-rpa-darwin-arm64": "0.2.2"
70
+ "@alibot/rust-rpa-win32-x64-msvc": "0.2.4",
71
+ "@alibot/rust-rpa-win32-ia32-msvc": "0.2.4",
72
+ "@alibot/rust-rpa-darwin-x64": "0.2.4",
73
+ "@alibot/rust-rpa-darwin-arm64": "0.2.4"
74
74
  }
75
75
  }