@elizaos/plugin-vision 2.0.0-beta.1 → 2.0.3-beta.5
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/LICENSE +21 -0
- package/README.md +73 -301
- package/dist/action.d.ts +3 -0
- package/dist/action.d.ts.map +1 -0
- package/dist/audio-capture-stream.d.ts +42 -0
- package/dist/audio-capture-stream.d.ts.map +1 -0
- package/dist/audio-capture.d.ts +25 -0
- package/dist/audio-capture.d.ts.map +1 -0
- package/dist/computeruse-ocr-bridge.d.ts +50 -0
- package/dist/computeruse-ocr-bridge.d.ts.map +1 -0
- package/dist/config.d.ts +68 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/describe-backpressure.d.ts +90 -0
- package/dist/describe-backpressure.d.ts.map +1 -0
- package/dist/dirty-tile-describer.d.ts +102 -0
- package/dist/dirty-tile-describer.d.ts.map +1 -0
- package/dist/dirty-tile-scene.d.ts +56 -0
- package/dist/dirty-tile-scene.d.ts.map +1 -0
- package/dist/entity-tracker.d.ts +33 -0
- package/dist/entity-tracker.d.ts.map +1 -0
- package/dist/face-detector-ggml.d.ts +60 -0
- package/dist/face-detector-ggml.d.ts.map +1 -0
- package/dist/face-detector-mediapipe.d.ts +25 -0
- package/dist/face-detector-mediapipe.d.ts.map +1 -0
- package/dist/face-recognition-ggml.d.ts +94 -0
- package/dist/face-recognition-ggml.d.ts.map +1 -0
- package/dist/get-screen-elements.d.ts +90 -0
- package/dist/get-screen-elements.d.ts.map +1 -0
- package/dist/get-screen.d.ts +60 -0
- package/dist/get-screen.d.ts.map +1 -0
- package/dist/image/sharp-compat.d.ts +89 -0
- package/dist/image/sharp-compat.d.ts.map +1 -0
- package/dist/image-input.d.ts +15 -0
- package/dist/image-input.d.ts.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +7957 -6238
- package/dist/index.js.map +41 -26
- package/dist/lifecycle.d.ts +94 -0
- package/dist/lifecycle.d.ts.map +1 -0
- package/dist/mobile/capacitor-camera.d.ts +85 -0
- package/dist/mobile/capacitor-camera.d.ts.map +1 -0
- package/dist/native/doctr-ffi.d.ts +40 -0
- package/dist/native/doctr-ffi.d.ts.map +1 -0
- package/dist/native/yolo-ffi.d.ts +21 -0
- package/dist/native/yolo-ffi.d.ts.map +1 -0
- package/dist/ocr-host-windows.d.ts +34 -0
- package/dist/ocr-host-windows.d.ts.map +1 -0
- package/dist/ocr-service-apple-vision-macos.d.ts +51 -0
- package/dist/ocr-service-apple-vision-macos.d.ts.map +1 -0
- package/dist/ocr-service-doctr.d.ts +61 -0
- package/dist/ocr-service-doctr.d.ts.map +1 -0
- package/dist/ocr-service-linux-tesseract.d.ts +85 -0
- package/dist/ocr-service-linux-tesseract.d.ts.map +1 -0
- package/dist/ocr-service-paddleocr.d.ts +59 -0
- package/dist/ocr-service-paddleocr.d.ts.map +1 -0
- package/dist/ocr-service-windows.d.ts +41 -0
- package/dist/ocr-service-windows.d.ts.map +1 -0
- package/dist/ocr-service.d.ts +91 -0
- package/dist/ocr-service.d.ts.map +1 -0
- package/dist/ocr-with-coords.d.ts +103 -0
- package/dist/ocr-with-coords.d.ts.map +1 -0
- package/dist/person-detector.d.ts +17 -0
- package/dist/person-detector.d.ts.map +1 -0
- package/dist/provider.d.ts +3 -0
- package/dist/provider.d.ts.map +1 -0
- package/dist/routes.d.ts +7 -0
- package/dist/routes.d.ts.map +1 -0
- package/dist/screen-capture-bridge.d.ts +51 -0
- package/dist/screen-capture-bridge.d.ts.map +1 -0
- package/dist/screen-capture.d.ts +17 -0
- package/dist/screen-capture.d.ts.map +1 -0
- package/dist/screen-tiler.d.ts +75 -0
- package/dist/screen-tiler.d.ts.map +1 -0
- package/dist/service.d.ts +176 -0
- package/dist/service.d.ts.map +1 -0
- package/dist/set-of-marks-provider.d.ts +64 -0
- package/dist/set-of-marks-provider.d.ts.map +1 -0
- package/dist/som.d.ts +135 -0
- package/dist/som.d.ts.map +1 -0
- package/dist/som.js +184 -0
- package/dist/som.js.map +11 -0
- package/dist/test-input.d.ts +25 -0
- package/dist/test-input.d.ts.map +1 -0
- package/dist/types.d.ts +241 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/vision-context-augmenter.d.ts +93 -0
- package/dist/vision-context-augmenter.d.ts.map +1 -0
- package/dist/vision-worker-manager.d.ts +51 -0
- package/dist/vision-worker-manager.d.ts.map +1 -0
- package/dist/workers/ocr-worker.d.ts +2 -0
- package/dist/workers/ocr-worker.d.ts.map +1 -0
- package/dist/workers/ocr-worker.js +1075 -7821
- package/dist/workers/ocr-worker.js.map +10 -51
- package/dist/workers/screen-capture-worker.d.ts +2 -0
- package/dist/workers/screen-capture-worker.d.ts.map +1 -0
- package/dist/workers/screen-capture-worker.js +364 -6
- package/dist/workers/screen-capture-worker.js.map +5 -4
- package/dist/workers/worker-logger.d.ts +10 -0
- package/dist/workers/worker-logger.d.ts.map +1 -0
- package/dist/yolo-detector.d.ts +37 -0
- package/dist/yolo-detector.d.ts.map +1 -0
- package/native/doctr.cpp/CMakeLists.txt +58 -0
- package/native/doctr.cpp/README.md +62 -0
- package/native/doctr.cpp/include/doctr.h +91 -0
- package/native/doctr.cpp/scripts/convert.py +98 -0
- package/native/doctr.cpp/src/doctr_det.cpp +112 -0
- package/native/doctr.cpp/src/doctr_rec.cpp +103 -0
- package/native/macos-vision-ocr.swift +113 -0
- package/native/mobilefacenet.cpp/README.md +13 -0
- package/native/movenet.cpp/README.md +10 -0
- package/native/retinaface.cpp/README.md +12 -0
- package/native/yolo.cpp/CMakeLists.txt +57 -0
- package/native/yolo.cpp/README.md +64 -0
- package/native/yolo.cpp/build.mjs +76 -0
- package/native/yolo.cpp/include/yolo.h +62 -0
- package/native/yolo.cpp/scripts/convert.py +248 -0
- package/native/yolo.cpp/src/yolo.cpp +425 -0
- package/native/yolo.cpp/verify/compare.py +99 -0
- package/native/yolo.cpp/verify/make_ref.py +75 -0
- package/native/yolo.cpp/verify/run_ggml.mjs +78 -0
- package/native/yolo.cpp/verify/run_ts.mjs +26 -0
- package/package.json +39 -21
- package/registry-entry.json +43 -0
- package/scripts/vendor-tesseract-linux.mjs +177 -0
- package/build.config.ts +0 -89
- package/dist/workers/florence2-worker.js +0 -779
- package/dist/workers/florence2-worker.js.map +0 -13
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"screen-capture-worker.d.ts","sourceRoot":"","sources":["../../src/workers/screen-capture-worker.ts"],"names":[],"mappings":""}
|
|
@@ -28,7 +28,20 @@ var __toESM = (mod, isNodeMode, target) => {
|
|
|
28
28
|
cache.set(mod, to);
|
|
29
29
|
return to;
|
|
30
30
|
};
|
|
31
|
-
var
|
|
31
|
+
var __returnValue = (v) => v;
|
|
32
|
+
function __exportSetter(name, newValue) {
|
|
33
|
+
this[name] = __returnValue.bind(null, newValue);
|
|
34
|
+
}
|
|
35
|
+
var __export = (target, all) => {
|
|
36
|
+
for (var name in all)
|
|
37
|
+
__defProp(target, name, {
|
|
38
|
+
get: all[name],
|
|
39
|
+
enumerable: true,
|
|
40
|
+
configurable: true,
|
|
41
|
+
set: __exportSetter.bind(all, name)
|
|
42
|
+
});
|
|
43
|
+
};
|
|
44
|
+
var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
|
|
32
45
|
|
|
33
46
|
// src/workers/screen-capture-worker.ts
|
|
34
47
|
var import_node_child_process = require("node:child_process");
|
|
@@ -36,7 +49,352 @@ var fs = __toESM(require("node:fs/promises"));
|
|
|
36
49
|
var path = __toESM(require("node:path"));
|
|
37
50
|
var import_node_util = require("node:util");
|
|
38
51
|
var import_node_worker_threads2 = require("node:worker_threads");
|
|
39
|
-
|
|
52
|
+
|
|
53
|
+
// src/image/sharp-compat.ts
|
|
54
|
+
var import_node_zlib = require("node:zlib");
|
|
55
|
+
var import_jimp = require("jimp");
|
|
56
|
+
var cached = null;
|
|
57
|
+
async function getSharp() {
|
|
58
|
+
if (cached)
|
|
59
|
+
return cached;
|
|
60
|
+
try {
|
|
61
|
+
const mod = await import("sharp");
|
|
62
|
+
cached = mod.default;
|
|
63
|
+
} catch {
|
|
64
|
+
cached = createJimpShim();
|
|
65
|
+
}
|
|
66
|
+
return cached;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
class JimpSharpInstance {
|
|
70
|
+
load;
|
|
71
|
+
outputFormat = "png";
|
|
72
|
+
alphaMode = null;
|
|
73
|
+
constructor(load) {
|
|
74
|
+
this.load = load;
|
|
75
|
+
}
|
|
76
|
+
chain(next) {
|
|
77
|
+
const prev = this.load;
|
|
78
|
+
this.load = async () => next(await prev());
|
|
79
|
+
return this;
|
|
80
|
+
}
|
|
81
|
+
metadata() {
|
|
82
|
+
return this.load().then((b) => ({
|
|
83
|
+
width: b.width,
|
|
84
|
+
height: b.height,
|
|
85
|
+
channels: hasAlphaPixels(b) ? 4 : 3,
|
|
86
|
+
format: this.outputFormat === "raw" ? "raw" : this.outputFormat
|
|
87
|
+
}));
|
|
88
|
+
}
|
|
89
|
+
resize(width, height, options) {
|
|
90
|
+
const fit = options?.fit ?? "cover";
|
|
91
|
+
if (fit !== "fill") {
|
|
92
|
+
throw new Error(`[sharp-compat] resize fit "${fit}" is not supported by the pure-JS fallback (only "fill")`);
|
|
93
|
+
}
|
|
94
|
+
return this.chain((b) => {
|
|
95
|
+
const img = bitmapToJimp(b);
|
|
96
|
+
img.resize({ w: width, h: height });
|
|
97
|
+
return jimpToBitmap(img);
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
removeAlpha() {
|
|
101
|
+
this.alphaMode = "remove";
|
|
102
|
+
return this;
|
|
103
|
+
}
|
|
104
|
+
ensureAlpha() {
|
|
105
|
+
this.alphaMode = "ensure";
|
|
106
|
+
return this;
|
|
107
|
+
}
|
|
108
|
+
extract(region) {
|
|
109
|
+
return this.chain((b) => cropBitmap(b, region));
|
|
110
|
+
}
|
|
111
|
+
extend(options) {
|
|
112
|
+
const top = options.top ?? 0;
|
|
113
|
+
const bottom = options.bottom ?? 0;
|
|
114
|
+
const left = options.left ?? 0;
|
|
115
|
+
const right = options.right ?? 0;
|
|
116
|
+
const bg = options.background ?? { r: 0, g: 0, b: 0, alpha: 1 };
|
|
117
|
+
return this.chain((b) => padBitmap(b, top, bottom, left, right, bg));
|
|
118
|
+
}
|
|
119
|
+
trim() {
|
|
120
|
+
return this.chain((b) => trimBitmap(b));
|
|
121
|
+
}
|
|
122
|
+
clone() {
|
|
123
|
+
const prev = this.load;
|
|
124
|
+
const clone = new JimpSharpInstance(async () => {
|
|
125
|
+
const b = await prev();
|
|
126
|
+
return { data: Buffer.from(b.data), width: b.width, height: b.height };
|
|
127
|
+
});
|
|
128
|
+
clone.outputFormat = this.outputFormat;
|
|
129
|
+
clone.alphaMode = this.alphaMode;
|
|
130
|
+
return clone;
|
|
131
|
+
}
|
|
132
|
+
png() {
|
|
133
|
+
this.outputFormat = "png";
|
|
134
|
+
return this;
|
|
135
|
+
}
|
|
136
|
+
jpeg() {
|
|
137
|
+
this.outputFormat = "jpeg";
|
|
138
|
+
return this;
|
|
139
|
+
}
|
|
140
|
+
raw() {
|
|
141
|
+
this.outputFormat = "raw";
|
|
142
|
+
return this;
|
|
143
|
+
}
|
|
144
|
+
async toBuffer(options) {
|
|
145
|
+
const bitmap = await this.load();
|
|
146
|
+
if (this.outputFormat === "raw") {
|
|
147
|
+
const channels = this.rawChannels(bitmap);
|
|
148
|
+
const data2 = toRawChannels(bitmap, channels);
|
|
149
|
+
if (options?.resolveWithObject) {
|
|
150
|
+
return {
|
|
151
|
+
data: data2,
|
|
152
|
+
info: { width: bitmap.width, height: bitmap.height, channels }
|
|
153
|
+
};
|
|
154
|
+
}
|
|
155
|
+
return data2;
|
|
156
|
+
}
|
|
157
|
+
const dropAlpha = this.alphaMode === "remove";
|
|
158
|
+
let data;
|
|
159
|
+
if (this.outputFormat === "jpeg") {
|
|
160
|
+
const img = bitmapToJimp(bitmap);
|
|
161
|
+
const encoded = await img.getBuffer(import_jimp.JimpMime.jpeg);
|
|
162
|
+
data = Buffer.isBuffer(encoded) ? encoded : Buffer.from(encoded);
|
|
163
|
+
} else {
|
|
164
|
+
data = encodePng(bitmap, dropAlpha);
|
|
165
|
+
}
|
|
166
|
+
if (options?.resolveWithObject) {
|
|
167
|
+
return {
|
|
168
|
+
data,
|
|
169
|
+
info: {
|
|
170
|
+
width: bitmap.width,
|
|
171
|
+
height: bitmap.height,
|
|
172
|
+
channels: dropAlpha ? 3 : 4
|
|
173
|
+
}
|
|
174
|
+
};
|
|
175
|
+
}
|
|
176
|
+
return data;
|
|
177
|
+
}
|
|
178
|
+
rawChannels(bitmap) {
|
|
179
|
+
if (this.alphaMode === "remove")
|
|
180
|
+
return 3;
|
|
181
|
+
if (this.alphaMode === "ensure")
|
|
182
|
+
return 4;
|
|
183
|
+
return hasAlphaPixels(bitmap) ? 4 : 3;
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
function createJimpShim() {
|
|
187
|
+
return (input, options) => {
|
|
188
|
+
if (options?.raw) {
|
|
189
|
+
if (!input) {
|
|
190
|
+
throw new Error("[sharp-compat] raw input requires a pixel buffer");
|
|
191
|
+
}
|
|
192
|
+
const { width, height, channels } = options.raw;
|
|
193
|
+
const rgba = rawToRgba(toBuffer(input), width, height, channels);
|
|
194
|
+
return new JimpSharpInstance(async () => ({
|
|
195
|
+
data: rgba,
|
|
196
|
+
width,
|
|
197
|
+
height
|
|
198
|
+
}));
|
|
199
|
+
}
|
|
200
|
+
if (!input) {
|
|
201
|
+
throw new Error("[sharp-compat] an input buffer is required");
|
|
202
|
+
}
|
|
203
|
+
const encoded = toBuffer(input);
|
|
204
|
+
return new JimpSharpInstance(async () => {
|
|
205
|
+
const img = await import_jimp.Jimp.read(encoded);
|
|
206
|
+
return jimpToBitmap(img);
|
|
207
|
+
});
|
|
208
|
+
};
|
|
209
|
+
}
|
|
210
|
+
function toBuffer(input) {
|
|
211
|
+
return Buffer.isBuffer(input) ? input : Buffer.from(input);
|
|
212
|
+
}
|
|
213
|
+
function bitmapToJimp(bitmap) {
|
|
214
|
+
return import_jimp.Jimp.fromBitmap({
|
|
215
|
+
data: bitmap.data,
|
|
216
|
+
width: bitmap.width,
|
|
217
|
+
height: bitmap.height
|
|
218
|
+
});
|
|
219
|
+
}
|
|
220
|
+
function jimpToBitmap(img) {
|
|
221
|
+
const { data, width, height } = img.bitmap;
|
|
222
|
+
return { data: Buffer.from(data), width, height };
|
|
223
|
+
}
|
|
224
|
+
function hasAlphaPixels(bitmap) {
|
|
225
|
+
for (let i = 3;i < bitmap.data.length; i += 4) {
|
|
226
|
+
if (bitmap.data[i] !== 255)
|
|
227
|
+
return true;
|
|
228
|
+
}
|
|
229
|
+
return false;
|
|
230
|
+
}
|
|
231
|
+
function rawToRgba(data, width, height, channels) {
|
|
232
|
+
const pixels = width * height;
|
|
233
|
+
const out = Buffer.allocUnsafe(pixels * 4);
|
|
234
|
+
for (let p = 0;p < pixels; p++) {
|
|
235
|
+
const src = p * channels;
|
|
236
|
+
const dst = p * 4;
|
|
237
|
+
if (channels >= 3) {
|
|
238
|
+
out[dst] = data[src];
|
|
239
|
+
out[dst + 1] = data[src + 1];
|
|
240
|
+
out[dst + 2] = data[src + 2];
|
|
241
|
+
out[dst + 3] = channels >= 4 ? data[src + 3] : 255;
|
|
242
|
+
} else {
|
|
243
|
+
const gray = data[src];
|
|
244
|
+
out[dst] = gray;
|
|
245
|
+
out[dst + 1] = gray;
|
|
246
|
+
out[dst + 2] = gray;
|
|
247
|
+
out[dst + 3] = channels === 2 ? data[src + 1] : 255;
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
return out;
|
|
251
|
+
}
|
|
252
|
+
function toRawChannels(bitmap, channels) {
|
|
253
|
+
const pixels = bitmap.width * bitmap.height;
|
|
254
|
+
if (channels === 4) {
|
|
255
|
+
return Buffer.from(bitmap.data.subarray(0, pixels * 4));
|
|
256
|
+
}
|
|
257
|
+
const out = Buffer.allocUnsafe(pixels * 3);
|
|
258
|
+
for (let p = 0;p < pixels; p++) {
|
|
259
|
+
out[p * 3] = bitmap.data[p * 4];
|
|
260
|
+
out[p * 3 + 1] = bitmap.data[p * 4 + 1];
|
|
261
|
+
out[p * 3 + 2] = bitmap.data[p * 4 + 2];
|
|
262
|
+
}
|
|
263
|
+
return out;
|
|
264
|
+
}
|
|
265
|
+
var CRC_TABLE = (() => {
|
|
266
|
+
const table = new Uint32Array(256);
|
|
267
|
+
for (let n = 0;n < 256; n++) {
|
|
268
|
+
let c = n;
|
|
269
|
+
for (let k = 0;k < 8; k++) {
|
|
270
|
+
c = c & 1 ? 3988292384 ^ c >>> 1 : c >>> 1;
|
|
271
|
+
}
|
|
272
|
+
table[n] = c >>> 0;
|
|
273
|
+
}
|
|
274
|
+
return table;
|
|
275
|
+
})();
|
|
276
|
+
function crc32(buf) {
|
|
277
|
+
let crc = 4294967295;
|
|
278
|
+
for (let i = 0;i < buf.length; i++) {
|
|
279
|
+
crc = CRC_TABLE[(crc ^ buf[i]) & 255] ^ crc >>> 8;
|
|
280
|
+
}
|
|
281
|
+
return (crc ^ 4294967295) >>> 0;
|
|
282
|
+
}
|
|
283
|
+
function pngChunk(type, data) {
|
|
284
|
+
const len = Buffer.allocUnsafe(4);
|
|
285
|
+
len.writeUInt32BE(data.length, 0);
|
|
286
|
+
const typeBuf = Buffer.from(type, "ascii");
|
|
287
|
+
const crc = Buffer.allocUnsafe(4);
|
|
288
|
+
crc.writeUInt32BE(crc32(Buffer.concat([typeBuf, data])), 0);
|
|
289
|
+
return Buffer.concat([len, typeBuf, data, crc]);
|
|
290
|
+
}
|
|
291
|
+
function encodePng(bitmap, dropAlpha) {
|
|
292
|
+
const { width, height, data } = bitmap;
|
|
293
|
+
const channels = dropAlpha ? 3 : 4;
|
|
294
|
+
const stride = width * channels;
|
|
295
|
+
const rawWithFilters = Buffer.allocUnsafe((stride + 1) * height);
|
|
296
|
+
for (let y = 0;y < height; y++) {
|
|
297
|
+
const dstRow = y * (stride + 1);
|
|
298
|
+
rawWithFilters[dstRow] = 0;
|
|
299
|
+
if (dropAlpha) {
|
|
300
|
+
const srcRow = y * width * 4;
|
|
301
|
+
for (let x = 0;x < width; x++) {
|
|
302
|
+
const s = srcRow + x * 4;
|
|
303
|
+
const d = dstRow + 1 + x * 3;
|
|
304
|
+
rawWithFilters[d] = data[s];
|
|
305
|
+
rawWithFilters[d + 1] = data[s + 1];
|
|
306
|
+
rawWithFilters[d + 2] = data[s + 2];
|
|
307
|
+
}
|
|
308
|
+
} else {
|
|
309
|
+
const srcRow = y * stride;
|
|
310
|
+
data.copy(rawWithFilters, dstRow + 1, srcRow, srcRow + stride);
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
const ihdr = Buffer.allocUnsafe(13);
|
|
314
|
+
ihdr.writeUInt32BE(width, 0);
|
|
315
|
+
ihdr.writeUInt32BE(height, 4);
|
|
316
|
+
ihdr[8] = 8;
|
|
317
|
+
ihdr[9] = dropAlpha ? 2 : 6;
|
|
318
|
+
ihdr[10] = 0;
|
|
319
|
+
ihdr[11] = 0;
|
|
320
|
+
ihdr[12] = 0;
|
|
321
|
+
const signature = Buffer.from([137, 80, 78, 71, 13, 10, 26, 10]);
|
|
322
|
+
return Buffer.concat([
|
|
323
|
+
signature,
|
|
324
|
+
pngChunk("IHDR", ihdr),
|
|
325
|
+
pngChunk("IDAT", import_node_zlib.deflateSync(rawWithFilters)),
|
|
326
|
+
pngChunk("IEND", Buffer.alloc(0))
|
|
327
|
+
]);
|
|
328
|
+
}
|
|
329
|
+
function cropBitmap(bitmap, region) {
|
|
330
|
+
const { left, top, width, height } = region;
|
|
331
|
+
const out = Buffer.allocUnsafe(width * height * 4);
|
|
332
|
+
const srcStride = bitmap.width * 4;
|
|
333
|
+
for (let y = 0;y < height; y++) {
|
|
334
|
+
const srcRow = (top + y) * srcStride + left * 4;
|
|
335
|
+
bitmap.data.copy(out, y * width * 4, srcRow, srcRow + width * 4);
|
|
336
|
+
}
|
|
337
|
+
return { data: out, width, height };
|
|
338
|
+
}
|
|
339
|
+
function padBitmap(bitmap, top, bottom, left, right, bg) {
|
|
340
|
+
const newWidth = bitmap.width + left + right;
|
|
341
|
+
const newHeight = bitmap.height + top + bottom;
|
|
342
|
+
const out = Buffer.allocUnsafe(newWidth * newHeight * 4);
|
|
343
|
+
const alpha = bg.alpha === undefined ? 255 : Math.round(bg.alpha * 255);
|
|
344
|
+
for (let i = 0;i < out.length; i += 4) {
|
|
345
|
+
out[i] = bg.r;
|
|
346
|
+
out[i + 1] = bg.g;
|
|
347
|
+
out[i + 2] = bg.b;
|
|
348
|
+
out[i + 3] = alpha;
|
|
349
|
+
}
|
|
350
|
+
for (let y = 0;y < bitmap.height; y++) {
|
|
351
|
+
const srcRow = y * bitmap.width * 4;
|
|
352
|
+
const dstRow = ((y + top) * newWidth + left) * 4;
|
|
353
|
+
bitmap.data.copy(out, dstRow, srcRow, srcRow + bitmap.width * 4);
|
|
354
|
+
}
|
|
355
|
+
return { data: out, width: newWidth, height: newHeight };
|
|
356
|
+
}
|
|
357
|
+
function trimBitmap(bitmap) {
|
|
358
|
+
const { data, width, height } = bitmap;
|
|
359
|
+
const sameAsCorner = (x, y) => {
|
|
360
|
+
const i = (y * width + x) * 4;
|
|
361
|
+
return data[i] === data[0] && data[i + 1] === data[1] && data[i + 2] === data[2] && data[i + 3] === data[3];
|
|
362
|
+
};
|
|
363
|
+
let top = 0;
|
|
364
|
+
let bottom = height - 1;
|
|
365
|
+
let left = 0;
|
|
366
|
+
let right = width - 1;
|
|
367
|
+
const rowUniform = (y) => {
|
|
368
|
+
for (let x = 0;x < width; x++)
|
|
369
|
+
if (!sameAsCorner(x, y))
|
|
370
|
+
return false;
|
|
371
|
+
return true;
|
|
372
|
+
};
|
|
373
|
+
const colUniform = (x) => {
|
|
374
|
+
for (let y = 0;y < height; y++)
|
|
375
|
+
if (!sameAsCorner(x, y))
|
|
376
|
+
return false;
|
|
377
|
+
return true;
|
|
378
|
+
};
|
|
379
|
+
while (top < bottom && rowUniform(top))
|
|
380
|
+
top++;
|
|
381
|
+
while (bottom > top && rowUniform(bottom))
|
|
382
|
+
bottom--;
|
|
383
|
+
while (left < right && colUniform(left))
|
|
384
|
+
left++;
|
|
385
|
+
while (right > left && colUniform(right))
|
|
386
|
+
right--;
|
|
387
|
+
const newWidth = right - left + 1;
|
|
388
|
+
const newHeight = bottom - top + 1;
|
|
389
|
+
if (newWidth === width && newHeight === height)
|
|
390
|
+
return bitmap;
|
|
391
|
+
const out = Buffer.allocUnsafe(newWidth * newHeight * 4);
|
|
392
|
+
for (let y = 0;y < newHeight; y++) {
|
|
393
|
+
const srcRow = ((y + top) * width + left) * 4;
|
|
394
|
+
out.set(data.subarray(srcRow, srcRow + newWidth * 4), y * newWidth * 4);
|
|
395
|
+
}
|
|
396
|
+
return { data: out, width: newWidth, height: newHeight };
|
|
397
|
+
}
|
|
40
398
|
|
|
41
399
|
// src/workers/worker-logger.ts
|
|
42
400
|
var import_node_worker_threads = require("node:worker_threads");
|
|
@@ -192,8 +550,7 @@ class ScreenCaptureWorker {
|
|
|
192
550
|
} else if (platform === "win32") {
|
|
193
551
|
const { stdout } = await execAsync("wmic path Win32_DesktopMonitor get DeviceID,ScreenWidth,ScreenHeight /format:csv");
|
|
194
552
|
const displays = [];
|
|
195
|
-
const lines = stdout.trim().split(
|
|
196
|
-
`).slice(2);
|
|
553
|
+
const lines = stdout.trim().split(/\r?\n/u).slice(2);
|
|
197
554
|
lines.forEach((line, index) => {
|
|
198
555
|
const parts = line.split(",");
|
|
199
556
|
if (parts.length >= 4) {
|
|
@@ -282,7 +639,8 @@ class ScreenCaptureWorker {
|
|
|
282
639
|
try {
|
|
283
640
|
await this.captureScreenToFile(tempFile, display);
|
|
284
641
|
const imageBuffer = await fs.readFile(tempFile);
|
|
285
|
-
const
|
|
642
|
+
const sharp = await getSharp();
|
|
643
|
+
const image = sharp(imageBuffer);
|
|
286
644
|
const metadata = await image.metadata();
|
|
287
645
|
const width = metadata.width || display.width;
|
|
288
646
|
const height = metadata.height || display.height;
|
|
@@ -360,5 +718,5 @@ if (import_node_worker_threads2.parentPort) {
|
|
|
360
718
|
});
|
|
361
719
|
}
|
|
362
720
|
|
|
363
|
-
//# debugId=
|
|
721
|
+
//# debugId=AF506971058FC3D264756E2164756E21
|
|
364
722
|
//# sourceMappingURL=screen-capture-worker.js.map
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
|
-
"sources": ["../../src/workers/screen-capture-worker.ts", "../../src/workers/worker-logger.ts"],
|
|
3
|
+
"sources": ["../../src/workers/screen-capture-worker.ts", "../../src/image/sharp-compat.ts", "../../src/workers/worker-logger.ts"],
|
|
4
4
|
"sourcesContent": [
|
|
5
|
-
"import { exec } from \"node:child_process\";\nimport * as fs from \"node:fs/promises\";\nimport * as path from \"node:path\";\nimport { promisify } from \"node:util\";\nimport { parentPort, workerData } from \"node:worker_threads\";\nimport sharp from \"sharp\";\nimport { logger } from \"./worker-logger\";\n\nconst execAsync = promisify(exec);\n\ninterface WorkerConfig {\n displayIndex?: number;\n captureAllDisplays?: boolean;\n targetFPS?: number;\n sharedBufferSize: number;\n}\n\ninterface DisplayInfo {\n id: string;\n name: string;\n width: number;\n height: number;\n x: number;\n y: number;\n isPrimary?: boolean;\n}\n\nclass ScreenCaptureWorker {\n private config: WorkerConfig;\n private sharedBuffer: SharedArrayBuffer;\n private dataView: DataView;\n private atomicState: Int32Array;\n private isRunning = true;\n private frameCount = 0;\n private lastFPSReport = Date.now();\n private displays: DisplayInfo[] = [];\n private currentDisplayIndex = 0;\n\n // Atomic indices\n private readonly FRAME_ID_INDEX = 0;\n private readonly WRITE_LOCK_INDEX = 1;\n private readonly WIDTH_INDEX = 2;\n private readonly HEIGHT_INDEX = 3;\n private readonly DISPLAY_INDEX = 4;\n private readonly TIMESTAMP_INDEX = 5;\n private readonly DATA_OFFSET = 24; // 6 * 4 bytes for metadata\n\n constructor(config: WorkerConfig, sharedBuffer: SharedArrayBuffer) {\n this.config = config;\n this.sharedBuffer = sharedBuffer;\n this.dataView = new DataView(sharedBuffer);\n this.atomicState = new Int32Array(sharedBuffer, 0, 6);\n }\n\n async initialize(): Promise<void> {\n // Get display information\n this.displays = await this.getDisplays();\n\n if (this.displays.length === 0) {\n throw new Error(\"No displays found\");\n }\n\n // Set initial display\n if (\n this.config.displayIndex !== undefined &&\n this.config.displayIndex < this.displays.length\n ) {\n this.currentDisplayIndex = this.config.displayIndex;\n }\n\n logger.info(\n `[ScreenCaptureWorker] Initialized with ${this.displays.length} displays`,\n );\n this.displays.forEach((d, i) => {\n logger.info(\n ` Display ${i}: ${d.name} (${d.width}x${d.height}) ${d.isPrimary ? \"[PRIMARY]\" : \"\"}`,\n );\n });\n }\n\n private async getDisplays(): Promise<DisplayInfo[]> {\n const platform = process.platform;\n\n try {\n if (platform === \"darwin\") {\n // macOS: Use system_profiler\n const { stdout } = await execAsync(\n \"system_profiler SPDisplaysDataType -json\",\n );\n const data = JSON.parse(stdout);\n const displays: DisplayInfo[] = [];\n\n if (data.SPDisplaysDataType?.[0]) {\n const gpuInfo = data.SPDisplaysDataType[0];\n const items: Array<{ native_resolution?: string; _name?: string }> =\n gpuInfo._items || [];\n\n items.forEach((item, index) => {\n const resolution = item.native_resolution;\n if (resolution) {\n const match = resolution.match(/(\\d+) x (\\d+)/);\n if (match) {\n displays.push({\n id: `display-${index}`,\n name: item._name || `Display ${index + 1}`,\n width: parseInt(match[1], 10),\n height: parseInt(match[2], 10),\n x: 0,\n y: 0,\n isPrimary: index === 0,\n });\n }\n }\n });\n }\n\n return displays;\n } else if (platform === \"linux\") {\n // Linux: Use xrandr\n const { stdout } = await execAsync(\"xrandr --query\");\n const displays: DisplayInfo[] = [];\n const lines = stdout.split(\"\\n\");\n\n for (const line of lines) {\n if (line.includes(\" connected\")) {\n const match = line.match(\n /^(\\S+) connected (?:primary )?(\\d+)x(\\d+)\\+(\\d+)\\+(\\d+)/,\n );\n if (match) {\n displays.push({\n id: match[1],\n name: match[1],\n width: parseInt(match[2], 10),\n height: parseInt(match[3], 10),\n x: parseInt(match[4], 10),\n y: parseInt(match[5], 10),\n isPrimary: line.includes(\"primary\"),\n });\n }\n }\n }\n\n return displays;\n } else if (platform === \"win32\") {\n // Windows: Use wmic\n const { stdout } = await execAsync(\n \"wmic path Win32_DesktopMonitor get DeviceID,ScreenWidth,ScreenHeight /format:csv\",\n );\n const displays: DisplayInfo[] = [];\n const lines = stdout.trim().split(\"\\n\").slice(2); // Skip headers\n\n lines.forEach((line, index) => {\n const parts = line.split(\",\");\n if (parts.length >= 4) {\n const width = parseInt(parts[2], 10);\n const height = parseInt(parts[3], 10);\n if (!Number.isNaN(width) && !Number.isNaN(height)) {\n displays.push({\n id: parts[1],\n name: parts[1] || `Display ${index + 1}`,\n width,\n height,\n x: 0,\n y: 0,\n isPrimary: index === 0,\n });\n }\n }\n });\n\n return displays.length > 0\n ? displays\n : [\n {\n id: \"primary\",\n name: \"Primary Display\",\n width: 1920,\n height: 1080,\n x: 0,\n y: 0,\n isPrimary: true,\n },\n ];\n }\n } catch (error) {\n logger.error(\"[ScreenCaptureWorker] Failed to get display info:\", error);\n }\n\n // Fallback\n return [\n {\n id: \"default\",\n name: \"Default Display\",\n width: 1920,\n height: 1080,\n x: 0,\n y: 0,\n isPrimary: true,\n },\n ];\n }\n\n async run(): Promise<void> {\n await this.initialize();\n\n logger.info(\"[ScreenCaptureWorker] Starting capture loop...\");\n\n while (this.isRunning) {\n const startTime = Date.now();\n\n try {\n await this.captureFrame();\n this.frameCount++;\n\n // Report FPS every second\n const now = Date.now();\n if (now - this.lastFPSReport >= 1000) {\n const fps = this.frameCount / ((now - this.lastFPSReport) / 1000);\n logger.info(\n `[ScreenCaptureWorker] FPS: ${fps.toFixed(2)}, Display: ${this.currentDisplayIndex}`,\n );\n\n parentPort?.postMessage({\n type: \"fps\",\n fps,\n frameCount: this.frameCount,\n displayIndex: this.currentDisplayIndex,\n });\n\n this.frameCount = 0;\n this.lastFPSReport = now;\n }\n\n // Cycle through displays if configured\n if (this.config.captureAllDisplays && this.displays.length > 1) {\n this.currentDisplayIndex =\n (this.currentDisplayIndex + 1) % this.displays.length;\n }\n\n // Target FPS limiting\n if (this.config.targetFPS) {\n const frameTime = 1000 / this.config.targetFPS;\n const elapsed = Date.now() - startTime;\n if (elapsed < frameTime) {\n await new Promise((resolve) =>\n setTimeout(resolve, frameTime - elapsed),\n );\n }\n }\n } catch (error) {\n logger.error(\"[ScreenCaptureWorker] Capture error:\", error);\n await new Promise((resolve) => setTimeout(resolve, 100)); // Brief pause on error\n }\n }\n }\n\n private async captureFrame(): Promise<void> {\n const display = this.displays[this.currentDisplayIndex];\n const tempFile = path.join(\n process.cwd(),\n `temp_screen_${Date.now()}_${this.currentDisplayIndex}.png`,\n );\n\n try {\n // Capture the screen\n await this.captureScreenToFile(tempFile, display);\n\n // Load and process the image\n const imageBuffer = await fs.readFile(tempFile);\n const image = sharp(imageBuffer);\n const metadata = await image.metadata();\n\n const width = metadata.width || display.width;\n const height = metadata.height || display.height;\n\n // Convert to raw RGBA for shared buffer\n const rawData = await image.ensureAlpha().raw().toBuffer();\n\n // Wait for write lock\n while (\n Atomics.compareExchange(\n this.atomicState,\n this.WRITE_LOCK_INDEX,\n 0,\n 1,\n ) !== 0\n ) {\n // Spin wait - in practice this should be very brief\n }\n\n try {\n // Write metadata\n Atomics.store(this.atomicState, this.WIDTH_INDEX, width);\n Atomics.store(this.atomicState, this.HEIGHT_INDEX, height);\n Atomics.store(\n this.atomicState,\n this.DISPLAY_INDEX,\n this.currentDisplayIndex,\n );\n Atomics.store(this.atomicState, this.TIMESTAMP_INDEX, Date.now());\n\n // Write image data\n const maxDataSize = this.sharedBuffer.byteLength - this.DATA_OFFSET;\n const dataSize = Math.min(rawData.length, maxDataSize);\n\n for (let i = 0; i < dataSize; i++) {\n this.dataView.setUint8(this.DATA_OFFSET + i, rawData[i]);\n }\n\n // Update frame ID (signals new frame available)\n Atomics.add(this.atomicState, this.FRAME_ID_INDEX, 1);\n } finally {\n // Release write lock\n Atomics.store(this.atomicState, this.WRITE_LOCK_INDEX, 0);\n }\n\n // Clean up temp file\n await fs.unlink(tempFile).catch(() => {});\n } catch (error) {\n // Clean up temp file on error\n await fs.unlink(tempFile).catch(() => {});\n throw error;\n }\n }\n\n private async captureScreenToFile(\n outputPath: string,\n display: DisplayInfo,\n ): Promise<void> {\n const platform = process.platform;\n\n try {\n if (platform === \"darwin\") {\n // macOS: Use screencapture with display index\n const displayArg =\n this.currentDisplayIndex > 0\n ? `-D ${this.currentDisplayIndex + 1}`\n : \"\";\n await execAsync(`screencapture -x ${displayArg} \"${outputPath}\"`);\n } else if (platform === \"linux\") {\n // Linux: Use scrot with geometry for specific display\n if (display.x !== 0 || display.y !== 0) {\n // Multi-monitor setup\n await execAsync(\n `scrot -a ${display.x},${display.y},${display.width},${display.height} \"${outputPath}\"`,\n );\n } else {\n await execAsync(`scrot \"${outputPath}\"`);\n }\n } else if (platform === \"win32\") {\n // Windows: PowerShell script for specific monitor\n const script = `\n Add-Type -AssemblyName System.Windows.Forms;\n Add-Type -AssemblyName System.Drawing;\n $screens = [System.Windows.Forms.Screen]::AllScreens;\n $screen = $screens[${this.currentDisplayIndex}];\n $bounds = $screen.Bounds;\n $bitmap = New-Object System.Drawing.Bitmap $bounds.Width, $bounds.Height;\n $graphics = [System.Drawing.Graphics]::FromImage($bitmap);\n $graphics.CopyFromScreen($bounds.Location, [System.Drawing.Point]::Empty, $bounds.Size);\n $bitmap.Save('${outputPath.replace(/\\\\/g, \"\\\\\\\\\")}');\n $graphics.Dispose();\n $bitmap.Dispose();\n `;\n await execAsync(`powershell -Command \"${script.replace(/\\n/g, \" \")}\"`);\n }\n } catch (error) {\n const errorMessage =\n error instanceof Error ? error.message : String(error);\n throw new Error(`Screen capture failed: ${errorMessage}`);\n }\n }\n\n stop(): void {\n this.isRunning = false;\n }\n}\n\n// Worker entry point\nif (parentPort) {\n const { config, sharedBuffer } = workerData;\n const worker = new ScreenCaptureWorker(config, sharedBuffer);\n\n // Handle messages from main thread\n parentPort.on(\"message\", (msg) => {\n if (msg.type === \"stop\") {\n worker.stop();\n }\n });\n\n // Run the worker\n worker.run().catch((error) => {\n logger.error(\"[ScreenCaptureWorker] Fatal error:\", error);\n parentPort?.postMessage({ type: \"error\", error: error.message });\n process.exit(1);\n });\n}\n",
|
|
5
|
+
"import { exec } from \"node:child_process\";\nimport * as fs from \"node:fs/promises\";\nimport * as path from \"node:path\";\nimport { promisify } from \"node:util\";\nimport { parentPort, workerData } from \"node:worker_threads\";\nimport { getSharp } from \"../image/sharp-compat\";\nimport { logger } from \"./worker-logger\";\n\nconst execAsync = promisify(exec);\n\ninterface WorkerConfig {\n displayIndex?: number;\n captureAllDisplays?: boolean;\n targetFPS?: number;\n sharedBufferSize: number;\n}\n\ninterface DisplayInfo {\n id: string;\n name: string;\n width: number;\n height: number;\n x: number;\n y: number;\n isPrimary?: boolean;\n}\n\nclass ScreenCaptureWorker {\n private config: WorkerConfig;\n private sharedBuffer: SharedArrayBuffer;\n private dataView: DataView;\n private atomicState: Int32Array;\n private isRunning = true;\n private frameCount = 0;\n private lastFPSReport = Date.now();\n private displays: DisplayInfo[] = [];\n private currentDisplayIndex = 0;\n\n // Atomic indices\n private readonly FRAME_ID_INDEX = 0;\n private readonly WRITE_LOCK_INDEX = 1;\n private readonly WIDTH_INDEX = 2;\n private readonly HEIGHT_INDEX = 3;\n private readonly DISPLAY_INDEX = 4;\n private readonly TIMESTAMP_INDEX = 5;\n private readonly DATA_OFFSET = 24; // 6 * 4 bytes for metadata\n\n constructor(config: WorkerConfig, sharedBuffer: SharedArrayBuffer) {\n this.config = config;\n this.sharedBuffer = sharedBuffer;\n this.dataView = new DataView(sharedBuffer);\n this.atomicState = new Int32Array(sharedBuffer, 0, 6);\n }\n\n async initialize(): Promise<void> {\n // Get display information\n this.displays = await this.getDisplays();\n\n if (this.displays.length === 0) {\n throw new Error(\"No displays found\");\n }\n\n // Set initial display\n if (\n this.config.displayIndex !== undefined &&\n this.config.displayIndex < this.displays.length\n ) {\n this.currentDisplayIndex = this.config.displayIndex;\n }\n\n logger.info(\n `[ScreenCaptureWorker] Initialized with ${this.displays.length} displays`,\n );\n this.displays.forEach((d, i) => {\n logger.info(\n ` Display ${i}: ${d.name} (${d.width}x${d.height}) ${d.isPrimary ? \"[PRIMARY]\" : \"\"}`,\n );\n });\n }\n\n private async getDisplays(): Promise<DisplayInfo[]> {\n const platform = process.platform;\n\n try {\n if (platform === \"darwin\") {\n // macOS: Use system_profiler\n const { stdout } = await execAsync(\n \"system_profiler SPDisplaysDataType -json\",\n );\n const data = JSON.parse(stdout);\n const displays: DisplayInfo[] = [];\n\n if (data.SPDisplaysDataType?.[0]) {\n const gpuInfo = data.SPDisplaysDataType[0];\n const items: Array<{ native_resolution?: string; _name?: string }> =\n gpuInfo._items || [];\n\n items.forEach((item, index) => {\n const resolution = item.native_resolution;\n if (resolution) {\n const match = resolution.match(/(\\d+) x (\\d+)/);\n if (match) {\n displays.push({\n id: `display-${index}`,\n name: item._name || `Display ${index + 1}`,\n width: parseInt(match[1], 10),\n height: parseInt(match[2], 10),\n x: 0,\n y: 0,\n isPrimary: index === 0,\n });\n }\n }\n });\n }\n\n return displays;\n } else if (platform === \"linux\") {\n // Linux: Use xrandr\n const { stdout } = await execAsync(\"xrandr --query\");\n const displays: DisplayInfo[] = [];\n const lines = stdout.split(\"\\n\");\n\n for (const line of lines) {\n if (line.includes(\" connected\")) {\n const match = line.match(\n /^(\\S+) connected (?:primary )?(\\d+)x(\\d+)\\+(\\d+)\\+(\\d+)/,\n );\n if (match) {\n displays.push({\n id: match[1],\n name: match[1],\n width: parseInt(match[2], 10),\n height: parseInt(match[3], 10),\n x: parseInt(match[4], 10),\n y: parseInt(match[5], 10),\n isPrimary: line.includes(\"primary\"),\n });\n }\n }\n }\n\n return displays;\n } else if (platform === \"win32\") {\n // Windows: Use wmic\n const { stdout } = await execAsync(\n \"wmic path Win32_DesktopMonitor get DeviceID,ScreenWidth,ScreenHeight /format:csv\",\n );\n const displays: DisplayInfo[] = [];\n const lines = stdout.trim().split(/\\r?\\n/u).slice(2); // Skip headers\n\n lines.forEach((line, index) => {\n const parts = line.split(\",\");\n if (parts.length >= 4) {\n const width = parseInt(parts[2], 10);\n const height = parseInt(parts[3], 10);\n if (!Number.isNaN(width) && !Number.isNaN(height)) {\n displays.push({\n id: parts[1],\n name: parts[1] || `Display ${index + 1}`,\n width,\n height,\n x: 0,\n y: 0,\n isPrimary: index === 0,\n });\n }\n }\n });\n\n return displays.length > 0\n ? displays\n : [\n {\n id: \"primary\",\n name: \"Primary Display\",\n width: 1920,\n height: 1080,\n x: 0,\n y: 0,\n isPrimary: true,\n },\n ];\n }\n } catch (error) {\n logger.error(\"[ScreenCaptureWorker] Failed to get display info:\", error);\n }\n\n // Fallback\n return [\n {\n id: \"default\",\n name: \"Default Display\",\n width: 1920,\n height: 1080,\n x: 0,\n y: 0,\n isPrimary: true,\n },\n ];\n }\n\n async run(): Promise<void> {\n await this.initialize();\n\n logger.info(\"[ScreenCaptureWorker] Starting capture loop...\");\n\n while (this.isRunning) {\n const startTime = Date.now();\n\n try {\n await this.captureFrame();\n this.frameCount++;\n\n // Report FPS every second\n const now = Date.now();\n if (now - this.lastFPSReport >= 1000) {\n const fps = this.frameCount / ((now - this.lastFPSReport) / 1000);\n logger.info(\n `[ScreenCaptureWorker] FPS: ${fps.toFixed(2)}, Display: ${this.currentDisplayIndex}`,\n );\n\n parentPort?.postMessage({\n type: \"fps\",\n fps,\n frameCount: this.frameCount,\n displayIndex: this.currentDisplayIndex,\n });\n\n this.frameCount = 0;\n this.lastFPSReport = now;\n }\n\n // Cycle through displays if configured\n if (this.config.captureAllDisplays && this.displays.length > 1) {\n this.currentDisplayIndex =\n (this.currentDisplayIndex + 1) % this.displays.length;\n }\n\n // Target FPS limiting\n if (this.config.targetFPS) {\n const frameTime = 1000 / this.config.targetFPS;\n const elapsed = Date.now() - startTime;\n if (elapsed < frameTime) {\n await new Promise((resolve) =>\n setTimeout(resolve, frameTime - elapsed),\n );\n }\n }\n } catch (error) {\n logger.error(\"[ScreenCaptureWorker] Capture error:\", error);\n await new Promise((resolve) => setTimeout(resolve, 100)); // Brief pause on error\n }\n }\n }\n\n private async captureFrame(): Promise<void> {\n const display = this.displays[this.currentDisplayIndex];\n const tempFile = path.join(\n process.cwd(),\n `temp_screen_${Date.now()}_${this.currentDisplayIndex}.png`,\n );\n\n try {\n // Capture the screen\n await this.captureScreenToFile(tempFile, display);\n\n // Load and process the image\n const imageBuffer = await fs.readFile(tempFile);\n const sharp = await getSharp();\n const image = sharp(imageBuffer);\n const metadata = await image.metadata();\n\n const width = metadata.width || display.width;\n const height = metadata.height || display.height;\n\n // Convert to raw RGBA for shared buffer\n const rawData = await image.ensureAlpha().raw().toBuffer();\n\n // Wait for write lock\n while (\n Atomics.compareExchange(\n this.atomicState,\n this.WRITE_LOCK_INDEX,\n 0,\n 1,\n ) !== 0\n ) {\n // Spin wait - in practice this should be very brief\n }\n\n try {\n // Write metadata\n Atomics.store(this.atomicState, this.WIDTH_INDEX, width);\n Atomics.store(this.atomicState, this.HEIGHT_INDEX, height);\n Atomics.store(\n this.atomicState,\n this.DISPLAY_INDEX,\n this.currentDisplayIndex,\n );\n Atomics.store(this.atomicState, this.TIMESTAMP_INDEX, Date.now());\n\n // Write image data\n const maxDataSize = this.sharedBuffer.byteLength - this.DATA_OFFSET;\n const dataSize = Math.min(rawData.length, maxDataSize);\n\n for (let i = 0; i < dataSize; i++) {\n this.dataView.setUint8(this.DATA_OFFSET + i, rawData[i]);\n }\n\n // Update frame ID (signals new frame available)\n Atomics.add(this.atomicState, this.FRAME_ID_INDEX, 1);\n } finally {\n // Release write lock\n Atomics.store(this.atomicState, this.WRITE_LOCK_INDEX, 0);\n }\n\n // Clean up temp file\n await fs.unlink(tempFile).catch(() => {});\n } catch (error) {\n // Clean up temp file on error\n await fs.unlink(tempFile).catch(() => {});\n throw error;\n }\n }\n\n private async captureScreenToFile(\n outputPath: string,\n display: DisplayInfo,\n ): Promise<void> {\n const platform = process.platform;\n\n try {\n if (platform === \"darwin\") {\n // macOS: Use screencapture with display index\n const displayArg =\n this.currentDisplayIndex > 0\n ? `-D ${this.currentDisplayIndex + 1}`\n : \"\";\n await execAsync(`screencapture -x ${displayArg} \"${outputPath}\"`);\n } else if (platform === \"linux\") {\n // Linux: Use scrot with geometry for specific display\n if (display.x !== 0 || display.y !== 0) {\n // Multi-monitor setup\n await execAsync(\n `scrot -a ${display.x},${display.y},${display.width},${display.height} \"${outputPath}\"`,\n );\n } else {\n await execAsync(`scrot \"${outputPath}\"`);\n }\n } else if (platform === \"win32\") {\n // Windows: PowerShell script for specific monitor\n const script = `\n Add-Type -AssemblyName System.Windows.Forms;\n Add-Type -AssemblyName System.Drawing;\n $screens = [System.Windows.Forms.Screen]::AllScreens;\n $screen = $screens[${this.currentDisplayIndex}];\n $bounds = $screen.Bounds;\n $bitmap = New-Object System.Drawing.Bitmap $bounds.Width, $bounds.Height;\n $graphics = [System.Drawing.Graphics]::FromImage($bitmap);\n $graphics.CopyFromScreen($bounds.Location, [System.Drawing.Point]::Empty, $bounds.Size);\n $bitmap.Save('${outputPath.replace(/\\\\/g, \"\\\\\\\\\")}');\n $graphics.Dispose();\n $bitmap.Dispose();\n `;\n await execAsync(`powershell -Command \"${script.replace(/\\n/g, \" \")}\"`);\n }\n } catch (error) {\n const errorMessage =\n error instanceof Error ? error.message : String(error);\n throw new Error(`Screen capture failed: ${errorMessage}`);\n }\n }\n\n stop(): void {\n this.isRunning = false;\n }\n}\n\n// Worker entry point\nif (parentPort) {\n const { config, sharedBuffer } = workerData;\n const worker = new ScreenCaptureWorker(config, sharedBuffer);\n\n // Handle messages from main thread\n parentPort.on(\"message\", (msg) => {\n if (msg.type === \"stop\") {\n worker.stop();\n }\n });\n\n // Run the worker\n worker.run().catch((error) => {\n logger.error(\"[ScreenCaptureWorker] Fatal error:\", error);\n parentPort?.postMessage({ type: \"error\", error: error.message });\n process.exit(1);\n });\n}\n",
|
|
6
|
+
"// sharp-compat.ts — lazy sharp resolver + pure-JS fallback.\n//\n// plugin-vision is loadable on mobile (Android bun-musl) only if its module\n// graph does not pull native code at module-eval. `sharp` loads the libvips\n// native addon the moment it is imported, so every runtime call site goes\n// through `getSharp()` here, which imports `sharp` *dynamically* (inside the\n// function) and caches the resolved factory. On a host where the native\n// binary loads (desktop glibc/musl), that is real `sharp` and performance is\n// unchanged. Where it cannot load, `getSharp()` returns a pure-JS shim backed\n// by `jimp` (no native deps) that is API-compatible for exactly the operations\n// the codebase uses: metadata, resize{fit:\"fill\"}, removeAlpha, ensureAlpha,\n// extract, extend, trim, clone, png, jpeg, raw, toBuffer.\n//\n// The shim is not a general sharp reimplementation — it implements the subset\n// in `sharp-compat.test.ts`, which diffs shim output against native sharp.\n\nimport { deflateSync } from \"node:zlib\";\nimport { Jimp, JimpMime } from \"jimp\";\n\n/** Raw-pixel input descriptor (mirrors `sharp.SharpOptions[\"raw\"]`). */\nexport interface SharpRawInput {\n width: number;\n height: number;\n channels: 1 | 2 | 3 | 4;\n}\n\n/** Constructor options subset used by the codebase. */\nexport interface SharpFactoryOptions {\n raw?: SharpRawInput;\n limitInputPixels?: number | boolean;\n failOnError?: boolean;\n}\n\n/** `resize` options subset used by the codebase. */\nexport interface SharpResizeOptions {\n fit?: \"fill\" | \"contain\" | \"cover\" | \"inside\" | \"outside\";\n}\n\n/** RGBA background for `extend` (alpha is accepted but encoded outputs only). */\nexport interface SharpColor {\n r: number;\n g: number;\n b: number;\n alpha?: number;\n}\n\nexport interface SharpExtendOptions {\n top?: number;\n bottom?: number;\n left?: number;\n right?: number;\n background?: SharpColor;\n}\n\nexport interface SharpExtractRegion {\n left: number;\n top: number;\n width: number;\n height: number;\n}\n\n/** Subset of `sharp.Metadata` the codebase reads. */\nexport interface SharpMetadata {\n width?: number;\n height?: number;\n channels?: number;\n format?: string;\n}\n\nexport interface SharpRawInfo {\n width: number;\n height: number;\n channels: number;\n}\n\nexport interface SharpResolveWithObject {\n data: Buffer;\n info: SharpRawInfo;\n}\n\n/**\n * The chainable instance surface. This is structurally the subset of\n * `sharp.Sharp` the codebase touches, so a real `sharp` instance satisfies it\n * and call sites need no per-backend typing.\n */\nexport interface SharpInstance {\n metadata(): Promise<SharpMetadata>;\n resize(\n width: number,\n height: number,\n options?: SharpResizeOptions,\n ): SharpInstance;\n removeAlpha(): SharpInstance;\n ensureAlpha(): SharpInstance;\n extract(region: SharpExtractRegion): SharpInstance;\n extend(options: SharpExtendOptions): SharpInstance;\n trim(): SharpInstance;\n clone(): SharpInstance;\n png(): SharpInstance;\n jpeg(): SharpInstance;\n raw(): SharpInstance;\n toBuffer(): Promise<Buffer>;\n toBuffer(options: {\n resolveWithObject: true;\n }): Promise<SharpResolveWithObject>;\n}\n\n/** The callable factory surface (`sharp(input, options?)`). */\nexport type SharpFactory = (\n input?: Buffer | Uint8Array,\n options?: SharpFactoryOptions,\n) => SharpInstance;\n\nlet cached: SharpFactory | null = null;\n\n/**\n * Resolve the image backend. Tries native `sharp` first (dynamic import so the\n * native addon is never touched at module-eval); on any failure falls back to\n * the pure-JS jimp shim. The result is cached for the process lifetime.\n */\nexport async function getSharp(): Promise<SharpFactory> {\n if (cached) return cached;\n try {\n const mod = (await import(\"sharp\")) as { default: SharpFactory };\n cached = mod.default;\n } catch {\n cached = createJimpShim();\n }\n return cached;\n}\n\n// --- pure-JS shim ----------------------------------------------------------\n\ntype JimpImage = Awaited<ReturnType<typeof Jimp.read>>;\n\n/** A jimp bitmap is always row-major RGBA. */\ninterface Bitmap {\n data: Buffer;\n width: number;\n height: number;\n}\n\ntype OutputFormat = \"raw\" | \"png\" | \"jpeg\";\n\n/**\n * Deferred operation chain. jimp decodes everything to RGBA, so the shim holds\n * a thunk that lazily loads the source pixels, then replays the recorded ops on\n * the bitmap. Channel intent (`removeAlpha` → 3, `ensureAlpha` → 4) is applied\n * only at the terminal raw output to match sharp's channel semantics.\n */\nclass JimpSharpInstance implements SharpInstance {\n private load: () => Promise<Bitmap>;\n private outputFormat: OutputFormat = \"png\";\n // null = no explicit alpha op; affects only `.raw()`/`.toBuffer({raw})`.\n private alphaMode: \"remove\" | \"ensure\" | null = null;\n\n constructor(load: () => Promise<Bitmap>) {\n this.load = load;\n }\n\n private chain(next: (bitmap: Bitmap) => Bitmap | Promise<Bitmap>): this {\n const prev = this.load;\n this.load = async () => next(await prev());\n return this;\n }\n\n metadata(): Promise<SharpMetadata> {\n return this.load().then((b) => ({\n width: b.width,\n height: b.height,\n channels: hasAlphaPixels(b) ? 4 : 3,\n format: this.outputFormat === \"raw\" ? \"raw\" : this.outputFormat,\n }));\n }\n\n resize(width: number, height: number, options?: SharpResizeOptions): this {\n const fit = options?.fit ?? \"cover\";\n if (fit !== \"fill\") {\n throw new Error(\n `[sharp-compat] resize fit \"${fit}\" is not supported by the pure-JS fallback (only \"fill\")`,\n );\n }\n return this.chain((b) => {\n const img = bitmapToJimp(b);\n img.resize({ w: width, h: height });\n return jimpToBitmap(img);\n });\n }\n\n removeAlpha(): this {\n this.alphaMode = \"remove\";\n return this;\n }\n\n ensureAlpha(): this {\n this.alphaMode = \"ensure\";\n return this;\n }\n\n extract(region: SharpExtractRegion): this {\n // Direct buffer crop — jimp's crop plugin is unreliable under the Node\n // vitest harness, and a sub-rectangle copy needs no codec.\n return this.chain((b) => cropBitmap(b, region));\n }\n\n extend(options: SharpExtendOptions): this {\n const top = options.top ?? 0;\n const bottom = options.bottom ?? 0;\n const left = options.left ?? 0;\n const right = options.right ?? 0;\n const bg = options.background ?? { r: 0, g: 0, b: 0, alpha: 1 };\n return this.chain((b) => padBitmap(b, top, bottom, left, right, bg));\n }\n\n trim(): this {\n return this.chain((b) => trimBitmap(b));\n }\n\n clone(): this {\n const prev = this.load;\n const clone = new JimpSharpInstance(async () => {\n const b = await prev();\n return { data: Buffer.from(b.data), width: b.width, height: b.height };\n });\n clone.outputFormat = this.outputFormat;\n clone.alphaMode = this.alphaMode;\n return clone as this;\n }\n\n png(): this {\n this.outputFormat = \"png\";\n return this;\n }\n\n jpeg(): this {\n this.outputFormat = \"jpeg\";\n return this;\n }\n\n raw(): this {\n this.outputFormat = \"raw\";\n return this;\n }\n\n toBuffer(): Promise<Buffer>;\n toBuffer(options: {\n resolveWithObject: true;\n }): Promise<SharpResolveWithObject>;\n async toBuffer(options?: {\n resolveWithObject: true;\n }): Promise<Buffer | SharpResolveWithObject> {\n const bitmap = await this.load();\n if (this.outputFormat === \"raw\") {\n const channels = this.rawChannels(bitmap);\n const data = toRawChannels(bitmap, channels);\n if (options?.resolveWithObject) {\n return {\n data,\n info: { width: bitmap.width, height: bitmap.height, channels },\n };\n }\n return data;\n }\n\n const dropAlpha = this.alphaMode === \"remove\";\n let data: Buffer;\n if (this.outputFormat === \"jpeg\") {\n // jimp's JPEG encoder is correct on both Node and bun; JPEG has no alpha.\n const img = bitmapToJimp(bitmap);\n const encoded = await img.getBuffer(JimpMime.jpeg);\n data = Buffer.isBuffer(encoded) ? encoded : Buffer.from(encoded);\n } else {\n // jimp's PNG encoder is broken under Node 24/25 (pngjs deflate), so encode\n // PNG directly via zlib — works identically on Node and bun, and both\n // sharp and jimp decode the result with exact pixel fidelity.\n data = encodePng(bitmap, dropAlpha);\n }\n if (options?.resolveWithObject) {\n return {\n data,\n info: {\n width: bitmap.width,\n height: bitmap.height,\n channels: dropAlpha ? 3 : 4,\n },\n };\n }\n return data;\n }\n\n /** Output channel count for raw output, matching sharp's alpha semantics. */\n private rawChannels(bitmap: Bitmap): 3 | 4 {\n if (this.alphaMode === \"remove\") return 3;\n if (this.alphaMode === \"ensure\") return 4;\n return hasAlphaPixels(bitmap) ? 4 : 3;\n }\n}\n\n/**\n * Construct the pure-JS shim factory directly. Exposed so the compat test can\n * diff the shim against native `sharp` without depending on which backend\n * `getSharp()` happens to resolve on the host.\n */\nexport function createJimpShim(): SharpFactory {\n return (input, options) => {\n if (options?.raw) {\n if (!input) {\n throw new Error(\"[sharp-compat] raw input requires a pixel buffer\");\n }\n const { width, height, channels } = options.raw;\n const rgba = rawToRgba(toBuffer(input), width, height, channels);\n return new JimpSharpInstance(async () => ({\n data: rgba,\n width,\n height,\n }));\n }\n if (!input) {\n throw new Error(\"[sharp-compat] an input buffer is required\");\n }\n const encoded = toBuffer(input);\n return new JimpSharpInstance(async () => {\n const img = await Jimp.read(encoded);\n return jimpToBitmap(img);\n });\n };\n}\n\nfunction toBuffer(input: Buffer | Uint8Array): Buffer {\n return Buffer.isBuffer(input) ? input : Buffer.from(input);\n}\n\nfunction bitmapToJimp(bitmap: Bitmap): JimpImage {\n return Jimp.fromBitmap({\n data: bitmap.data,\n width: bitmap.width,\n height: bitmap.height,\n });\n}\n\nfunction jimpToBitmap(img: JimpImage): Bitmap {\n const { data, width, height } = img.bitmap;\n return { data: Buffer.from(data), width, height };\n}\n\n/** True when any pixel has a non-opaque alpha channel. */\nfunction hasAlphaPixels(bitmap: Bitmap): boolean {\n for (let i = 3; i < bitmap.data.length; i += 4) {\n if (bitmap.data[i] !== 255) return true;\n }\n return false;\n}\n\n/** Expand raw N-channel pixels to the RGBA bitmap jimp works in. */\nfunction rawToRgba(\n data: Buffer,\n width: number,\n height: number,\n channels: number,\n): Buffer {\n const pixels = width * height;\n const out = Buffer.allocUnsafe(pixels * 4);\n for (let p = 0; p < pixels; p++) {\n const src = p * channels;\n const dst = p * 4;\n if (channels >= 3) {\n out[dst] = data[src];\n out[dst + 1] = data[src + 1];\n out[dst + 2] = data[src + 2];\n out[dst + 3] = channels >= 4 ? data[src + 3] : 255;\n } else {\n // 1ch grayscale or 2ch gray+alpha.\n const gray = data[src];\n out[dst] = gray;\n out[dst + 1] = gray;\n out[dst + 2] = gray;\n out[dst + 3] = channels === 2 ? data[src + 1] : 255;\n }\n }\n return out;\n}\n\n/** Collapse the RGBA working bitmap to the requested raw channel count. */\nfunction toRawChannels(bitmap: Bitmap, channels: 3 | 4): Buffer {\n const pixels = bitmap.width * bitmap.height;\n if (channels === 4) {\n return Buffer.from(bitmap.data.subarray(0, pixels * 4));\n }\n const out = Buffer.allocUnsafe(pixels * 3);\n for (let p = 0; p < pixels; p++) {\n out[p * 3] = bitmap.data[p * 4];\n out[p * 3 + 1] = bitmap.data[p * 4 + 1];\n out[p * 3 + 2] = bitmap.data[p * 4 + 2];\n }\n return out;\n}\n\n// --- PNG encoder -----------------------------------------------------------\n//\n// Minimal, dependency-free PNG encoder (filter type 0, single IDAT) backed by\n// node's built-in zlib. Replaces jimp's PNG encoder, which produces corrupt\n// output under Node 24/25. Color type 6 (RGBA) by default, color type 2 (RGB)\n// when alpha was dropped.\n\nconst CRC_TABLE = (() => {\n const table = new Uint32Array(256);\n for (let n = 0; n < 256; n++) {\n let c = n;\n for (let k = 0; k < 8; k++) {\n c = c & 1 ? 0xedb88320 ^ (c >>> 1) : c >>> 1;\n }\n table[n] = c >>> 0;\n }\n return table;\n})();\n\nfunction crc32(buf: Buffer): number {\n let crc = 0xffffffff;\n for (let i = 0; i < buf.length; i++) {\n crc = CRC_TABLE[(crc ^ buf[i]) & 0xff] ^ (crc >>> 8);\n }\n return (crc ^ 0xffffffff) >>> 0;\n}\n\nfunction pngChunk(type: string, data: Buffer): Buffer {\n const len = Buffer.allocUnsafe(4);\n len.writeUInt32BE(data.length, 0);\n const typeBuf = Buffer.from(type, \"ascii\");\n const crc = Buffer.allocUnsafe(4);\n crc.writeUInt32BE(crc32(Buffer.concat([typeBuf, data])), 0);\n return Buffer.concat([len, typeBuf, data, crc]);\n}\n\nfunction encodePng(bitmap: Bitmap, dropAlpha: boolean): Buffer {\n const { width, height, data } = bitmap;\n const channels = dropAlpha ? 3 : 4;\n const stride = width * channels;\n // One filter byte (type 0 = none) per scanline, then the row pixels.\n const rawWithFilters = Buffer.allocUnsafe((stride + 1) * height);\n for (let y = 0; y < height; y++) {\n const dstRow = y * (stride + 1);\n rawWithFilters[dstRow] = 0;\n if (dropAlpha) {\n const srcRow = y * width * 4;\n for (let x = 0; x < width; x++) {\n const s = srcRow + x * 4;\n const d = dstRow + 1 + x * 3;\n rawWithFilters[d] = data[s];\n rawWithFilters[d + 1] = data[s + 1];\n rawWithFilters[d + 2] = data[s + 2];\n }\n } else {\n const srcRow = y * stride;\n data.copy(rawWithFilters, dstRow + 1, srcRow, srcRow + stride);\n }\n }\n\n const ihdr = Buffer.allocUnsafe(13);\n ihdr.writeUInt32BE(width, 0);\n ihdr.writeUInt32BE(height, 4);\n ihdr[8] = 8; // bit depth\n ihdr[9] = dropAlpha ? 2 : 6; // color type: 2 = RGB, 6 = RGBA\n ihdr[10] = 0; // compression\n ihdr[11] = 0; // filter\n ihdr[12] = 0; // interlace\n\n const signature = Buffer.from([137, 80, 78, 71, 13, 10, 26, 10]);\n return Buffer.concat([\n signature,\n pngChunk(\"IHDR\", ihdr),\n pngChunk(\"IDAT\", deflateSync(rawWithFilters)),\n pngChunk(\"IEND\", Buffer.alloc(0)),\n ]);\n}\n\n/** Copy a sub-rectangle out of an RGBA bitmap (sharp `extract` semantics). */\nfunction cropBitmap(bitmap: Bitmap, region: SharpExtractRegion): Bitmap {\n const { left, top, width, height } = region;\n const out = Buffer.allocUnsafe(width * height * 4);\n const srcStride = bitmap.width * 4;\n for (let y = 0; y < height; y++) {\n const srcRow = (top + y) * srcStride + left * 4;\n bitmap.data.copy(out, y * width * 4, srcRow, srcRow + width * 4);\n }\n return { data: out, width, height };\n}\n\n/** Pad a bitmap with a solid-color border (sharp `extend` semantics). */\nfunction padBitmap(\n bitmap: Bitmap,\n top: number,\n bottom: number,\n left: number,\n right: number,\n bg: SharpColor,\n): Bitmap {\n const newWidth = bitmap.width + left + right;\n const newHeight = bitmap.height + top + bottom;\n const out = Buffer.allocUnsafe(newWidth * newHeight * 4);\n const alpha = bg.alpha === undefined ? 255 : Math.round(bg.alpha * 255);\n for (let i = 0; i < out.length; i += 4) {\n out[i] = bg.r;\n out[i + 1] = bg.g;\n out[i + 2] = bg.b;\n out[i + 3] = alpha;\n }\n for (let y = 0; y < bitmap.height; y++) {\n const srcRow = y * bitmap.width * 4;\n const dstRow = ((y + top) * newWidth + left) * 4;\n bitmap.data.copy(out, dstRow, srcRow, srcRow + bitmap.width * 4);\n }\n return { data: out, width: newWidth, height: newHeight };\n}\n\n/**\n * Autocrop a uniform border (sharp `trim` default: trim pixels matching the\n * top-left corner color, full-tolerance equality).\n */\nfunction trimBitmap(bitmap: Bitmap): Bitmap {\n const { data, width, height } = bitmap;\n const sameAsCorner = (x: number, y: number): boolean => {\n const i = (y * width + x) * 4;\n return (\n data[i] === data[0] &&\n data[i + 1] === data[1] &&\n data[i + 2] === data[2] &&\n data[i + 3] === data[3]\n );\n };\n let top = 0;\n let bottom = height - 1;\n let left = 0;\n let right = width - 1;\n const rowUniform = (y: number): boolean => {\n for (let x = 0; x < width; x++) if (!sameAsCorner(x, y)) return false;\n return true;\n };\n const colUniform = (x: number): boolean => {\n for (let y = 0; y < height; y++) if (!sameAsCorner(x, y)) return false;\n return true;\n };\n while (top < bottom && rowUniform(top)) top++;\n while (bottom > top && rowUniform(bottom)) bottom--;\n while (left < right && colUniform(left)) left++;\n while (right > left && colUniform(right)) right--;\n\n const newWidth = right - left + 1;\n const newHeight = bottom - top + 1;\n if (newWidth === width && newHeight === height) return bitmap;\n const out = Buffer.allocUnsafe(newWidth * newHeight * 4);\n for (let y = 0; y < newHeight; y++) {\n const srcRow = ((y + top) * width + left) * 4;\n out.set(data.subarray(srcRow, srcRow + newWidth * 4), y * newWidth * 4);\n }\n return { data: out, width: newWidth, height: newHeight };\n}\n",
|
|
6
7
|
"import { parentPort } from \"node:worker_threads\";\n\n/**\n * Worker-safe logger that sends log messages to the main thread\n */\nexport const logger = {\n info: (message: string, ...args: unknown[]) => {\n const logMessage = {\n type: \"log\",\n level: \"info\",\n message,\n args,\n timestamp: new Date().toISOString(),\n };\n\n if (parentPort) {\n parentPort.postMessage(logMessage);\n } else {\n console.log(`[INFO] ${message}`, ...args);\n }\n },\n\n warn: (message: string, ...args: unknown[]) => {\n const logMessage = {\n type: \"log\",\n level: \"warn\",\n message,\n args,\n timestamp: new Date().toISOString(),\n };\n\n if (parentPort) {\n parentPort.postMessage(logMessage);\n } else {\n console.warn(`[WARN] ${message}`, ...args);\n }\n },\n\n error: (message: string, ...args: unknown[]) => {\n const logMessage = {\n type: \"log\",\n level: \"error\",\n message,\n args,\n timestamp: new Date().toISOString(),\n };\n\n if (parentPort) {\n parentPort.postMessage(logMessage);\n } else {\n console.error(`[ERROR] ${message}`, ...args);\n }\n },\n\n debug: (message: string, ...args: unknown[]) => {\n const logMessage = {\n type: \"log\",\n level: \"debug\",\n message,\n args,\n timestamp: new Date().toISOString(),\n };\n\n if (parentPort) {\n parentPort.postMessage(logMessage);\n } else {\n console.debug(`[DEBUG] ${message}`, ...args);\n }\n },\n};\n"
|
|
7
8
|
],
|
|
8
|
-
"mappings": "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",
|
|
9
|
-
"debugId": "
|
|
9
|
+
"mappings": "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",
|
|
10
|
+
"debugId": "AF506971058FC3D264756E2164756E21",
|
|
10
11
|
"names": []
|
|
11
12
|
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Worker-safe logger that sends log messages to the main thread
|
|
3
|
+
*/
|
|
4
|
+
export declare const logger: {
|
|
5
|
+
info: (message: string, ...args: unknown[]) => void;
|
|
6
|
+
warn: (message: string, ...args: unknown[]) => void;
|
|
7
|
+
error: (message: string, ...args: unknown[]) => void;
|
|
8
|
+
debug: (message: string, ...args: unknown[]) => void;
|
|
9
|
+
};
|
|
10
|
+
//# sourceMappingURL=worker-logger.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"worker-logger.d.ts","sourceRoot":"","sources":["../../src/workers/worker-logger.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,eAAO,MAAM,MAAM;oBACD,MAAM,WAAW,OAAO,EAAE;oBAgB1B,MAAM,WAAW,OAAO,EAAE;qBAgBzB,MAAM,WAAW,OAAO,EAAE;qBAgB1B,MAAM,WAAW,OAAO,EAAE;CAe5C,CAAC"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import type { DetectedObject } from "./types";
|
|
2
|
+
export interface YOLOConfig {
|
|
3
|
+
/** GGUF weights path. Defaults to `<state-dir>/models/vision/yolov8n.gguf`. */
|
|
4
|
+
weightsPath?: string;
|
|
5
|
+
/** Class names override; defaults to COCO 80 or whatever's embedded in the GGUF. */
|
|
6
|
+
classes?: string[];
|
|
7
|
+
/** Score threshold for emitted detections. */
|
|
8
|
+
scoreThreshold?: number;
|
|
9
|
+
/** Non-max suppression IoU threshold. */
|
|
10
|
+
nmsIouThreshold?: number;
|
|
11
|
+
/** Restrict output to these COCO class names (case-insensitive). */
|
|
12
|
+
classFilter?: string[];
|
|
13
|
+
}
|
|
14
|
+
export declare class YOLODetector {
|
|
15
|
+
private readonly cfg;
|
|
16
|
+
private initPromise;
|
|
17
|
+
private initialized;
|
|
18
|
+
private classes;
|
|
19
|
+
private readonly classFilterLower;
|
|
20
|
+
constructor(config?: YOLOConfig);
|
|
21
|
+
static isAvailable(opts?: {
|
|
22
|
+
weightsPath?: string;
|
|
23
|
+
}): Promise<boolean>;
|
|
24
|
+
isInitialized(): boolean;
|
|
25
|
+
initialize(): Promise<void>;
|
|
26
|
+
private _initialize;
|
|
27
|
+
detect(imageBuffer: Buffer): Promise<DetectedObject[]>;
|
|
28
|
+
/**
|
|
29
|
+
* YOLOv8 raw output: (channels, anchors) where channels = 4 bbox + N classes.
|
|
30
|
+
* Decode each anchor: bbox = (cx, cy, w, h); score = best class prob.
|
|
31
|
+
*/
|
|
32
|
+
private parseYoloV8;
|
|
33
|
+
private nms;
|
|
34
|
+
private iou;
|
|
35
|
+
dispose(): Promise<void>;
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=yolo-detector.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"yolo-detector.d.ts","sourceRoot":"","sources":["../src/yolo-detector.ts"],"names":[],"mappings":"AAsBA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAqF9C,MAAM,WAAW,UAAU;IACzB,+EAA+E;IAC/E,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,oFAAoF;IACpF,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,8CAA8C;IAC9C,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,yCAAyC;IACzC,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,oEAAoE;IACpE,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;CACxB;AAYD,qBAAa,YAAY;IACvB,OAAO,CAAC,QAAQ,CAAC,GAAG,CAGP;IACb,OAAO,CAAC,WAAW,CAA8B;IACjD,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,OAAO,CAAW;IAC1B,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAqB;gBAE1C,MAAM,GAAE,UAAe;WAatB,WAAW,CAAC,IAAI,CAAC,EAAE;QAAE,WAAW,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,OAAO,CAAC;IAK3E,aAAa,IAAI,OAAO;IAIlB,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;YAOnB,WAAW;IA6BnB,MAAM,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC;IAuE5D;;;OAGG;IACH,OAAO,CAAC,WAAW;IA6CnB,OAAO,CAAC,GAAG;IAcX,OAAO,CAAC,GAAG;IAWL,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;CAO/B"}
|