@hasna/browser 0.3.2 → 0.3.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/dist/cli/index.js +999 -299
- package/dist/index.js +75 -22
- package/dist/mcp/index.js +1086 -338
- package/dist/server/index.js +90 -40
- package/package.json +1 -1
- package/dashboard/dist/assets/index-Cy4XUbL1.js +0 -40
- package/dashboard/dist/index.html +0 -16
- package/dist/cli/commands/browse.d.ts +0 -3
- package/dist/cli/commands/browse.d.ts.map +0 -1
- package/dist/cli/commands/script.d.ts +0 -3
- package/dist/cli/commands/script.d.ts.map +0 -1
- package/dist/cli/commands/session.d.ts +0 -3
- package/dist/cli/commands/session.d.ts.map +0 -1
- package/dist/cli/commands/tools.d.ts +0 -3
- package/dist/cli/commands/tools.d.ts.map +0 -1
- package/dist/cli/index.d.ts +0 -3
- package/dist/cli/index.d.ts.map +0 -1
- package/dist/cli/index.test.d.ts +0 -2
- package/dist/cli/index.test.d.ts.map +0 -1
- package/dist/db/agents.d.ts +0 -16
- package/dist/db/agents.d.ts.map +0 -1
- package/dist/db/agents.test.d.ts +0 -2
- package/dist/db/agents.test.d.ts.map +0 -1
- package/dist/db/console-log.d.ts +0 -6
- package/dist/db/console-log.d.ts.map +0 -1
- package/dist/db/crawl-results.d.ts +0 -6
- package/dist/db/crawl-results.d.ts.map +0 -1
- package/dist/db/gallery.d.ts +0 -26
- package/dist/db/gallery.d.ts.map +0 -1
- package/dist/db/gallery.test.d.ts +0 -2
- package/dist/db/gallery.test.d.ts.map +0 -1
- package/dist/db/heartbeats.d.ts +0 -6
- package/dist/db/heartbeats.d.ts.map +0 -1
- package/dist/db/network-log.d.ts +0 -7
- package/dist/db/network-log.d.ts.map +0 -1
- package/dist/db/projects.d.ts +0 -9
- package/dist/db/projects.d.ts.map +0 -1
- package/dist/db/projects.test.d.ts +0 -2
- package/dist/db/projects.test.d.ts.map +0 -1
- package/dist/db/recordings.d.ts +0 -11
- package/dist/db/recordings.d.ts.map +0 -1
- package/dist/db/recordings.test.d.ts +0 -2
- package/dist/db/recordings.test.d.ts.map +0 -1
- package/dist/db/schema.d.ts +0 -5
- package/dist/db/schema.d.ts.map +0 -1
- package/dist/db/schema.test.d.ts +0 -2
- package/dist/db/schema.test.d.ts.map +0 -1
- package/dist/db/scripts.d.ts +0 -84
- package/dist/db/scripts.d.ts.map +0 -1
- package/dist/db/sessions.d.ts +0 -35
- package/dist/db/sessions.d.ts.map +0 -1
- package/dist/db/sessions.test.d.ts +0 -2
- package/dist/db/sessions.test.d.ts.map +0 -1
- package/dist/db/snapshots.d.ts +0 -7
- package/dist/db/snapshots.d.ts.map +0 -1
- package/dist/db/timeline.d.ts +0 -11
- package/dist/db/timeline.d.ts.map +0 -1
- package/dist/engines/bun-webview.d.ts +0 -147
- package/dist/engines/bun-webview.d.ts.map +0 -1
- package/dist/engines/bun-webview.test.d.ts +0 -2
- package/dist/engines/bun-webview.test.d.ts.map +0 -1
- package/dist/engines/cdp.d.ts +0 -27
- package/dist/engines/cdp.d.ts.map +0 -1
- package/dist/engines/lightpanda.d.ts +0 -25
- package/dist/engines/lightpanda.d.ts.map +0 -1
- package/dist/engines/playwright.d.ts +0 -27
- package/dist/engines/playwright.d.ts.map +0 -1
- package/dist/engines/selector.d.ts +0 -17
- package/dist/engines/selector.d.ts.map +0 -1
- package/dist/engines/selector.test.d.ts +0 -2
- package/dist/engines/selector.test.d.ts.map +0 -1
- package/dist/index.d.ts +0 -28
- package/dist/index.d.ts.map +0 -1
- package/dist/lib/actions-ref.test.d.ts +0 -2
- package/dist/lib/actions-ref.test.d.ts.map +0 -1
- package/dist/lib/actions.d.ts +0 -91
- package/dist/lib/actions.d.ts.map +0 -1
- package/dist/lib/actions.test.d.ts +0 -2
- package/dist/lib/actions.test.d.ts.map +0 -1
- package/dist/lib/agents.d.ts +0 -9
- package/dist/lib/agents.d.ts.map +0 -1
- package/dist/lib/agents.test.d.ts +0 -2
- package/dist/lib/agents.test.d.ts.map +0 -1
- package/dist/lib/ai-inference.d.ts +0 -21
- package/dist/lib/ai-inference.d.ts.map +0 -1
- package/dist/lib/ai-task.d.ts +0 -23
- package/dist/lib/ai-task.d.ts.map +0 -1
- package/dist/lib/annotate.d.ts +0 -18
- package/dist/lib/annotate.d.ts.map +0 -1
- package/dist/lib/annotate.test.d.ts +0 -2
- package/dist/lib/annotate.test.d.ts.map +0 -1
- package/dist/lib/api-detector.d.ts +0 -17
- package/dist/lib/api-detector.d.ts.map +0 -1
- package/dist/lib/auth-flow.d.ts +0 -43
- package/dist/lib/auth-flow.d.ts.map +0 -1
- package/dist/lib/auth.d.ts +0 -28
- package/dist/lib/auth.d.ts.map +0 -1
- package/dist/lib/console.d.ts +0 -6
- package/dist/lib/console.d.ts.map +0 -1
- package/dist/lib/coordination.d.ts +0 -12
- package/dist/lib/coordination.d.ts.map +0 -1
- package/dist/lib/crawler.d.ts +0 -3
- package/dist/lib/crawler.d.ts.map +0 -1
- package/dist/lib/cron-manager.d.ts +0 -43
- package/dist/lib/cron-manager.d.ts.map +0 -1
- package/dist/lib/daemon-client.d.ts +0 -16
- package/dist/lib/daemon-client.d.ts.map +0 -1
- package/dist/lib/datasets.d.ts +0 -33
- package/dist/lib/datasets.d.ts.map +0 -1
- package/dist/lib/deep-performance.d.ts +0 -49
- package/dist/lib/deep-performance.d.ts.map +0 -1
- package/dist/lib/dialogs.d.ts +0 -15
- package/dist/lib/dialogs.d.ts.map +0 -1
- package/dist/lib/downloads.d.ts +0 -15
- package/dist/lib/downloads.d.ts.map +0 -1
- package/dist/lib/downloads.test.d.ts +0 -2
- package/dist/lib/downloads.test.d.ts.map +0 -1
- package/dist/lib/env-detector.d.ts +0 -12
- package/dist/lib/env-detector.d.ts.map +0 -1
- package/dist/lib/extractor.d.ts +0 -22
- package/dist/lib/extractor.d.ts.map +0 -1
- package/dist/lib/extractor.test.d.ts +0 -2
- package/dist/lib/extractor.test.d.ts.map +0 -1
- package/dist/lib/files-integration.d.ts +0 -13
- package/dist/lib/files-integration.d.ts.map +0 -1
- package/dist/lib/gallery-diff.d.ts +0 -3
- package/dist/lib/gallery-diff.d.ts.map +0 -1
- package/dist/lib/integrations.test.d.ts +0 -2
- package/dist/lib/integrations.test.d.ts.map +0 -1
- package/dist/lib/login-scripts.d.ts +0 -89
- package/dist/lib/login-scripts.d.ts.map +0 -1
- package/dist/lib/network.d.ts +0 -11
- package/dist/lib/network.d.ts.map +0 -1
- package/dist/lib/network.test.d.ts +0 -2
- package/dist/lib/network.test.d.ts.map +0 -1
- package/dist/lib/page-memory.d.ts +0 -14
- package/dist/lib/page-memory.d.ts.map +0 -1
- package/dist/lib/performance.d.ts +0 -13
- package/dist/lib/performance.d.ts.map +0 -1
- package/dist/lib/profiles.d.ts +0 -23
- package/dist/lib/profiles.d.ts.map +0 -1
- package/dist/lib/qol.test.d.ts +0 -2
- package/dist/lib/qol.test.d.ts.map +0 -1
- package/dist/lib/recorder.d.ts +0 -11
- package/dist/lib/recorder.d.ts.map +0 -1
- package/dist/lib/recorder.test.d.ts +0 -2
- package/dist/lib/recorder.test.d.ts.map +0 -1
- package/dist/lib/ref-cache.d.ts +0 -9
- package/dist/lib/ref-cache.d.ts.map +0 -1
- package/dist/lib/sanitize.d.ts +0 -21
- package/dist/lib/sanitize.d.ts.map +0 -1
- package/dist/lib/screenshot-v4.test.d.ts +0 -2
- package/dist/lib/screenshot-v4.test.d.ts.map +0 -1
- package/dist/lib/screenshot.d.ts +0 -11
- package/dist/lib/screenshot.d.ts.map +0 -1
- package/dist/lib/screenshot.test.d.ts +0 -2
- package/dist/lib/screenshot.test.d.ts.map +0 -1
- package/dist/lib/script-engine.d.ts +0 -28
- package/dist/lib/script-engine.d.ts.map +0 -1
- package/dist/lib/self-heal.d.ts +0 -18
- package/dist/lib/self-heal.d.ts.map +0 -1
- package/dist/lib/session-v3.test.d.ts +0 -2
- package/dist/lib/session-v3.test.d.ts.map +0 -1
- package/dist/lib/session.d.ts +0 -38
- package/dist/lib/session.d.ts.map +0 -1
- package/dist/lib/skills-runner.d.ts +0 -14
- package/dist/lib/skills-runner.d.ts.map +0 -1
- package/dist/lib/snapshot-diff.test.d.ts +0 -2
- package/dist/lib/snapshot-diff.test.d.ts.map +0 -1
- package/dist/lib/snapshot.d.ts +0 -34
- package/dist/lib/snapshot.d.ts.map +0 -1
- package/dist/lib/snapshot.test.d.ts +0 -2
- package/dist/lib/snapshot.test.d.ts.map +0 -1
- package/dist/lib/stealth.d.ts +0 -5
- package/dist/lib/stealth.d.ts.map +0 -1
- package/dist/lib/stealth.test.d.ts +0 -2
- package/dist/lib/stealth.test.d.ts.map +0 -1
- package/dist/lib/storage-state.d.ts +0 -15
- package/dist/lib/storage-state.d.ts.map +0 -1
- package/dist/lib/storage.d.ts +0 -19
- package/dist/lib/storage.d.ts.map +0 -1
- package/dist/lib/structured-extract.d.ts +0 -26
- package/dist/lib/structured-extract.d.ts.map +0 -1
- package/dist/lib/tabs.d.ts +0 -18
- package/dist/lib/tabs.d.ts.map +0 -1
- package/dist/lib/task-queue.d.ts +0 -21
- package/dist/lib/task-queue.d.ts.map +0 -1
- package/dist/lib/url-watcher.d.ts +0 -33
- package/dist/lib/url-watcher.d.ts.map +0 -1
- package/dist/lib/vision-fallback.d.ts +0 -29
- package/dist/lib/vision-fallback.d.ts.map +0 -1
- package/dist/lib/workflows.d.ts +0 -46
- package/dist/lib/workflows.d.ts.map +0 -1
- package/dist/mcp/actions.d.ts +0 -3
- package/dist/mcp/actions.d.ts.map +0 -1
- package/dist/mcp/capture.d.ts +0 -3
- package/dist/mcp/capture.d.ts.map +0 -1
- package/dist/mcp/data.d.ts +0 -3
- package/dist/mcp/data.d.ts.map +0 -1
- package/dist/mcp/gallery.test.d.ts +0 -2
- package/dist/mcp/gallery.test.d.ts.map +0 -1
- package/dist/mcp/helpers.d.ts +0 -55
- package/dist/mcp/helpers.d.ts.map +0 -1
- package/dist/mcp/index.d.ts +0 -3
- package/dist/mcp/index.d.ts.map +0 -1
- package/dist/mcp/index.test.d.ts +0 -2
- package/dist/mcp/index.test.d.ts.map +0 -1
- package/dist/mcp/meta.d.ts +0 -3
- package/dist/mcp/meta.d.ts.map +0 -1
- package/dist/mcp/network.d.ts +0 -3
- package/dist/mcp/network.d.ts.map +0 -1
- package/dist/mcp/recordings.d.ts +0 -3
- package/dist/mcp/recordings.d.ts.map +0 -1
- package/dist/mcp/scripts.d.ts +0 -3
- package/dist/mcp/scripts.d.ts.map +0 -1
- package/dist/mcp/sessions.d.ts +0 -3
- package/dist/mcp/sessions.d.ts.map +0 -1
- package/dist/mcp/v4.test.d.ts +0 -2
- package/dist/mcp/v4.test.d.ts.map +0 -1
- package/dist/server/index.d.ts +0 -2
- package/dist/server/index.d.ts.map +0 -1
- package/dist/server/index.test.d.ts +0 -2
- package/dist/server/index.test.d.ts.map +0 -1
- package/dist/types/index.d.ts +0 -425
- package/dist/types/index.d.ts.map +0 -1
package/dist/server/index.js
CHANGED
|
@@ -4,25 +4,43 @@ var __getProtoOf = Object.getPrototypeOf;
|
|
|
4
4
|
var __defProp = Object.defineProperty;
|
|
5
5
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
6
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
|
+
function __accessProp(key) {
|
|
8
|
+
return this[key];
|
|
9
|
+
}
|
|
10
|
+
var __toESMCache_node;
|
|
11
|
+
var __toESMCache_esm;
|
|
7
12
|
var __toESM = (mod, isNodeMode, target) => {
|
|
13
|
+
var canCache = mod != null && typeof mod === "object";
|
|
14
|
+
if (canCache) {
|
|
15
|
+
var cache = isNodeMode ? __toESMCache_node ??= new WeakMap : __toESMCache_esm ??= new WeakMap;
|
|
16
|
+
var cached = cache.get(mod);
|
|
17
|
+
if (cached)
|
|
18
|
+
return cached;
|
|
19
|
+
}
|
|
8
20
|
target = mod != null ? __create(__getProtoOf(mod)) : {};
|
|
9
21
|
const to = isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target;
|
|
10
22
|
for (let key of __getOwnPropNames(mod))
|
|
11
23
|
if (!__hasOwnProp.call(to, key))
|
|
12
24
|
__defProp(to, key, {
|
|
13
|
-
get: (
|
|
25
|
+
get: __accessProp.bind(mod, key),
|
|
14
26
|
enumerable: true
|
|
15
27
|
});
|
|
28
|
+
if (canCache)
|
|
29
|
+
cache.set(mod, to);
|
|
16
30
|
return to;
|
|
17
31
|
};
|
|
18
32
|
var __commonJS = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
|
|
33
|
+
var __returnValue = (v) => v;
|
|
34
|
+
function __exportSetter(name, newValue) {
|
|
35
|
+
this[name] = __returnValue.bind(null, newValue);
|
|
36
|
+
}
|
|
19
37
|
var __export = (target, all) => {
|
|
20
38
|
for (var name in all)
|
|
21
39
|
__defProp(target, name, {
|
|
22
40
|
get: all[name],
|
|
23
41
|
enumerable: true,
|
|
24
42
|
configurable: true,
|
|
25
|
-
set: (
|
|
43
|
+
set: __exportSetter.bind(all, name)
|
|
26
44
|
});
|
|
27
45
|
};
|
|
28
46
|
var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
|
|
@@ -88,10 +106,30 @@ var init_types = __esm(() => {
|
|
|
88
106
|
// src/db/schema.ts
|
|
89
107
|
import { Database } from "bun:sqlite";
|
|
90
108
|
import { join } from "path";
|
|
91
|
-
import { mkdirSync } from "fs";
|
|
109
|
+
import { mkdirSync, existsSync, readdirSync, copyFileSync, statSync } from "fs";
|
|
92
110
|
import { homedir } from "os";
|
|
93
111
|
function getDataDir() {
|
|
94
|
-
|
|
112
|
+
if (process.env["BROWSER_DATA_DIR"])
|
|
113
|
+
return process.env["BROWSER_DATA_DIR"];
|
|
114
|
+
const home = process.env["HOME"] || process.env["USERPROFILE"] || homedir();
|
|
115
|
+
const newDir = join(home, ".hasna", "browser");
|
|
116
|
+
const oldDir = join(home, ".browser");
|
|
117
|
+
if (existsSync(oldDir) && !existsSync(newDir)) {
|
|
118
|
+
mkdirSync(newDir, { recursive: true });
|
|
119
|
+
try {
|
|
120
|
+
for (const file of readdirSync(oldDir)) {
|
|
121
|
+
const oldPath = join(oldDir, file);
|
|
122
|
+
const newPath = join(newDir, file);
|
|
123
|
+
try {
|
|
124
|
+
if (statSync(oldPath).isFile()) {
|
|
125
|
+
copyFileSync(oldPath, newPath);
|
|
126
|
+
}
|
|
127
|
+
} catch {}
|
|
128
|
+
}
|
|
129
|
+
} catch {}
|
|
130
|
+
}
|
|
131
|
+
mkdirSync(newDir, { recursive: true });
|
|
132
|
+
return newDir;
|
|
95
133
|
}
|
|
96
134
|
function getDatabase(path) {
|
|
97
135
|
const resolvedPath = path ?? process.env["BROWSER_DB_PATH"] ?? join(getDataDir(), "browser.db");
|
|
@@ -583,9 +621,8 @@ __export(exports_storage_state, {
|
|
|
583
621
|
listStates: () => listStates,
|
|
584
622
|
deleteState: () => deleteState
|
|
585
623
|
});
|
|
586
|
-
import { mkdirSync as mkdirSync3, existsSync, readdirSync, unlinkSync } from "fs";
|
|
624
|
+
import { mkdirSync as mkdirSync3, existsSync as existsSync2, readdirSync as readdirSync2, unlinkSync } from "fs";
|
|
587
625
|
import { join as join3 } from "path";
|
|
588
|
-
import { homedir as homedir3 } from "os";
|
|
589
626
|
function ensureDir() {
|
|
590
627
|
mkdirSync3(STATES_DIR, { recursive: true });
|
|
591
628
|
}
|
|
@@ -603,11 +640,11 @@ async function saveStateFromPage(page, name) {
|
|
|
603
640
|
}
|
|
604
641
|
function loadStatePath(name) {
|
|
605
642
|
const path = statePath(name);
|
|
606
|
-
return
|
|
643
|
+
return existsSync2(path) ? path : null;
|
|
607
644
|
}
|
|
608
645
|
function listStates() {
|
|
609
646
|
ensureDir();
|
|
610
|
-
return
|
|
647
|
+
return readdirSync2(STATES_DIR).filter((f) => f.endsWith(".json")).map((f) => {
|
|
611
648
|
const path = join3(STATES_DIR, f);
|
|
612
649
|
const stat = Bun.file(path);
|
|
613
650
|
return {
|
|
@@ -619,7 +656,7 @@ function listStates() {
|
|
|
619
656
|
}
|
|
620
657
|
function deleteState(name) {
|
|
621
658
|
const path = statePath(name);
|
|
622
|
-
if (
|
|
659
|
+
if (existsSync2(path)) {
|
|
623
660
|
unlinkSync(path);
|
|
624
661
|
return true;
|
|
625
662
|
}
|
|
@@ -627,7 +664,8 @@ function deleteState(name) {
|
|
|
627
664
|
}
|
|
628
665
|
var STATES_DIR;
|
|
629
666
|
var init_storage_state = __esm(() => {
|
|
630
|
-
|
|
667
|
+
init_schema();
|
|
668
|
+
STATES_DIR = join3(getDataDir(), "states");
|
|
631
669
|
});
|
|
632
670
|
|
|
633
671
|
// node_modules/sharp/lib/is.js
|
|
@@ -7225,7 +7263,7 @@ var init_snapshots = __esm(() => {
|
|
|
7225
7263
|
|
|
7226
7264
|
// src/server/index.ts
|
|
7227
7265
|
import { join as join7 } from "path";
|
|
7228
|
-
import { existsSync as
|
|
7266
|
+
import { existsSync as existsSync5 } from "fs";
|
|
7229
7267
|
|
|
7230
7268
|
// src/lib/session.ts
|
|
7231
7269
|
init_types();
|
|
@@ -7323,10 +7361,15 @@ class BrowserPool {
|
|
|
7323
7361
|
this.pool.push({ browser, inUse: true, createdAt: Date.now() });
|
|
7324
7362
|
return browser;
|
|
7325
7363
|
}
|
|
7326
|
-
return new Promise((resolve) => {
|
|
7364
|
+
return new Promise((resolve, reject) => {
|
|
7365
|
+
const timeout = setTimeout(() => {
|
|
7366
|
+
clearInterval(interval);
|
|
7367
|
+
reject(new BrowserError("Browser pool exhausted \u2014 no browser became available within 30s", "POOL_TIMEOUT", true));
|
|
7368
|
+
}, 30000);
|
|
7327
7369
|
const interval = setInterval(() => {
|
|
7328
7370
|
const free = this.pool.find((e) => !e.inUse);
|
|
7329
7371
|
if (free) {
|
|
7372
|
+
clearTimeout(timeout);
|
|
7330
7373
|
clearInterval(interval);
|
|
7331
7374
|
free.inUse = true;
|
|
7332
7375
|
resolve(free.browser);
|
|
@@ -7365,7 +7408,7 @@ function isLightpandaAvailable() {
|
|
|
7365
7408
|
const paths = [
|
|
7366
7409
|
"/usr/local/bin/lightpanda",
|
|
7367
7410
|
"/usr/bin/lightpanda",
|
|
7368
|
-
`${process.env["HOME"]}/.browser/bin/lightpanda`
|
|
7411
|
+
`${process.env["HOME"]}/.hasna/browser/bin/lightpanda`
|
|
7369
7412
|
];
|
|
7370
7413
|
return paths.some((p) => {
|
|
7371
7414
|
try {
|
|
@@ -7384,7 +7427,7 @@ function getLightpandaBinaryPath() {
|
|
|
7384
7427
|
"lightpanda",
|
|
7385
7428
|
"/usr/local/bin/lightpanda",
|
|
7386
7429
|
"/usr/bin/lightpanda",
|
|
7387
|
-
`${process.env["HOME"]}/.browser/bin/lightpanda`
|
|
7430
|
+
`${process.env["HOME"]}/.hasna/browser/bin/lightpanda`
|
|
7388
7431
|
];
|
|
7389
7432
|
for (const p of paths) {
|
|
7390
7433
|
try {
|
|
@@ -7452,14 +7495,14 @@ async function connectLightpanda(port) {
|
|
|
7452
7495
|
}
|
|
7453
7496
|
|
|
7454
7497
|
// src/engines/bun-webview.ts
|
|
7498
|
+
init_schema();
|
|
7455
7499
|
import { join as join2 } from "path";
|
|
7456
7500
|
import { mkdirSync as mkdirSync2 } from "fs";
|
|
7457
|
-
import { homedir as homedir2 } from "os";
|
|
7458
7501
|
function isBunWebViewAvailable() {
|
|
7459
7502
|
return typeof globalThis.Bun !== "undefined" && typeof globalThis.Bun.WebView !== "undefined";
|
|
7460
7503
|
}
|
|
7461
7504
|
function getProfileDir(profileName) {
|
|
7462
|
-
const base =
|
|
7505
|
+
const base = getDataDir();
|
|
7463
7506
|
const dir = join2(base, "profiles", profileName);
|
|
7464
7507
|
mkdirSync2(dir, { recursive: true });
|
|
7465
7508
|
return dir;
|
|
@@ -7918,6 +7961,7 @@ function enableNetworkLogging(page, sessionId) {
|
|
|
7918
7961
|
};
|
|
7919
7962
|
const onResponse = (res) => {
|
|
7920
7963
|
const start = requestStart.get(res.url()) ?? Date.now();
|
|
7964
|
+
requestStart.delete(res.url());
|
|
7921
7965
|
const duration = Date.now() - start;
|
|
7922
7966
|
const req = res.request();
|
|
7923
7967
|
try {
|
|
@@ -7934,11 +7978,17 @@ function enableNetworkLogging(page, sessionId) {
|
|
|
7934
7978
|
});
|
|
7935
7979
|
} catch {}
|
|
7936
7980
|
};
|
|
7981
|
+
const onRequestFailed = (req) => {
|
|
7982
|
+
requestStart.delete(req.url());
|
|
7983
|
+
};
|
|
7937
7984
|
page.on("request", onRequest);
|
|
7938
7985
|
page.on("response", onResponse);
|
|
7986
|
+
page.on("requestfailed", onRequestFailed);
|
|
7939
7987
|
return () => {
|
|
7940
7988
|
page.off("request", onRequest);
|
|
7941
7989
|
page.off("response", onResponse);
|
|
7990
|
+
page.off("requestfailed", onRequestFailed);
|
|
7991
|
+
requestStart.clear();
|
|
7942
7992
|
};
|
|
7943
7993
|
}
|
|
7944
7994
|
function startHAR(page) {
|
|
@@ -7957,6 +8007,7 @@ function startHAR(page) {
|
|
|
7957
8007
|
const start = requestStart.get(key);
|
|
7958
8008
|
if (!start)
|
|
7959
8009
|
return;
|
|
8010
|
+
requestStart.delete(key);
|
|
7960
8011
|
const duration = Date.now() - start.time;
|
|
7961
8012
|
const entry = {
|
|
7962
8013
|
startedDateTime: new Date(start.time).toISOString(),
|
|
@@ -7979,15 +8030,20 @@ function startHAR(page) {
|
|
|
7979
8030
|
timings: { send: 0, wait: duration, receive: 0 }
|
|
7980
8031
|
};
|
|
7981
8032
|
entries.push(entry);
|
|
7982
|
-
|
|
8033
|
+
};
|
|
8034
|
+
const onRequestFailed = (req) => {
|
|
8035
|
+
requestStart.delete(req.url() + req.method());
|
|
7983
8036
|
};
|
|
7984
8037
|
page.on("request", onRequest);
|
|
7985
8038
|
page.on("response", onResponse);
|
|
8039
|
+
page.on("requestfailed", onRequestFailed);
|
|
7986
8040
|
return {
|
|
7987
8041
|
entries,
|
|
7988
8042
|
stop: () => {
|
|
7989
8043
|
page.off("request", onRequest);
|
|
7990
8044
|
page.off("response", onResponse);
|
|
8045
|
+
page.off("requestfailed", onRequestFailed);
|
|
8046
|
+
requestStart.clear();
|
|
7991
8047
|
return {
|
|
7992
8048
|
log: {
|
|
7993
8049
|
version: "1.2",
|
|
@@ -8549,7 +8605,6 @@ init_types();
|
|
|
8549
8605
|
var import_sharp = __toESM(require_lib(), 1);
|
|
8550
8606
|
import { join as join4 } from "path";
|
|
8551
8607
|
import { mkdirSync as mkdirSync4 } from "fs";
|
|
8552
|
-
import { homedir as homedir4 } from "os";
|
|
8553
8608
|
|
|
8554
8609
|
// src/db/gallery.ts
|
|
8555
8610
|
init_schema();
|
|
@@ -8678,11 +8733,9 @@ function getGalleryStats(projectId) {
|
|
|
8678
8733
|
}
|
|
8679
8734
|
|
|
8680
8735
|
// src/lib/screenshot.ts
|
|
8681
|
-
|
|
8682
|
-
return process.env["BROWSER_DATA_DIR"] ?? join4(homedir4(), ".browser");
|
|
8683
|
-
}
|
|
8736
|
+
init_schema();
|
|
8684
8737
|
function getScreenshotDir(projectId) {
|
|
8685
|
-
const base = join4(
|
|
8738
|
+
const base = join4(getDataDir(), "screenshots");
|
|
8686
8739
|
const date = new Date().toISOString().split("T")[0];
|
|
8687
8740
|
const dir = projectId ? join4(base, projectId, date) : join4(base, date);
|
|
8688
8741
|
mkdirSync4(dir, { recursive: true });
|
|
@@ -9050,14 +9103,11 @@ init_console_log();
|
|
|
9050
9103
|
init_recordings();
|
|
9051
9104
|
|
|
9052
9105
|
// src/lib/downloads.ts
|
|
9106
|
+
init_schema();
|
|
9053
9107
|
import { join as join5, basename, extname } from "path";
|
|
9054
|
-
import { mkdirSync as mkdirSync5, existsSync as
|
|
9055
|
-
import { homedir as homedir5 } from "os";
|
|
9056
|
-
function getDataDir3() {
|
|
9057
|
-
return process.env["BROWSER_DATA_DIR"] ?? join5(homedir5(), ".browser");
|
|
9058
|
-
}
|
|
9108
|
+
import { mkdirSync as mkdirSync5, existsSync as existsSync3, readdirSync as readdirSync3, statSync as statSync2, unlinkSync as unlinkSync2, copyFileSync as copyFileSync2, writeFileSync, readFileSync } from "fs";
|
|
9059
9109
|
function getDownloadsDir(sessionId) {
|
|
9060
|
-
const base = join5(
|
|
9110
|
+
const base = join5(getDataDir(), "downloads");
|
|
9061
9111
|
const dir = sessionId ? join5(base, sessionId) : base;
|
|
9062
9112
|
mkdirSync5(dir, { recursive: true });
|
|
9063
9113
|
return dir;
|
|
@@ -9069,20 +9119,20 @@ function listDownloads(sessionId) {
|
|
|
9069
9119
|
const dir = getDownloadsDir(sessionId);
|
|
9070
9120
|
const results = [];
|
|
9071
9121
|
function scanDir(d) {
|
|
9072
|
-
if (!
|
|
9122
|
+
if (!existsSync3(d))
|
|
9073
9123
|
return;
|
|
9074
|
-
const entries =
|
|
9124
|
+
const entries = readdirSync3(d);
|
|
9075
9125
|
for (const entry of entries) {
|
|
9076
9126
|
if (entry.endsWith(".meta.json"))
|
|
9077
9127
|
continue;
|
|
9078
9128
|
const full = join5(d, entry);
|
|
9079
|
-
const stat =
|
|
9129
|
+
const stat = statSync2(full);
|
|
9080
9130
|
if (stat.isDirectory()) {
|
|
9081
9131
|
scanDir(full);
|
|
9082
9132
|
continue;
|
|
9083
9133
|
}
|
|
9084
9134
|
const mpath = metaPath(full);
|
|
9085
|
-
if (!
|
|
9135
|
+
if (!existsSync3(mpath))
|
|
9086
9136
|
continue;
|
|
9087
9137
|
try {
|
|
9088
9138
|
const meta = JSON.parse(readFileSync(mpath, "utf8"));
|
|
@@ -9113,7 +9163,7 @@ function deleteDownload(id, sessionId) {
|
|
|
9113
9163
|
return false;
|
|
9114
9164
|
try {
|
|
9115
9165
|
unlinkSync2(file.path);
|
|
9116
|
-
if (
|
|
9166
|
+
if (existsSync3(file.meta_path))
|
|
9117
9167
|
unlinkSync2(file.meta_path);
|
|
9118
9168
|
return true;
|
|
9119
9169
|
} catch {
|
|
@@ -9135,10 +9185,10 @@ function cleanStaleDownloads(olderThanDays = 7) {
|
|
|
9135
9185
|
}
|
|
9136
9186
|
|
|
9137
9187
|
// src/lib/gallery-diff.ts
|
|
9188
|
+
init_schema();
|
|
9138
9189
|
var import_sharp2 = __toESM(require_lib(), 1);
|
|
9139
9190
|
import { join as join6 } from "path";
|
|
9140
9191
|
import { mkdirSync as mkdirSync6 } from "fs";
|
|
9141
|
-
import { homedir as homedir6 } from "os";
|
|
9142
9192
|
async function diffImages(path1, path2) {
|
|
9143
9193
|
const img1 = import_sharp2.default(path1);
|
|
9144
9194
|
const img2 = import_sharp2.default(path2);
|
|
@@ -9169,7 +9219,7 @@ async function diffImages(path1, path2) {
|
|
|
9169
9219
|
diffBuffer[i + 2] = Math.round(raw1[i + 2] * 0.4);
|
|
9170
9220
|
}
|
|
9171
9221
|
}
|
|
9172
|
-
const dataDir =
|
|
9222
|
+
const dataDir = getDataDir();
|
|
9173
9223
|
const diffDir = join6(dataDir, "diffs");
|
|
9174
9224
|
mkdirSync6(diffDir, { recursive: true });
|
|
9175
9225
|
const diffPath = join6(diffDir, `diff-${Date.now()}.webp`);
|
|
@@ -9425,14 +9475,14 @@ var server = Bun.serve({
|
|
|
9425
9475
|
if (path.match(/^\/api\/gallery\/([^/]+)\/thumbnail$/) && method === "GET") {
|
|
9426
9476
|
const id = path.split("/")[3];
|
|
9427
9477
|
const entry = getEntry(id);
|
|
9428
|
-
if (!entry?.thumbnail_path || !
|
|
9478
|
+
if (!entry?.thumbnail_path || !existsSync5(entry.thumbnail_path))
|
|
9429
9479
|
return notFound("Thumbnail not found");
|
|
9430
9480
|
return new Response(Bun.file(entry.thumbnail_path), { headers: { ...CORS_HEADERS } });
|
|
9431
9481
|
}
|
|
9432
9482
|
if (path.match(/^\/api\/gallery\/([^/]+)\/image$/) && method === "GET") {
|
|
9433
9483
|
const id = path.split("/")[3];
|
|
9434
9484
|
const entry = getEntry(id);
|
|
9435
|
-
if (!entry?.path || !
|
|
9485
|
+
if (!entry?.path || !existsSync5(entry.path))
|
|
9436
9486
|
return notFound("Image not found");
|
|
9437
9487
|
return new Response(Bun.file(entry.path), { headers: { ...CORS_HEADERS } });
|
|
9438
9488
|
}
|
|
@@ -9460,7 +9510,7 @@ var server = Bun.serve({
|
|
|
9460
9510
|
if (path.match(/^\/api\/downloads\/([^/]+)\/raw$/) && method === "GET") {
|
|
9461
9511
|
const id = path.split("/")[3];
|
|
9462
9512
|
const file = getDownload(id);
|
|
9463
|
-
if (!file || !
|
|
9513
|
+
if (!file || !existsSync5(file.path))
|
|
9464
9514
|
return notFound("Download not found");
|
|
9465
9515
|
return new Response(Bun.file(file.path), { headers: { ...CORS_HEADERS } });
|
|
9466
9516
|
}
|
|
@@ -9469,9 +9519,9 @@ var server = Bun.serve({
|
|
|
9469
9519
|
return ok({ deleted: deleteDownload(id) });
|
|
9470
9520
|
}
|
|
9471
9521
|
const dashboardDist = join7(import.meta.dir, "../../dashboard/dist");
|
|
9472
|
-
if (
|
|
9522
|
+
if (existsSync5(dashboardDist)) {
|
|
9473
9523
|
const filePath = path === "/" ? join7(dashboardDist, "index.html") : join7(dashboardDist, path);
|
|
9474
|
-
if (
|
|
9524
|
+
if (existsSync5(filePath)) {
|
|
9475
9525
|
return new Response(Bun.file(filePath), { headers: CORS_HEADERS });
|
|
9476
9526
|
}
|
|
9477
9527
|
return new Response(Bun.file(join7(dashboardDist, "index.html")), { headers: CORS_HEADERS });
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hasna/browser",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.4",
|
|
4
4
|
"description": "General-purpose browser agent toolkit — Playwright, Chrome DevTools Protocol, Lightpanda with auto engine selection. CLI + MCP + REST + SDK.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|