firecrawl 4.20.0 → 4.21.0
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/dist/{chunk-UXVHRV2G.js → chunk-R625SBJY.js} +1 -1
- package/dist/index.cjs +55 -24
- package/dist/index.d.cts +2 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +56 -25
- package/dist/{package-ELM7Z5VP.js → package-MRLSD24T.js} +1 -1
- package/package.json +1 -1
- package/src/v2/methods/search.ts +6 -0
- package/src/v2/types.ts +2 -0
- package/src/v2/watcher.ts +44 -24
|
@@ -8,7 +8,7 @@ var require_package = __commonJS({
|
|
|
8
8
|
"package.json"(exports, module) {
|
|
9
9
|
module.exports = {
|
|
10
10
|
name: "@mendable/firecrawl-js",
|
|
11
|
-
version: "4.
|
|
11
|
+
version: "4.21.0",
|
|
12
12
|
description: "JavaScript SDK for Firecrawl API",
|
|
13
13
|
main: "dist/index.js",
|
|
14
14
|
types: "dist/index.d.ts",
|
package/dist/index.cjs
CHANGED
|
@@ -35,7 +35,7 @@ var require_package = __commonJS({
|
|
|
35
35
|
"package.json"(exports2, module2) {
|
|
36
36
|
module2.exports = {
|
|
37
37
|
name: "@mendable/firecrawl-js",
|
|
38
|
-
version: "4.
|
|
38
|
+
version: "4.21.0",
|
|
39
39
|
description: "JavaScript SDK for Firecrawl API",
|
|
40
40
|
main: "dist/index.js",
|
|
41
41
|
types: "dist/index.d.ts",
|
|
@@ -625,11 +625,17 @@ function prepareSearchPayload(req) {
|
|
|
625
625
|
throw new Error("limit must be positive");
|
|
626
626
|
if (req.timeout != null && req.timeout <= 0)
|
|
627
627
|
throw new Error("timeout must be positive");
|
|
628
|
+
if (req.includeDomains?.length && req.excludeDomains?.length)
|
|
629
|
+
throw new Error(
|
|
630
|
+
"includeDomains and excludeDomains cannot both be specified"
|
|
631
|
+
);
|
|
628
632
|
const payload = {
|
|
629
633
|
query: req.query
|
|
630
634
|
};
|
|
631
635
|
if (req.sources) payload.sources = req.sources;
|
|
632
636
|
if (req.categories) payload.categories = req.categories;
|
|
637
|
+
if (req.includeDomains) payload.includeDomains = req.includeDomains;
|
|
638
|
+
if (req.excludeDomains) payload.excludeDomains = req.excludeDomains;
|
|
633
639
|
if (req.limit != null) payload.limit = req.limit;
|
|
634
640
|
if (req.tbs != null) payload.tbs = req.tbs;
|
|
635
641
|
if (req.location != null) payload.location = req.location;
|
|
@@ -1418,23 +1424,41 @@ var Watcher = class extends import_events.EventEmitter {
|
|
|
1418
1424
|
return `${wsBase}${path}`;
|
|
1419
1425
|
}
|
|
1420
1426
|
async start() {
|
|
1421
|
-
|
|
1422
|
-
const
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
|
|
1427
|
+
return new Promise((resolve, reject) => {
|
|
1428
|
+
const onDone = () => {
|
|
1429
|
+
cleanup();
|
|
1430
|
+
resolve();
|
|
1431
|
+
};
|
|
1432
|
+
const onError = (err) => {
|
|
1433
|
+
cleanup();
|
|
1434
|
+
resolve();
|
|
1435
|
+
};
|
|
1436
|
+
const cleanup = () => {
|
|
1437
|
+
this.removeListener("done", onDone);
|
|
1438
|
+
this.removeListener("error", onError);
|
|
1439
|
+
};
|
|
1440
|
+
this.on("done", onDone);
|
|
1441
|
+
this.on("error", onError);
|
|
1442
|
+
(async () => {
|
|
1443
|
+
try {
|
|
1444
|
+
const url = this.buildWsUrl();
|
|
1445
|
+
const wsCtor = await getWebSocketCtor();
|
|
1446
|
+
if (!wsCtor) {
|
|
1447
|
+
this.pollLoop();
|
|
1448
|
+
return;
|
|
1449
|
+
}
|
|
1450
|
+
this.ws = new wsCtor(url, this.http.getApiKey());
|
|
1451
|
+
if (this.ws && "binaryType" in this.ws) {
|
|
1452
|
+
this.ws.binaryType = "arraybuffer";
|
|
1453
|
+
}
|
|
1454
|
+
if (this.ws) {
|
|
1455
|
+
this.attachWsHandlers(this.ws);
|
|
1456
|
+
}
|
|
1457
|
+
} catch (err) {
|
|
1458
|
+
this.pollLoop();
|
|
1459
|
+
}
|
|
1460
|
+
})();
|
|
1461
|
+
});
|
|
1438
1462
|
}
|
|
1439
1463
|
attachWsHandlers(ws) {
|
|
1440
1464
|
let startTs = Date.now();
|
|
@@ -1457,14 +1481,14 @@ var Watcher = class extends import_events.EventEmitter {
|
|
|
1457
1481
|
}
|
|
1458
1482
|
if (type === "document") {
|
|
1459
1483
|
const doc = body.data;
|
|
1460
|
-
if (doc) this.
|
|
1484
|
+
if (doc) this.emitDocuments([doc]);
|
|
1461
1485
|
return;
|
|
1462
1486
|
}
|
|
1463
1487
|
if (type === "done") {
|
|
1464
1488
|
const payload2 = body.data || body;
|
|
1465
1489
|
const data = payload2.data || [];
|
|
1466
1490
|
if (data.length) this.emitDocuments(data);
|
|
1467
|
-
this.emit("done", { status: "completed", data, id: this.jobId });
|
|
1491
|
+
this.emit("done", { status: "completed", data, id: this.jobId, total: payload2.total, completed: payload2.completed, creditsUsed: payload2.creditsUsed });
|
|
1468
1492
|
this.close();
|
|
1469
1493
|
return;
|
|
1470
1494
|
}
|
|
@@ -1472,7 +1496,10 @@ var Watcher = class extends import_events.EventEmitter {
|
|
|
1472
1496
|
if (payload && payload.status) this.emitSnapshot(payload);
|
|
1473
1497
|
} catch {
|
|
1474
1498
|
}
|
|
1475
|
-
if (timeoutMs && Date.now() - startTs > timeoutMs)
|
|
1499
|
+
if (timeoutMs && Date.now() - startTs > timeoutMs) {
|
|
1500
|
+
this.emit("error", { status: "failed", data: [], error: "Watcher timeout", id: this.jobId });
|
|
1501
|
+
this.close();
|
|
1502
|
+
}
|
|
1476
1503
|
};
|
|
1477
1504
|
ws.onerror = () => {
|
|
1478
1505
|
this.emit("error", { status: "failed", data: [], error: "WebSocket error", id: this.jobId });
|
|
@@ -1528,7 +1555,7 @@ var Watcher = class extends import_events.EventEmitter {
|
|
|
1528
1555
|
};
|
|
1529
1556
|
this.emit("snapshot", snap);
|
|
1530
1557
|
if (["completed", "failed", "cancelled"].includes(status)) {
|
|
1531
|
-
this.emit("done", { status, data, id: this.jobId });
|
|
1558
|
+
this.emit("done", { status, data, id: this.jobId, total: payload.total ?? 0, completed: payload.completed ?? 0, creditsUsed: payload.creditsUsed });
|
|
1532
1559
|
this.close();
|
|
1533
1560
|
}
|
|
1534
1561
|
}
|
|
@@ -1541,13 +1568,17 @@ var Watcher = class extends import_events.EventEmitter {
|
|
|
1541
1568
|
this.emitDocuments(snap.data || []);
|
|
1542
1569
|
this.emit("snapshot", snap);
|
|
1543
1570
|
if (["completed", "failed", "cancelled"].includes(snap.status)) {
|
|
1544
|
-
this.emit("done", { status: snap.status, data: snap.data, id: this.jobId });
|
|
1571
|
+
this.emit("done", { status: snap.status, data: snap.data, id: this.jobId, total: snap.total ?? 0, completed: snap.completed ?? 0, creditsUsed: snap.creditsUsed });
|
|
1545
1572
|
this.close();
|
|
1546
1573
|
break;
|
|
1547
1574
|
}
|
|
1548
1575
|
} catch {
|
|
1549
1576
|
}
|
|
1550
|
-
if (timeoutMs && Date.now() - startTs > timeoutMs)
|
|
1577
|
+
if (timeoutMs && Date.now() - startTs > timeoutMs) {
|
|
1578
|
+
this.emit("error", { status: "failed", data: [], error: "Watcher timeout", id: this.jobId });
|
|
1579
|
+
this.close();
|
|
1580
|
+
break;
|
|
1581
|
+
}
|
|
1551
1582
|
await new Promise((r) => setTimeout(r, Math.max(1e3, this.pollInterval * 1e3)));
|
|
1552
1583
|
}
|
|
1553
1584
|
}
|
package/dist/index.d.cts
CHANGED
|
@@ -395,6 +395,8 @@ interface SearchRequest {
|
|
|
395
395
|
type: 'web' | 'news' | 'images';
|
|
396
396
|
}>;
|
|
397
397
|
categories?: Array<'github' | 'research' | 'pdf' | CategoryOption>;
|
|
398
|
+
includeDomains?: string[];
|
|
399
|
+
excludeDomains?: string[];
|
|
398
400
|
limit?: number;
|
|
399
401
|
tbs?: string;
|
|
400
402
|
location?: string;
|
package/dist/index.d.ts
CHANGED
|
@@ -395,6 +395,8 @@ interface SearchRequest {
|
|
|
395
395
|
type: 'web' | 'news' | 'images';
|
|
396
396
|
}>;
|
|
397
397
|
categories?: Array<'github' | 'research' | 'pdf' | CategoryOption>;
|
|
398
|
+
includeDomains?: string[];
|
|
399
|
+
excludeDomains?: string[];
|
|
398
400
|
limit?: number;
|
|
399
401
|
tbs?: string;
|
|
400
402
|
location?: string;
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
require_package
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-R625SBJY.js";
|
|
4
4
|
|
|
5
5
|
// src/v2/utils/httpClient.ts
|
|
6
6
|
import axios from "axios";
|
|
@@ -501,11 +501,17 @@ function prepareSearchPayload(req) {
|
|
|
501
501
|
throw new Error("limit must be positive");
|
|
502
502
|
if (req.timeout != null && req.timeout <= 0)
|
|
503
503
|
throw new Error("timeout must be positive");
|
|
504
|
+
if (req.includeDomains?.length && req.excludeDomains?.length)
|
|
505
|
+
throw new Error(
|
|
506
|
+
"includeDomains and excludeDomains cannot both be specified"
|
|
507
|
+
);
|
|
504
508
|
const payload = {
|
|
505
509
|
query: req.query
|
|
506
510
|
};
|
|
507
511
|
if (req.sources) payload.sources = req.sources;
|
|
508
512
|
if (req.categories) payload.categories = req.categories;
|
|
513
|
+
if (req.includeDomains) payload.includeDomains = req.includeDomains;
|
|
514
|
+
if (req.excludeDomains) payload.excludeDomains = req.excludeDomains;
|
|
509
515
|
if (req.limit != null) payload.limit = req.limit;
|
|
510
516
|
if (req.tbs != null) payload.tbs = req.tbs;
|
|
511
517
|
if (req.location != null) payload.location = req.location;
|
|
@@ -1294,23 +1300,41 @@ var Watcher = class extends EventEmitter {
|
|
|
1294
1300
|
return `${wsBase}${path}`;
|
|
1295
1301
|
}
|
|
1296
1302
|
async start() {
|
|
1297
|
-
|
|
1298
|
-
const
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1303
|
+
return new Promise((resolve, reject) => {
|
|
1304
|
+
const onDone = () => {
|
|
1305
|
+
cleanup();
|
|
1306
|
+
resolve();
|
|
1307
|
+
};
|
|
1308
|
+
const onError = (err) => {
|
|
1309
|
+
cleanup();
|
|
1310
|
+
resolve();
|
|
1311
|
+
};
|
|
1312
|
+
const cleanup = () => {
|
|
1313
|
+
this.removeListener("done", onDone);
|
|
1314
|
+
this.removeListener("error", onError);
|
|
1315
|
+
};
|
|
1316
|
+
this.on("done", onDone);
|
|
1317
|
+
this.on("error", onError);
|
|
1318
|
+
(async () => {
|
|
1319
|
+
try {
|
|
1320
|
+
const url = this.buildWsUrl();
|
|
1321
|
+
const wsCtor = await getWebSocketCtor();
|
|
1322
|
+
if (!wsCtor) {
|
|
1323
|
+
this.pollLoop();
|
|
1324
|
+
return;
|
|
1325
|
+
}
|
|
1326
|
+
this.ws = new wsCtor(url, this.http.getApiKey());
|
|
1327
|
+
if (this.ws && "binaryType" in this.ws) {
|
|
1328
|
+
this.ws.binaryType = "arraybuffer";
|
|
1329
|
+
}
|
|
1330
|
+
if (this.ws) {
|
|
1331
|
+
this.attachWsHandlers(this.ws);
|
|
1332
|
+
}
|
|
1333
|
+
} catch (err) {
|
|
1334
|
+
this.pollLoop();
|
|
1335
|
+
}
|
|
1336
|
+
})();
|
|
1337
|
+
});
|
|
1314
1338
|
}
|
|
1315
1339
|
attachWsHandlers(ws) {
|
|
1316
1340
|
let startTs = Date.now();
|
|
@@ -1333,14 +1357,14 @@ var Watcher = class extends EventEmitter {
|
|
|
1333
1357
|
}
|
|
1334
1358
|
if (type === "document") {
|
|
1335
1359
|
const doc = body.data;
|
|
1336
|
-
if (doc) this.
|
|
1360
|
+
if (doc) this.emitDocuments([doc]);
|
|
1337
1361
|
return;
|
|
1338
1362
|
}
|
|
1339
1363
|
if (type === "done") {
|
|
1340
1364
|
const payload2 = body.data || body;
|
|
1341
1365
|
const data = payload2.data || [];
|
|
1342
1366
|
if (data.length) this.emitDocuments(data);
|
|
1343
|
-
this.emit("done", { status: "completed", data, id: this.jobId });
|
|
1367
|
+
this.emit("done", { status: "completed", data, id: this.jobId, total: payload2.total, completed: payload2.completed, creditsUsed: payload2.creditsUsed });
|
|
1344
1368
|
this.close();
|
|
1345
1369
|
return;
|
|
1346
1370
|
}
|
|
@@ -1348,7 +1372,10 @@ var Watcher = class extends EventEmitter {
|
|
|
1348
1372
|
if (payload && payload.status) this.emitSnapshot(payload);
|
|
1349
1373
|
} catch {
|
|
1350
1374
|
}
|
|
1351
|
-
if (timeoutMs && Date.now() - startTs > timeoutMs)
|
|
1375
|
+
if (timeoutMs && Date.now() - startTs > timeoutMs) {
|
|
1376
|
+
this.emit("error", { status: "failed", data: [], error: "Watcher timeout", id: this.jobId });
|
|
1377
|
+
this.close();
|
|
1378
|
+
}
|
|
1352
1379
|
};
|
|
1353
1380
|
ws.onerror = () => {
|
|
1354
1381
|
this.emit("error", { status: "failed", data: [], error: "WebSocket error", id: this.jobId });
|
|
@@ -1404,7 +1431,7 @@ var Watcher = class extends EventEmitter {
|
|
|
1404
1431
|
};
|
|
1405
1432
|
this.emit("snapshot", snap);
|
|
1406
1433
|
if (["completed", "failed", "cancelled"].includes(status)) {
|
|
1407
|
-
this.emit("done", { status, data, id: this.jobId });
|
|
1434
|
+
this.emit("done", { status, data, id: this.jobId, total: payload.total ?? 0, completed: payload.completed ?? 0, creditsUsed: payload.creditsUsed });
|
|
1408
1435
|
this.close();
|
|
1409
1436
|
}
|
|
1410
1437
|
}
|
|
@@ -1417,13 +1444,17 @@ var Watcher = class extends EventEmitter {
|
|
|
1417
1444
|
this.emitDocuments(snap.data || []);
|
|
1418
1445
|
this.emit("snapshot", snap);
|
|
1419
1446
|
if (["completed", "failed", "cancelled"].includes(snap.status)) {
|
|
1420
|
-
this.emit("done", { status: snap.status, data: snap.data, id: this.jobId });
|
|
1447
|
+
this.emit("done", { status: snap.status, data: snap.data, id: this.jobId, total: snap.total ?? 0, completed: snap.completed ?? 0, creditsUsed: snap.creditsUsed });
|
|
1421
1448
|
this.close();
|
|
1422
1449
|
break;
|
|
1423
1450
|
}
|
|
1424
1451
|
} catch {
|
|
1425
1452
|
}
|
|
1426
|
-
if (timeoutMs && Date.now() - startTs > timeoutMs)
|
|
1453
|
+
if (timeoutMs && Date.now() - startTs > timeoutMs) {
|
|
1454
|
+
this.emit("error", { status: "failed", data: [], error: "Watcher timeout", id: this.jobId });
|
|
1455
|
+
this.close();
|
|
1456
|
+
break;
|
|
1457
|
+
}
|
|
1427
1458
|
await new Promise((r) => setTimeout(r, Math.max(1e3, this.pollInterval * 1e3)));
|
|
1428
1459
|
}
|
|
1429
1460
|
}
|
|
@@ -1778,7 +1809,7 @@ var FirecrawlApp = class {
|
|
|
1778
1809
|
if (typeof process !== "undefined" && process.env && process.env.npm_package_version) {
|
|
1779
1810
|
return process.env.npm_package_version;
|
|
1780
1811
|
}
|
|
1781
|
-
const packageJson = await import("./package-
|
|
1812
|
+
const packageJson = await import("./package-MRLSD24T.js");
|
|
1782
1813
|
return packageJson.default.version;
|
|
1783
1814
|
} catch (error) {
|
|
1784
1815
|
const isTest = typeof process !== "undefined" && (process.env.JEST_WORKER_ID != null || false);
|
package/package.json
CHANGED
package/src/v2/methods/search.ts
CHANGED
|
@@ -20,11 +20,17 @@ function prepareSearchPayload(req: SearchRequest): Record<string, unknown> {
|
|
|
20
20
|
throw new Error("limit must be positive");
|
|
21
21
|
if (req.timeout != null && req.timeout <= 0)
|
|
22
22
|
throw new Error("timeout must be positive");
|
|
23
|
+
if (req.includeDomains?.length && req.excludeDomains?.length)
|
|
24
|
+
throw new Error(
|
|
25
|
+
"includeDomains and excludeDomains cannot both be specified",
|
|
26
|
+
);
|
|
23
27
|
const payload: Record<string, unknown> = {
|
|
24
28
|
query: req.query,
|
|
25
29
|
};
|
|
26
30
|
if (req.sources) payload.sources = req.sources;
|
|
27
31
|
if (req.categories) payload.categories = req.categories;
|
|
32
|
+
if (req.includeDomains) payload.includeDomains = req.includeDomains;
|
|
33
|
+
if (req.excludeDomains) payload.excludeDomains = req.excludeDomains;
|
|
28
34
|
if (req.limit != null) payload.limit = req.limit;
|
|
29
35
|
if (req.tbs != null) payload.tbs = req.tbs;
|
|
30
36
|
if (req.location != null) payload.location = req.location;
|
package/src/v2/types.ts
CHANGED
|
@@ -508,6 +508,8 @@ export interface SearchRequest {
|
|
|
508
508
|
'web' | 'news' | 'images' | { type: 'web' | 'news' | 'images' }
|
|
509
509
|
>;
|
|
510
510
|
categories?: Array<'github' | 'research' | 'pdf' | CategoryOption>;
|
|
511
|
+
includeDomains?: string[];
|
|
512
|
+
excludeDomains?: string[];
|
|
511
513
|
limit?: number;
|
|
512
514
|
tbs?: string;
|
|
513
515
|
location?: string;
|
package/src/v2/watcher.ts
CHANGED
|
@@ -109,24 +109,37 @@ export class Watcher extends EventEmitter {
|
|
|
109
109
|
}
|
|
110
110
|
|
|
111
111
|
async start(): Promise<void> {
|
|
112
|
-
|
|
113
|
-
const
|
|
114
|
-
const
|
|
115
|
-
|
|
116
|
-
this.
|
|
117
|
-
|
|
118
|
-
}
|
|
119
|
-
this.
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
112
|
+
return new Promise<void>((resolve, reject) => {
|
|
113
|
+
const onDone = () => { cleanup(); resolve(); };
|
|
114
|
+
const onError = (err: any) => { cleanup(); resolve(); };
|
|
115
|
+
const cleanup = () => {
|
|
116
|
+
this.removeListener("done", onDone);
|
|
117
|
+
this.removeListener("error", onError);
|
|
118
|
+
};
|
|
119
|
+
this.on("done", onDone);
|
|
120
|
+
this.on("error", onError);
|
|
121
|
+
|
|
122
|
+
(async () => {
|
|
123
|
+
try {
|
|
124
|
+
const url = this.buildWsUrl();
|
|
125
|
+
const wsCtor = await getWebSocketCtor();
|
|
126
|
+
if (!wsCtor) {
|
|
127
|
+
this.pollLoop();
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
130
|
+
this.ws = new wsCtor(url, this.http.getApiKey()) as any;
|
|
131
|
+
if (this.ws && "binaryType" in this.ws) {
|
|
132
|
+
(this.ws as any).binaryType = "arraybuffer";
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
if (this.ws) {
|
|
136
|
+
this.attachWsHandlers(this.ws);
|
|
137
|
+
}
|
|
138
|
+
} catch (err) {
|
|
139
|
+
this.pollLoop();
|
|
140
|
+
}
|
|
141
|
+
})();
|
|
142
|
+
});
|
|
130
143
|
}
|
|
131
144
|
|
|
132
145
|
private attachWsHandlers(ws: WebSocket) {
|
|
@@ -150,14 +163,14 @@ export class Watcher extends EventEmitter {
|
|
|
150
163
|
}
|
|
151
164
|
if (type === "document") {
|
|
152
165
|
const doc = body.data;
|
|
153
|
-
if (doc) this.
|
|
166
|
+
if (doc) this.emitDocuments([doc]);
|
|
154
167
|
return;
|
|
155
168
|
}
|
|
156
169
|
if (type === "done") {
|
|
157
170
|
const payload = body.data || body;
|
|
158
171
|
const data = (payload.data || []) as Document[];
|
|
159
172
|
if (data.length) this.emitDocuments(data);
|
|
160
|
-
this.emit("done", { status: "completed", data, id: this.jobId });
|
|
173
|
+
this.emit("done", { status: "completed", data, id: this.jobId, total: payload.total, completed: payload.completed, creditsUsed: payload.creditsUsed });
|
|
161
174
|
this.close();
|
|
162
175
|
return;
|
|
163
176
|
}
|
|
@@ -166,7 +179,10 @@ export class Watcher extends EventEmitter {
|
|
|
166
179
|
} catch {
|
|
167
180
|
// ignore
|
|
168
181
|
}
|
|
169
|
-
if (timeoutMs && Date.now() - startTs > timeoutMs)
|
|
182
|
+
if (timeoutMs && Date.now() - startTs > timeoutMs) {
|
|
183
|
+
this.emit("error", { status: "failed", data: [], error: "Watcher timeout", id: this.jobId });
|
|
184
|
+
this.close();
|
|
185
|
+
}
|
|
170
186
|
};
|
|
171
187
|
ws.onerror = () => {
|
|
172
188
|
this.emit("error", { status: "failed", data: [], error: "WebSocket error", id: this.jobId });
|
|
@@ -227,7 +243,7 @@ export class Watcher extends EventEmitter {
|
|
|
227
243
|
};
|
|
228
244
|
this.emit("snapshot", snap);
|
|
229
245
|
if (["completed", "failed", "cancelled"].includes(status)) {
|
|
230
|
-
this.emit("done", { status, data, id: this.jobId });
|
|
246
|
+
this.emit("done", { status, data, id: this.jobId, total: payload.total ?? 0, completed: payload.completed ?? 0, creditsUsed: payload.creditsUsed });
|
|
231
247
|
this.close();
|
|
232
248
|
}
|
|
233
249
|
}
|
|
@@ -243,14 +259,18 @@ export class Watcher extends EventEmitter {
|
|
|
243
259
|
this.emitDocuments((snap.data || []) as Document[]);
|
|
244
260
|
this.emit("snapshot", snap);
|
|
245
261
|
if (["completed", "failed", "cancelled"].includes(snap.status)) {
|
|
246
|
-
this.emit("done", { status: snap.status, data: snap.data, id: this.jobId });
|
|
262
|
+
this.emit("done", { status: snap.status, data: snap.data, id: this.jobId, total: (snap as any).total ?? 0, completed: (snap as any).completed ?? 0, creditsUsed: (snap as any).creditsUsed });
|
|
247
263
|
this.close();
|
|
248
264
|
break;
|
|
249
265
|
}
|
|
250
266
|
} catch {
|
|
251
267
|
// ignore polling errors
|
|
252
268
|
}
|
|
253
|
-
if (timeoutMs && Date.now() - startTs > timeoutMs)
|
|
269
|
+
if (timeoutMs && Date.now() - startTs > timeoutMs) {
|
|
270
|
+
this.emit("error", { status: "failed", data: [], error: "Watcher timeout", id: this.jobId });
|
|
271
|
+
this.close();
|
|
272
|
+
break;
|
|
273
|
+
}
|
|
254
274
|
await new Promise((r) => setTimeout(r, Math.max(1000, this.pollInterval * 1000)));
|
|
255
275
|
}
|
|
256
276
|
}
|