nothing-browser 0.1.0 → 0.1.2

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/piggy.js CHANGED
@@ -7279,6 +7279,24 @@ class PiggyClient {
7279
7279
  }
7280
7280
  }
7281
7281
  }
7282
+ if (event.event === "dialog") {
7283
+ const key = `dialog:${event.tabId ?? "default"}`;
7284
+ const handlers = this.globalEventHandlers.get(key);
7285
+ if (handlers) {
7286
+ for (const h of handlers) {
7287
+ try {
7288
+ h({
7289
+ dialogType: event.dialogType,
7290
+ message: event.message,
7291
+ defaultValue: event.defaultValue,
7292
+ tabId: event.tabId
7293
+ });
7294
+ } catch (e) {
7295
+ logger_default.error(`dialog handler error: ${e}`);
7296
+ }
7297
+ }
7298
+ }
7299
+ }
7282
7300
  }
7283
7301
  onEvent(eventName, tabId, handler) {
7284
7302
  const key = `${eventName}:${tabId}`;
@@ -7426,14 +7444,14 @@ class PiggyClient {
7426
7444
  async setCookie(name, value, domain, path = "/", tabId = "default") {
7427
7445
  await this.send("cookie.set", { name, value, domain, path, tabId });
7428
7446
  }
7429
- async getCookie(name, tabId = "default") {
7430
- return this.send("cookie.get", { name, tabId });
7447
+ async getCookie(name, domain = "", tabId = "default") {
7448
+ return this.send("cookie.get", { name, domain, tabId });
7431
7449
  }
7432
- async deleteCookie(name, tabId = "default") {
7433
- await this.send("cookie.delete", { name, tabId });
7450
+ async deleteCookie(name, domain, tabId = "default") {
7451
+ await this.send("cookie.delete", { name, domain, tabId });
7434
7452
  }
7435
- async listCookies(tabId = "default") {
7436
- return this.send("cookie.list", { tabId });
7453
+ async listCookies(domain = "", tabId = "default") {
7454
+ return this.send("cookie.list", { domain, tabId });
7437
7455
  }
7438
7456
  async addInterceptRule(action, pattern, options = {}, tabId = "default") {
7439
7457
  await this.send("intercept.rule.add", { action, pattern, ...options, tabId });
@@ -28617,174 +28635,511 @@ async function storeRecord(storeName, data) {
28617
28635
  return { stored, skipped };
28618
28636
  }
28619
28637
 
28620
- // piggy/register/index.ts
28621
- var globalClient = null;
28622
- var humanMode = false;
28623
- function setClient(c) {
28624
- globalClient = c;
28638
+ // piggy/find/index.ts
28639
+ class FindClient {
28640
+ client;
28641
+ constructor(client) {
28642
+ this.client = client;
28643
+ }
28644
+ css(selector, tabId = "default") {
28645
+ return this.client.send("find.css", { selector, tabId });
28646
+ }
28647
+ all(selector, tabId = "default") {
28648
+ return this.client.send("find.all", { selector, tabId });
28649
+ }
28650
+ first(selector, tabId = "default") {
28651
+ return this.client.send("find.first", { selector, tabId });
28652
+ }
28653
+ byText(text, tabId = "default") {
28654
+ return this.client.send("find.byText", { text, tabId });
28655
+ }
28656
+ byAttr(attr, value, tabId = "default") {
28657
+ return this.client.send("find.byAttr", { attr, value, tabId });
28658
+ }
28659
+ byTag(tag, tabId = "default") {
28660
+ return this.client.send("find.byTag", { tag, tabId });
28661
+ }
28662
+ byPlaceholder(text, tabId = "default") {
28663
+ return this.client.send("find.byPlaceholder", { text, tabId });
28664
+ }
28665
+ byRole(role, name, tabId = "default") {
28666
+ return this.client.send("find.byRole", { role, name, tabId });
28667
+ }
28668
+ children(selector, tabId = "default") {
28669
+ return this.client.send("find.children", { selector, tabId });
28670
+ }
28671
+ parent(selector, tabId = "default") {
28672
+ return this.client.send("find.parent", { selector, tabId });
28673
+ }
28674
+ closest(selector, ancestor, tabId = "default") {
28675
+ return this.client.send("find.closest", { selector, ancestor, tabId });
28676
+ }
28677
+ count(selector, tabId = "default") {
28678
+ return this.client.send("find.count", { selector, tabId });
28679
+ }
28680
+ exists(selector, tabId = "default") {
28681
+ return this.client.send("find.exists", { selector, tabId });
28682
+ }
28683
+ visible(selector, tabId = "default") {
28684
+ return this.client.send("find.visible", { selector, tabId });
28685
+ }
28686
+ enabled(selector, tabId = "default") {
28687
+ return this.client.send("find.enabled", { selector, tabId });
28688
+ }
28689
+ checked(selector, tabId = "default") {
28690
+ return this.client.send("find.checked", { selector, tabId });
28691
+ }
28625
28692
  }
28626
- function setHumanMode(v) {
28627
- humanMode = v;
28693
+ function createFindAPI(client) {
28694
+ return new FindClient(client);
28628
28695
  }
28629
- async function retry(label, fn, retries = 2, backoff = 150) {
28630
- let last;
28631
- for (let i = 0;i <= retries; i++) {
28632
- try {
28633
- return await fn();
28634
- } catch (e) {
28635
- last = e;
28636
- if (i < retries) {
28637
- logger_default.warn(`[${label}] retry ${i + 1}/${retries}: ${e.message}`);
28638
- await new Promise((r) => setTimeout(r, backoff * (i + 1)));
28639
- }
28640
- }
28696
+
28697
+ // piggy/provide/index.ts
28698
+ class ProvideClient {
28699
+ client;
28700
+ constructor(client) {
28701
+ this.client = client;
28702
+ }
28703
+ text(opts, tabId = "default") {
28704
+ return this.client.send("provide.text", { ...opts, tabId });
28705
+ }
28706
+ textAll(opts, tabId = "default") {
28707
+ return this.client.send("provide.textAll", { ...opts, tabId });
28708
+ }
28709
+ attr(opts, tabId = "default") {
28710
+ return this.client.send("provide.attr", { ...opts, tabId });
28711
+ }
28712
+ attrAll(opts, tabId = "default") {
28713
+ return this.client.send("provide.attrAll", { ...opts, tabId });
28714
+ }
28715
+ html(opts, tabId = "default") {
28716
+ return this.client.send("provide.html", { ...opts, tabId });
28717
+ }
28718
+ table(opts, tabId = "default") {
28719
+ return this.client.send("provide.table", { ...opts, tabId });
28720
+ }
28721
+ list(opts, tabId = "default") {
28722
+ return this.client.send("provide.list", { ...opts, tabId });
28723
+ }
28724
+ links(opts, tabId = "default") {
28725
+ return this.client.send("provide.links", { ...opts, tabId });
28726
+ }
28727
+ images(opts, tabId = "default") {
28728
+ return this.client.send("provide.images", { ...opts, tabId });
28729
+ }
28730
+ form(opts, tabId = "default") {
28731
+ return this.client.send("provide.form", { ...opts, tabId });
28732
+ }
28733
+ page(tabId = "default") {
28734
+ return this.client.send("provide.page", { tabId });
28735
+ }
28736
+ div(opts, tabId = "default") {
28737
+ return this.client.send("provide.div", { ...opts, tabId });
28738
+ }
28739
+ meta(tabId = "default") {
28740
+ return this.client.send("provide.meta", { tabId });
28741
+ }
28742
+ select(opts, tabId = "default") {
28743
+ return this.client.send("provide.select", { ...opts, tabId });
28744
+ }
28745
+ json(opts, tabId = "default") {
28746
+ return this.client.send("provide.json", { ...opts, tabId });
28641
28747
  }
28642
- throw last;
28643
28748
  }
28644
- function createSiteObject(name, registeredUrl, client, tabId, pool) {
28645
- let _currentUrl = registeredUrl;
28646
- let _modifyRuleCounter = 0;
28647
- function withTab(fn) {
28648
- return pool ? pool.withTab(fn) : fn(tabId);
28749
+ function createProvideAPI(client) {
28750
+ return new ProvideClient(client);
28751
+ }
28752
+
28753
+ // piggy/session/index.ts
28754
+ class SessionClient {
28755
+ client;
28756
+ constructor(client) {
28757
+ this.client = client;
28649
28758
  }
28650
- const _eventListeners = new Map;
28651
- const _unsubNavigate = client.onEvent("navigate", tabId, (url2) => {
28652
- _currentUrl = url2;
28653
- const handlers = _eventListeners.get("navigate");
28654
- if (handlers) {
28655
- for (const h of handlers) {
28656
- try {
28657
- h(url2);
28658
- } catch (e) {
28659
- logger_default.error(`[${name}] navigate handler error: ${e}`);
28660
- }
28661
- }
28662
- }
28663
- });
28664
- const withErrScreen = async (fn, label) => {
28665
- try {
28666
- return await fn();
28667
- } catch (err) {
28668
- const p = `./error-${name}-${Date.now()}.png`;
28669
- try {
28670
- await client.screenshot(p, tabId);
28671
- logger_default.error(`[${name}] ${label} failed → ${p}`);
28672
- } catch {
28673
- logger_default.error(`[${name}] ${label} failed (no screenshot)`);
28674
- }
28675
- throw err;
28676
- }
28677
- };
28678
- const site = {
28679
- _name: name,
28680
- _tabId: tabId,
28681
- _pool: pool ?? null,
28682
- poolStats: () => pool?.stats ?? null,
28683
- navigate: (url2, opts) => {
28684
- const target = url2 ?? registeredUrl;
28685
- return withTab((t2) => retry(name, async () => {
28686
- logger_default.network(`[${name}] navigating → ${target}`);
28687
- await client.navigate(target, t2);
28688
- _currentUrl = target;
28689
- }, opts?.retries ?? 2));
28690
- },
28691
- reload: () => withTab((t2) => client.reload(t2)),
28692
- goBack: () => withTab((t2) => client.goBack(t2)),
28693
- goForward: () => withTab((t2) => client.goForward(t2)),
28694
- waitForNavigation: () => withTab((t2) => client.waitForNavigation(t2)),
28695
- title: () => withTab(async (t2) => {
28696
- const title = await client.getTitle(t2);
28697
- logger_default.info(`[${name}] title: ${title}`);
28698
- return title;
28699
- }),
28700
- url: () => _currentUrl,
28701
- content: () => withTab((t2) => client.content(t2)),
28702
- wait: (ms) => {
28703
- const actual = humanMode ? ms + Math.floor(Math.random() * 600) - 300 : ms;
28704
- return new Promise((r) => setTimeout(r, Math.max(0, actual)));
28705
- },
28706
- waitForSelector: (selector, timeout = 30000) => withTab((t2) => {
28707
- logger_default.debug(`[${name}] waitForSelector: ${selector}`);
28708
- return client.waitForSelector(selector, timeout, t2);
28709
- }),
28710
- waitForVisible: (selector, timeout = 30000) => withTab((t2) => client.waitForSelector(selector, timeout, t2)),
28711
- waitForResponse: (pattern, timeout = 30000) => withTab((t2) => client.waitForResponse(pattern, timeout, t2)),
28712
- addInitScript: async (js) => {
28713
- const code = typeof js === "function" ? `(${js.toString()})();` : js;
28714
- await withTab((t2) => client.addInitScript(code, t2));
28715
- logger_default.success(`[${name}] init script added`);
28716
- return site;
28717
- },
28718
- on: (event, handler) => {
28719
- if (!_eventListeners.has(event))
28720
- _eventListeners.set(event, new Set);
28721
- _eventListeners.get(event).add(handler);
28722
- logger_default.debug(`[${name}] on('${event}') registered`);
28723
- return () => {
28724
- _eventListeners.get(event)?.delete(handler);
28725
- logger_default.debug(`[${name}] on('${event}') unsubscribed`);
28726
- };
28727
- },
28728
- off: (event, handler) => {
28729
- _eventListeners.get(event)?.delete(handler);
28730
- },
28731
- click: (selector, opts) => withErrScreen(() => withTab((t2) => retry(name, async () => {
28732
- if (humanMode)
28733
- await new Promise((r) => setTimeout(r, 80 + Math.random() * 140));
28734
- await client.waitForSelector(selector, opts?.timeout ?? 15000, t2);
28735
- const ok = await client.click(selector, t2);
28736
- if (!ok)
28737
- throw new Error(`click failed: ${selector}`);
28738
- logger_default.success(`[${name}] clicked: ${selector}`);
28739
- return ok;
28740
- }, opts?.retries ?? 2)), `click(${selector})`),
28741
- doubleClick: (selector) => withErrScreen(() => withTab(async (t2) => {
28742
- if (humanMode)
28743
- await new Promise((r) => setTimeout(r, 80 + Math.random() * 120));
28744
- return client.doubleClick(selector, t2);
28745
- }), `dblclick(${selector})`),
28746
- hover: (selector) => withErrScreen(() => withTab(async (t2) => {
28747
- if (humanMode)
28748
- await new Promise((r) => setTimeout(r, 50 + Math.random() * 100));
28749
- return client.hover(selector, t2);
28750
- }), `hover(${selector})`),
28751
- type: (selector, text, opts) => withErrScreen(() => withTab(async (t2) => {
28752
- await client.waitForSelector(selector, 30000, t2);
28753
- if (humanMode) {
28754
- const human = new HumanClient(client);
28755
- await human.type({
28756
- selector,
28757
- text,
28758
- clear: opts?.clear ?? false,
28759
- speed: opts?.speed
28760
- }, t2);
28761
- } else {
28762
- if (opts?.clear) {
28763
- await client.evaluate(`
28764
- const el = document.querySelector('${selector.replace(/'/g, "\\'")}');
28765
- if (el) { el.value = ''; el.dispatchEvent(new Event('input', { bubbles: true })); }
28766
- `, t2);
28767
- }
28768
- await client.type(selector, text, t2);
28769
- }
28770
- await client.evaluate(`
28771
- document.querySelector('${selector.replace(/'/g, "\\'")}')?.dispatchEvent(new Event('blur', { bubbles: true }));
28772
- `, t2);
28773
- logger_default.success(`[${name}] typed into: ${selector}`);
28774
- return true;
28775
- }), `type(${selector})`),
28776
- select: (selector, value) => withTab((t2) => client.select(selector, value, t2)),
28777
- evaluate: (js, ...args) => {
28778
- const code = typeof js === "function" ? `(${js.toString()})(${args.map((a) => JSON.stringify(a)).join(",")})` : js;
28779
- return withTab((t2) => client.evaluate(code, t2));
28780
- },
28781
- keyboard: {
28782
- press: (key) => withTab((t2) => client.keyPress(key, t2)),
28783
- combo: (combo) => withTab((t2) => client.keyCombo(combo, t2))
28784
- },
28785
- mouse: {
28786
- move: (x, y) => withTab((t2) => client.mouseMove(x, y, t2)),
28787
- drag: (from, to) => withTab((t2) => client.mouseDrag(from, to, t2))
28759
+ reload(tabId = "default") {
28760
+ return this.client.send("session.reload", { tabId });
28761
+ }
28762
+ paths() {
28763
+ return this.client.send("session.paths", {});
28764
+ }
28765
+ cookiesPath() {
28766
+ return this.client.send("session.cookies.path", {});
28767
+ }
28768
+ profilePath() {
28769
+ return this.client.send("session.profile.path", {});
28770
+ }
28771
+ wsPath() {
28772
+ return this.client.send("session.ws.path", {});
28773
+ }
28774
+ pingsPath() {
28775
+ return this.client.send("session.pings.path", {});
28776
+ }
28777
+ setWsSave(enabled) {
28778
+ return this.client.send("session.ws.save", { enabled });
28779
+ }
28780
+ setPingsSave(enabled) {
28781
+ return this.client.send("session.pings.save", { enabled });
28782
+ }
28783
+ async export(tabId = "default") {
28784
+ const raw = await this.client.send("session.export", { tabId });
28785
+ return typeof raw === "string" ? JSON.parse(raw) : raw;
28786
+ }
28787
+ import(data, tabId = "default") {
28788
+ return this.client.send("session.import", {
28789
+ data: JSON.stringify(data),
28790
+ tabId
28791
+ });
28792
+ }
28793
+ setCookie(opts, tabId = "default") {
28794
+ return this.client.send("cookie.set", { ...opts, tabId });
28795
+ }
28796
+ deleteCookie(opts, tabId = "default") {
28797
+ return this.client.send("cookie.delete", { ...opts, tabId });
28798
+ }
28799
+ }
28800
+ function createSessionAPI(client) {
28801
+ return new SessionClient(client);
28802
+ }
28803
+
28804
+ // piggy/dialog/index.ts
28805
+ class DialogClient {
28806
+ client;
28807
+ constructor(client) {
28808
+ this.client = client;
28809
+ }
28810
+ accept(tabId = "default", text) {
28811
+ return this.client.send("dialog.accept", { tabId, ...text !== undefined ? { text } : {} });
28812
+ }
28813
+ dismiss(tabId = "default") {
28814
+ return this.client.send("dialog.dismiss", { tabId });
28815
+ }
28816
+ status(tabId = "default") {
28817
+ return this.client.send("dialog.status", { tabId });
28818
+ }
28819
+ setAutoAction(tabId = "default", action) {
28820
+ return this.client.send("dialog.onDialog", { tabId, action });
28821
+ }
28822
+ upload(selector, filePath, tabId = "default") {
28823
+ return this.client.send("upload", { selector, path: filePath, tabId });
28824
+ }
28825
+ onDialog(tabId, handler) {
28826
+ return this.client.onEvent("dialog", tabId, handler);
28827
+ }
28828
+ waitAndAccept(tabId = "default", text, timeoutMs = 30000) {
28829
+ return new Promise((resolve2, reject) => {
28830
+ const timer = setTimeout(() => {
28831
+ unsub();
28832
+ reject(new Error(`dialog.waitAndAccept: timed out after ${timeoutMs}ms`));
28833
+ }, timeoutMs);
28834
+ const unsub = this.onDialog(tabId, async (data) => {
28835
+ clearTimeout(timer);
28836
+ unsub();
28837
+ await this.accept(tabId, text);
28838
+ resolve2(data);
28839
+ });
28840
+ });
28841
+ }
28842
+ waitAndDismiss(tabId = "default", timeoutMs = 30000) {
28843
+ return new Promise((resolve2, reject) => {
28844
+ const timer = setTimeout(() => {
28845
+ unsub();
28846
+ reject(new Error(`dialog.waitAndDismiss: timed out after ${timeoutMs}ms`));
28847
+ }, timeoutMs);
28848
+ const unsub = this.onDialog(tabId, async (data) => {
28849
+ clearTimeout(timer);
28850
+ unsub();
28851
+ await this.dismiss(tabId);
28852
+ resolve2(data);
28853
+ });
28854
+ });
28855
+ }
28856
+ }
28857
+ function createDialogAPI(client) {
28858
+ return new DialogClient(client);
28859
+ }
28860
+
28861
+ // piggy/iframe/index.ts
28862
+ class IframeClient {
28863
+ client;
28864
+ constructor(client) {
28865
+ this.client = client;
28866
+ }
28867
+ list(tabId = "default") {
28868
+ return this.client.send("iframe.list", { tabId });
28869
+ }
28870
+ evaluate(opts, tabId = "default") {
28871
+ return this.client.send("iframe.evaluate", { ...opts, tabId });
28872
+ }
28873
+ click(opts, tabId = "default") {
28874
+ return this.client.send("iframe.click", { ...opts, tabId });
28875
+ }
28876
+ type(opts, tabId = "default") {
28877
+ return this.client.send("iframe.type", { ...opts, tabId });
28878
+ }
28879
+ text(opts, tabId = "default") {
28880
+ return this.client.send("iframe.text", { ...opts, tabId });
28881
+ }
28882
+ html(opts, tabId = "default") {
28883
+ return this.client.send("iframe.html", { ...opts, tabId });
28884
+ }
28885
+ waitSel(opts, tabId = "default") {
28886
+ return this.client.send("iframe.waitSel", { ...opts, tabId });
28887
+ }
28888
+ }
28889
+ function createIframeAPI(client) {
28890
+ return new IframeClient(client);
28891
+ }
28892
+
28893
+ // piggy/expose/index.ts
28894
+ async function exposeFunction(client, fnName, handler, tabId) {
28895
+ await client.exposeFunction(fnName, handler, tabId);
28896
+ logger_default.success(`[${tabId}] exposed function: ${fnName}`);
28897
+ }
28898
+ async function unexposeFunction(client, fnName, tabId) {
28899
+ await client.unexposeFunction(fnName, tabId);
28900
+ logger_default.info(`[${tabId}] unexposed function: ${fnName}`);
28901
+ }
28902
+ async function clearExposedFunctions(client, tabId) {
28903
+ await client.clearExposedFunctions(tabId);
28904
+ logger_default.info(`[${tabId}] cleared all exposed functions`);
28905
+ }
28906
+ async function exposeAndInject(client, fnName, handler, injectionJs, tabId) {
28907
+ await client.exposeFunction(fnName, handler, tabId);
28908
+ const js = typeof injectionJs === "function" ? injectionJs(fnName) : injectionJs;
28909
+ await client.evaluate(js, tabId);
28910
+ logger_default.success(`[${tabId}] exposed and injected: ${fnName}`);
28911
+ }
28912
+
28913
+ // piggy/captcha/index.ts
28914
+ class CaptchaClient {
28915
+ client;
28916
+ constructor(client) {
28917
+ this.client = client;
28918
+ }
28919
+ status(tabId = "default") {
28920
+ return this.client.send("captcha.status", { tabId });
28921
+ }
28922
+ resolve(tabId = "default") {
28923
+ return this.client.send("captcha.resolve", { tabId });
28924
+ }
28925
+ pause(tabId = "default") {
28926
+ return this.client.send("captcha.pause", { tabId });
28927
+ }
28928
+ check(tabId = "default") {
28929
+ return this.client.send("captcha.check", { tabId });
28930
+ }
28931
+ setAutoRetry(enabled) {
28932
+ return this.client.send("captcha.autoRetry", { enabled });
28933
+ }
28934
+ blockStatus(tabId = "default") {
28935
+ return this.client.send("block.status", { tabId });
28936
+ }
28937
+ blockRetry(tabId = "default") {
28938
+ return this.client.send("block.retry", { tabId });
28939
+ }
28940
+ onCaptcha(tabId, handler) {
28941
+ return this.client.onEvent("captcha", tabId, handler);
28942
+ }
28943
+ onCaptchaResolved(tabId, handler) {
28944
+ return this.client.onEvent("captcha:resolved", tabId, handler);
28945
+ }
28946
+ onBlocked(tabId, handler) {
28947
+ return this.client.onEvent("blocked", tabId, handler);
28948
+ }
28949
+ onBlockRetry(tabId, handler) {
28950
+ return this.client.onEvent("block:retry", tabId, handler);
28951
+ }
28952
+ waitForResolution(tabId = "default", timeoutMs = 300000) {
28953
+ return new Promise((resolve2, reject) => {
28954
+ const timer = setTimeout(() => {
28955
+ unsub();
28956
+ reject(new Error(`captcha.waitForResolution: timed out after ${timeoutMs}ms`));
28957
+ }, timeoutMs);
28958
+ const unsub = this.onCaptchaResolved(tabId, () => {
28959
+ clearTimeout(timer);
28960
+ unsub();
28961
+ resolve2();
28962
+ });
28963
+ logger_default.warn(`[captcha] waiting for manual resolution on tab ${tabId}…`);
28964
+ });
28965
+ }
28966
+ }
28967
+ function createCaptchaAPI(client) {
28968
+ return new CaptchaClient(client);
28969
+ }
28970
+
28971
+ // piggy/register/index.ts
28972
+ var globalClient = null;
28973
+ var humanMode = false;
28974
+ function setClient(c) {
28975
+ globalClient = c;
28976
+ }
28977
+ function setHumanMode(v) {
28978
+ humanMode = v;
28979
+ }
28980
+ async function retry(label, fn, retries = 2, backoff = 150) {
28981
+ let last;
28982
+ for (let i = 0;i <= retries; i++) {
28983
+ try {
28984
+ return await fn();
28985
+ } catch (e) {
28986
+ last = e;
28987
+ if (i < retries) {
28988
+ logger_default.warn(`[${label}] retry ${i + 1}/${retries}: ${e.message}`);
28989
+ await new Promise((r) => setTimeout(r, backoff * (i + 1)));
28990
+ }
28991
+ }
28992
+ }
28993
+ throw last;
28994
+ }
28995
+ function createSiteObject(name, registeredUrl, client, tabId, pool) {
28996
+ let _currentUrl = registeredUrl;
28997
+ let _modifyRuleCounter = 0;
28998
+ function withTab(fn) {
28999
+ return pool ? pool.withTab(fn) : fn(tabId);
29000
+ }
29001
+ const _eventListeners = new Map;
29002
+ const _unsubNavigate = client.onEvent("navigate", tabId, (url2) => {
29003
+ _currentUrl = url2;
29004
+ const handlers = _eventListeners.get("navigate");
29005
+ if (handlers) {
29006
+ for (const h of handlers) {
29007
+ try {
29008
+ h(url2);
29009
+ } catch (e) {
29010
+ logger_default.error(`[${name}] navigate handler error: ${e}`);
29011
+ }
29012
+ }
29013
+ }
29014
+ });
29015
+ const withErrScreen = async (fn, label) => {
29016
+ try {
29017
+ return await fn();
29018
+ } catch (err) {
29019
+ const p = `./error-${name}-${Date.now()}.png`;
29020
+ try {
29021
+ await client.screenshot(p, tabId);
29022
+ logger_default.error(`[${name}] ${label} failed → ${p}`);
29023
+ } catch {
29024
+ logger_default.error(`[${name}] ${label} failed (no screenshot)`);
29025
+ }
29026
+ throw err;
29027
+ }
29028
+ };
29029
+ const site = {
29030
+ _name: name,
29031
+ _tabId: tabId,
29032
+ _pool: pool ?? null,
29033
+ poolStats: () => pool?.stats ?? null,
29034
+ navigate: (url2, opts) => {
29035
+ const target = url2 ?? registeredUrl;
29036
+ return withTab((t2) => retry(name, async () => {
29037
+ logger_default.network(`[${name}] navigating → ${target}`);
29038
+ await client.navigate(target, t2);
29039
+ _currentUrl = target;
29040
+ }, opts?.retries ?? 2));
29041
+ },
29042
+ reload: () => withTab((t2) => client.reload(t2)),
29043
+ goBack: () => withTab((t2) => client.goBack(t2)),
29044
+ goForward: () => withTab((t2) => client.goForward(t2)),
29045
+ waitForNavigation: () => withTab((t2) => client.waitForNavigation(t2)),
29046
+ title: () => withTab(async (t2) => {
29047
+ const title = await client.getTitle(t2);
29048
+ logger_default.info(`[${name}] title: ${title}`);
29049
+ return title;
29050
+ }),
29051
+ url: () => _currentUrl,
29052
+ content: () => withTab((t2) => client.content(t2)),
29053
+ wait: (ms) => {
29054
+ const actual = humanMode ? ms + Math.floor(Math.random() * 600) - 300 : ms;
29055
+ return new Promise((r) => setTimeout(r, Math.max(0, actual)));
29056
+ },
29057
+ waitForSelector: (selector, timeout = 30000) => withTab((t2) => {
29058
+ logger_default.debug(`[${name}] waitForSelector: ${selector}`);
29059
+ return client.waitForSelector(selector, timeout, t2);
29060
+ }),
29061
+ exposeFunction: (fnName, handler) => exposeFunction(client, fnName, handler, tabId).then(() => site),
29062
+ unexposeFunction: (fnName) => unexposeFunction(client, fnName, tabId).then(() => site),
29063
+ clearExposedFunctions: () => clearExposedFunctions(client, tabId).then(() => site),
29064
+ exposeAndInject: (fnName, handler, injectionJs) => exposeAndInject(client, fnName, handler, injectionJs, tabId).then(() => site),
29065
+ waitForVisible: (selector, timeout = 30000) => withTab((t2) => client.waitForSelector(selector, timeout, t2)),
29066
+ waitForResponse: (pattern, timeout = 30000) => withTab((t2) => client.waitForResponse(pattern, timeout, t2)),
29067
+ addInitScript: async (js) => {
29068
+ const code = typeof js === "function" ? `(${js.toString()})();` : js;
29069
+ await withTab((t2) => client.addInitScript(code, t2));
29070
+ logger_default.success(`[${name}] init script added`);
29071
+ return site;
29072
+ },
29073
+ on: (event, handler) => {
29074
+ if (!_eventListeners.has(event))
29075
+ _eventListeners.set(event, new Set);
29076
+ _eventListeners.get(event).add(handler);
29077
+ logger_default.debug(`[${name}] on('${event}') registered`);
29078
+ return () => {
29079
+ _eventListeners.get(event)?.delete(handler);
29080
+ logger_default.debug(`[${name}] on('${event}') unsubscribed`);
29081
+ };
29082
+ },
29083
+ off: (event, handler) => {
29084
+ _eventListeners.get(event)?.delete(handler);
29085
+ },
29086
+ click: (selector, opts) => withErrScreen(() => withTab((t2) => retry(name, async () => {
29087
+ if (humanMode)
29088
+ await new Promise((r) => setTimeout(r, 80 + Math.random() * 140));
29089
+ await client.waitForSelector(selector, opts?.timeout ?? 15000, t2);
29090
+ const ok = await client.click(selector, t2);
29091
+ if (!ok)
29092
+ throw new Error(`click failed: ${selector}`);
29093
+ logger_default.success(`[${name}] clicked: ${selector}`);
29094
+ return ok;
29095
+ }, opts?.retries ?? 2)), `click(${selector})`),
29096
+ doubleClick: (selector) => withErrScreen(() => withTab(async (t2) => {
29097
+ if (humanMode)
29098
+ await new Promise((r) => setTimeout(r, 80 + Math.random() * 120));
29099
+ return client.doubleClick(selector, t2);
29100
+ }), `dblclick(${selector})`),
29101
+ hover: (selector) => withErrScreen(() => withTab(async (t2) => {
29102
+ if (humanMode)
29103
+ await new Promise((r) => setTimeout(r, 50 + Math.random() * 100));
29104
+ return client.hover(selector, t2);
29105
+ }), `hover(${selector})`),
29106
+ type: (selector, text, opts) => withErrScreen(() => withTab(async (t2) => {
29107
+ await client.waitForSelector(selector, 30000, t2);
29108
+ if (humanMode) {
29109
+ const human = new HumanClient(client);
29110
+ await human.type({
29111
+ selector,
29112
+ text,
29113
+ clear: opts?.clear ?? false,
29114
+ speed: opts?.speed
29115
+ }, t2);
29116
+ } else {
29117
+ if (opts?.clear) {
29118
+ await client.evaluate(`
29119
+ const el = document.querySelector('${selector.replace(/'/g, "\\'")}');
29120
+ if (el) { el.value = ''; el.dispatchEvent(new Event('input', { bubbles: true })); }
29121
+ `, t2);
29122
+ }
29123
+ await client.type(selector, text, t2);
29124
+ }
29125
+ await client.evaluate(`
29126
+ document.querySelector('${selector.replace(/'/g, "\\'")}')?.dispatchEvent(new Event('blur', { bubbles: true }));
29127
+ `, t2);
29128
+ logger_default.success(`[${name}] typed into: ${selector}`);
29129
+ return true;
29130
+ }), `type(${selector})`),
29131
+ select: (selector, value) => withTab((t2) => client.select(selector, value, t2)),
29132
+ evaluate: (js, ...args) => {
29133
+ const code = typeof js === "function" ? `(${js.toString()})(${args.map((a) => JSON.stringify(a)).join(",")})` : js;
29134
+ return withTab((t2) => client.evaluate(code, t2));
29135
+ },
29136
+ keyboard: {
29137
+ press: (key) => withTab((t2) => client.keyPress(key, t2)),
29138
+ combo: (combo) => withTab((t2) => client.keyCombo(combo, t2))
29139
+ },
29140
+ mouse: {
29141
+ move: (x, y) => withTab((t2) => client.mouseMove(x, y, t2)),
29142
+ drag: (from, to) => withTab((t2) => client.mouseDrag(from, to, t2))
28788
29143
  },
28789
29144
  scroll: {
28790
29145
  to: (selector) => withTab((t2) => client.scrollTo(selector, t2)),
@@ -28816,6 +29171,68 @@ function createSiteObject(name, registeredUrl, client, tabId, pool) {
28816
29171
  css: (query) => withTab((t2) => client.searchCss(query, t2)),
28817
29172
  id: (query) => withTab((t2) => client.searchId(query, t2))
28818
29173
  },
29174
+ captcha: {
29175
+ status: () => withTab((t2) => createCaptchaAPI(client).status(t2)),
29176
+ resolve: () => withTab((t2) => createCaptchaAPI(client).resolve(t2)),
29177
+ pause: () => withTab((t2) => createCaptchaAPI(client).pause(t2)),
29178
+ check: () => withTab((t2) => createCaptchaAPI(client).check(t2)),
29179
+ autoRetry: (opts) => withTab((t2) => createCaptchaAPI(client).setAutoRetry(opts.enabled)),
29180
+ onCaptcha: (handler) => createCaptchaAPI(client).onCaptcha(tabId, handler),
29181
+ onResolved: (handler) => createCaptchaAPI(client).onCaptchaResolved(tabId, handler)
29182
+ },
29183
+ block: {
29184
+ status: () => withTab((t2) => createCaptchaAPI(client).blockStatus(t2)),
29185
+ retry: () => withTab((t2) => createCaptchaAPI(client).blockRetry(t2)),
29186
+ onBlocked: (handler) => createCaptchaAPI(client).onBlocked(tabId, handler),
29187
+ onRetry: (handler) => createCaptchaAPI(client).onBlockRetry(tabId, handler)
29188
+ },
29189
+ find: {
29190
+ css: (selector) => withTab((t2) => {
29191
+ console.log("[DEBUG] find.css tabId:", t2);
29192
+ return createFindAPI(client).css(selector, t2);
29193
+ }),
29194
+ all: (selector) => withTab((t2) => createFindAPI(client).all(selector, t2)),
29195
+ first: (selector) => withTab((t2) => createFindAPI(client).first(selector, t2)),
29196
+ byText: (text) => withTab((t2) => createFindAPI(client).byText(text, t2)),
29197
+ byAttr: (attr, value) => withTab((t2) => createFindAPI(client).byAttr(attr, value, t2)),
29198
+ byTag: (tag) => withTab((t2) => createFindAPI(client).byTag(tag, t2)),
29199
+ byPlaceholder: (text) => withTab((t2) => createFindAPI(client).byPlaceholder(text, t2)),
29200
+ byRole: (role, name2) => withTab((t2) => createFindAPI(client).byRole(role, name2, t2)),
29201
+ children: (selector) => withTab((t2) => createFindAPI(client).children(selector, t2)),
29202
+ parent: (selector) => withTab((t2) => createFindAPI(client).parent(selector, t2)),
29203
+ closest: (selector, ancestor) => withTab((t2) => createFindAPI(client).closest(selector, ancestor, t2)),
29204
+ count: (selector) => withTab((t2) => createFindAPI(client).count(selector, t2)),
29205
+ exists: (selector) => withTab((t2) => createFindAPI(client).exists(selector, t2)),
29206
+ visible: (selector) => withTab((t2) => createFindAPI(client).visible(selector, t2)),
29207
+ enabled: (selector) => withTab((t2) => createFindAPI(client).enabled(selector, t2)),
29208
+ checked: (selector) => withTab((t2) => createFindAPI(client).checked(selector, t2))
29209
+ },
29210
+ provide: {
29211
+ text: (opts) => withTab((t2) => createProvideAPI(client).text(opts, t2)),
29212
+ textAll: (opts) => withTab((t2) => createProvideAPI(client).textAll(opts, t2)),
29213
+ attr: (opts) => withTab((t2) => createProvideAPI(client).attr(opts, t2)),
29214
+ attrAll: (opts) => withTab((t2) => createProvideAPI(client).attrAll(opts, t2)),
29215
+ html: (opts) => withTab((t2) => createProvideAPI(client).html(opts, t2)),
29216
+ table: (opts) => withTab((t2) => createProvideAPI(client).table(opts, t2)),
29217
+ list: (opts) => withTab((t2) => createProvideAPI(client).list(opts, t2)),
29218
+ links: (opts) => withTab((t2) => createProvideAPI(client).links(opts, t2)),
29219
+ images: (opts) => withTab((t2) => createProvideAPI(client).images(opts, t2)),
29220
+ form: (opts) => withTab((t2) => createProvideAPI(client).form(opts, t2)),
29221
+ page: () => withTab((t2) => createProvideAPI(client).page(t2)),
29222
+ div: (opts) => withTab((t2) => createProvideAPI(client).div(opts, t2)),
29223
+ meta: () => withTab((t2) => createProvideAPI(client).meta(t2)),
29224
+ select: (opts) => withTab((t2) => createProvideAPI(client).select(opts, t2)),
29225
+ json: (opts) => withTab((t2) => createProvideAPI(client).json(opts, t2))
29226
+ },
29227
+ iframe: {
29228
+ list: () => withTab((t2) => createIframeAPI(client).list(t2)),
29229
+ evaluate: (opts) => withTab((t2) => createIframeAPI(client).evaluate(opts, t2)),
29230
+ click: (opts) => withTab((t2) => createIframeAPI(client).click(opts, t2)),
29231
+ type: (opts) => withTab((t2) => createIframeAPI(client).type(opts, t2)),
29232
+ text: (opts) => withTab((t2) => createIframeAPI(client).text(opts, t2)),
29233
+ html: (opts) => withTab((t2) => createIframeAPI(client).html(opts, t2)),
29234
+ waitSel: (opts) => withTab((t2) => createIframeAPI(client).waitSel(opts, t2))
29235
+ },
28819
29236
  screenshot: async (filePath) => {
28820
29237
  const r = await withTab((t2) => client.screenshot(filePath, t2));
28821
29238
  logger_default.success(`[${name}] screenshot → ${filePath ?? "base64"}`);
@@ -28826,6 +29243,12 @@ function createSiteObject(name, registeredUrl, client, tabId, pool) {
28826
29243
  logger_default.success(`[${name}] pdf → ${filePath ?? "base64"}`);
28827
29244
  return r;
28828
29245
  },
29246
+ human: {
29247
+ set: (opts) => withTab((t2) => createHumanAPI(client).set(opts, t2)),
29248
+ get: () => withTab((t2) => createHumanAPI(client).get(t2)),
29249
+ type: (opts) => withTab((t2) => createHumanAPI(client).type(opts, t2)),
29250
+ click: (opts) => withTab((t2) => createHumanAPI(client).click(opts, t2))
29251
+ },
28829
29252
  blockImages: () => withTab(async (t2) => {
28830
29253
  await client.blockImages(t2);
28831
29254
  logger_default.info(`[${name}] images blocked`);
@@ -28839,12 +29262,13 @@ function createSiteObject(name, registeredUrl, client, tabId, pool) {
28839
29262
  await withTab((t2) => client.setCookie(cookieName, value, domain, path, t2));
28840
29263
  logger_default.info(`[${name}] cookie set: ${cookieName} @ ${domain}`);
28841
29264
  },
28842
- get: (cookieName) => withTab((t2) => client.getCookie(cookieName, t2)),
28843
- delete: async (cookieName) => {
28844
- await withTab((t2) => client.deleteCookie(cookieName, t2));
29265
+ get: (cookieName, domain = "") => withTab((t2) => client.getCookie(cookieName, domain, t2)),
29266
+ delete: async (cookieName, domain) => {
29267
+ const d = domain ?? new URL(registeredUrl).hostname;
29268
+ await withTab((t2) => client.deleteCookie(cookieName, d, t2));
28845
29269
  logger_default.info(`[${name}] cookie deleted: ${cookieName}`);
28846
29270
  },
28847
- list: () => withTab((t2) => client.listCookies(t2))
29271
+ list: (domain = "") => withTab((t2) => client.listCookies(domain, t2))
28848
29272
  },
28849
29273
  intercept: {
28850
29274
  block: async (pattern) => {
@@ -28931,6 +29355,16 @@ function createSiteObject(name, registeredUrl, client, tabId, pool) {
28931
29355
  logger_default.info(`[${name}] intercept rules cleared`);
28932
29356
  }
28933
29357
  },
29358
+ dialog: {
29359
+ accept: (tabId2 = "default", text) => new DialogClient(client).accept(tabId2, text),
29360
+ dismiss: (tabId2 = "default") => new DialogClient(client).dismiss(tabId2),
29361
+ status: (tabId2 = "default") => new DialogClient(client).status(tabId2),
29362
+ setAutoAction: (tabId2 = "default", action) => new DialogClient(client).setAutoAction(tabId2, action),
29363
+ upload: (selector, filePath, tabId2 = "default") => new DialogClient(client).upload(selector, filePath, tabId2),
29364
+ onDialog: (tabId2, handler) => new DialogClient(client).onDialog(tabId2, handler),
29365
+ waitAndAccept: (tabId2 = "default", text, timeoutMs = 30000) => new DialogClient(client).waitAndAccept(tabId2, text, timeoutMs),
29366
+ waitAndDismiss: (tabId2 = "default", timeoutMs = 30000) => new DialogClient(client).waitAndDismiss(tabId2, timeoutMs)
29367
+ },
28934
29368
  capture: {
28935
29369
  start: () => withTab(async (t2) => {
28936
29370
  await client.captureStart(t2);
@@ -28950,37 +29384,14 @@ function createSiteObject(name, registeredUrl, client, tabId, pool) {
28950
29384
  })
28951
29385
  },
28952
29386
  session: {
28953
- export: async () => {
28954
- const data = await withTab((t2) => client.sessionExport(t2));
28955
- logger_default.success(`[${name}] session exported`);
28956
- return data;
28957
- },
28958
- import: async (data) => {
28959
- await withTab((t2) => client.sessionImport(data, t2));
28960
- logger_default.success(`[${name}] session imported`);
28961
- }
28962
- },
28963
- exposeFunction: async (fnName, handler) => {
28964
- await client.exposeFunction(fnName, handler, tabId);
28965
- logger_default.success(`[${name}] exposed function: ${fnName}`);
28966
- return site;
28967
- },
28968
- unexposeFunction: async (fnName) => {
28969
- await client.unexposeFunction(fnName, tabId);
28970
- logger_default.info(`[${name}] unexposed function: ${fnName}`);
28971
- return site;
28972
- },
28973
- clearExposedFunctions: async () => {
28974
- await client.clearExposedFunctions(tabId);
28975
- logger_default.info(`[${name}] cleared all exposed functions`);
28976
- return site;
28977
- },
28978
- exposeAndInject: async (fnName, handler, injectionJs) => {
28979
- await client.exposeFunction(fnName, handler, tabId);
28980
- const js = typeof injectionJs === "function" ? injectionJs(fnName) : injectionJs;
28981
- await withTab((t2) => client.evaluate(js, t2));
28982
- logger_default.success(`[${name}] exposed and injected: ${fnName}`);
28983
- return site;
29387
+ export: () => withTab((t2) => createSessionAPI(client).export(t2)),
29388
+ import: (data) => withTab((t2) => createSessionAPI(client).import(data, t2)),
29389
+ reload: () => withTab((t2) => createSessionAPI(client).reload(t2)),
29390
+ paths: () => createSessionAPI(client).paths(),
29391
+ cookies: { path: () => createSessionAPI(client).cookiesPath() },
29392
+ profile: { path: () => createSessionAPI(client).profilePath() },
29393
+ ws: { save: (opts) => createSessionAPI(client).setWsSave(opts.enabled) },
29394
+ pings: { save: (opts) => createSessionAPI(client).setPingsSave(opts.enabled) }
28984
29395
  },
28985
29396
  store: async (data, schemaName) => {
28986
29397
  const target = schemaName ?? name;
@@ -29074,173 +29485,58 @@ class TabPool {
29074
29485
  return await fn(tabId);
29075
29486
  } finally {
29076
29487
  this.release(tabId);
29077
- }
29078
- }
29079
- async close() {
29080
- for (const tabId of [...this.idle, ...this.busy]) {
29081
- try {
29082
- await this.client.closeTab(tabId);
29083
- } catch {}
29084
- }
29085
- this.idle = [];
29086
- this.busy.clear();
29087
- this.queue = [];
29088
- }
29089
- get stats() {
29090
- return {
29091
- idle: this.idle.length,
29092
- busy: this.busy.size,
29093
- queued: this.queue.length,
29094
- total: this.size
29095
- };
29096
- }
29097
- }
29098
-
29099
- // piggy/capture/index.ts
29100
- class CaptureClient {
29101
- client;
29102
- constructor(client) {
29103
- this.client = client;
29104
- }
29105
- start(tabId = "default") {
29106
- return this.client.send("capture.start", { tabId });
29107
- }
29108
- stop(tabId = "default") {
29109
- return this.client.send("capture.stop", { tabId });
29110
- }
29111
- requests(tabId = "default") {
29112
- return this.client.send("capture.requests", { tabId });
29113
- }
29114
- ws(tabId = "default") {
29115
- return this.client.send("capture.ws", { tabId });
29116
- }
29117
- cookies(tabId = "default") {
29118
- return this.client.send("capture.cookies", { tabId });
29119
- }
29120
- storage(tabId = "default") {
29121
- return this.client.send("capture.storage", { tabId });
29122
- }
29123
- clear(tabId = "default") {
29124
- return this.client.send("capture.clear", { tabId });
29125
- }
29126
- }
29127
- function createCaptureAPI(client) {
29128
- return new CaptureClient(client);
29129
- }
29130
-
29131
- // piggy/captcha/index.ts
29132
- class CaptchaClient {
29133
- client;
29134
- constructor(client) {
29135
- this.client = client;
29136
- }
29137
- status(tabId = "default") {
29138
- return this.client.send("captcha.status", { tabId });
29139
- }
29140
- resolve(tabId = "default") {
29141
- return this.client.send("captcha.resolve", { tabId });
29142
- }
29143
- pause(tabId = "default") {
29144
- return this.client.send("captcha.pause", { tabId });
29145
- }
29146
- check(tabId = "default") {
29147
- return this.client.send("captcha.check", { tabId });
29148
- }
29149
- setAutoRetry(enabled) {
29150
- return this.client.send("captcha.autoRetry", { enabled });
29151
- }
29152
- blockStatus(tabId = "default") {
29153
- return this.client.send("block.status", { tabId });
29154
- }
29155
- blockRetry(tabId = "default") {
29156
- return this.client.send("block.retry", { tabId });
29157
- }
29158
- onCaptcha(tabId, handler) {
29159
- return this.client.onEvent("captcha", tabId, handler);
29160
- }
29161
- onCaptchaResolved(tabId, handler) {
29162
- return this.client.onEvent("captcha:resolved", tabId, handler);
29163
- }
29164
- onBlocked(tabId, handler) {
29165
- return this.client.onEvent("blocked", tabId, handler);
29166
- }
29167
- onBlockRetry(tabId, handler) {
29168
- return this.client.onEvent("block:retry", tabId, handler);
29169
- }
29170
- waitForResolution(tabId = "default", timeoutMs = 300000) {
29171
- return new Promise((resolve2, reject) => {
29172
- const timer = setTimeout(() => {
29173
- unsub();
29174
- reject(new Error(`captcha.waitForResolution: timed out after ${timeoutMs}ms`));
29175
- }, timeoutMs);
29176
- const unsub = this.onCaptchaResolved(tabId, () => {
29177
- clearTimeout(timer);
29178
- unsub();
29179
- resolve2();
29180
- });
29181
- logger_default.warn(`[captcha] waiting for manual resolution on tab ${tabId}…`);
29182
- });
29488
+ }
29489
+ }
29490
+ async close() {
29491
+ for (const tabId of [...this.idle, ...this.busy]) {
29492
+ try {
29493
+ await this.client.closeTab(tabId);
29494
+ } catch {}
29495
+ }
29496
+ this.idle = [];
29497
+ this.busy.clear();
29498
+ this.queue = [];
29499
+ }
29500
+ get stats() {
29501
+ return {
29502
+ idle: this.idle.length,
29503
+ busy: this.busy.size,
29504
+ queued: this.queue.length,
29505
+ total: this.size
29506
+ };
29183
29507
  }
29184
- }
29185
- function createCaptchaAPI(client) {
29186
- return new CaptchaClient(client);
29187
29508
  }
29188
29509
 
29189
- // piggy/dialog/index.ts
29190
- class DialogClient {
29510
+ // piggy/capture/index.ts
29511
+ class CaptureClient {
29191
29512
  client;
29192
29513
  constructor(client) {
29193
29514
  this.client = client;
29194
29515
  }
29195
- accept(tabId = "default", text) {
29196
- return this.client.send("dialog.accept", { tabId, ...text !== undefined ? { text } : {} });
29197
- }
29198
- dismiss(tabId = "default") {
29199
- return this.client.send("dialog.dismiss", { tabId });
29516
+ start(tabId = "default") {
29517
+ return this.client.send("capture.start", { tabId });
29200
29518
  }
29201
- status(tabId = "default") {
29202
- return this.client.send("dialog.status", { tabId });
29519
+ stop(tabId = "default") {
29520
+ return this.client.send("capture.stop", { tabId });
29203
29521
  }
29204
- setAutoAction(tabId = "default", action) {
29205
- return this.client.send("dialog.onDialog", { tabId, action });
29522
+ requests(tabId = "default") {
29523
+ return this.client.send("capture.requests", { tabId });
29206
29524
  }
29207
- upload(selector, filePath, tabId = "default") {
29208
- return this.client.send("upload", { selector, path: filePath, tabId });
29525
+ ws(tabId = "default") {
29526
+ return this.client.send("capture.ws", { tabId });
29209
29527
  }
29210
- onDialog(tabId, handler) {
29211
- return this.client.onEvent("dialog", tabId, handler);
29528
+ cookies(tabId = "default") {
29529
+ return this.client.send("capture.cookies", { tabId });
29212
29530
  }
29213
- waitAndAccept(tabId = "default", text, timeoutMs = 30000) {
29214
- return new Promise((resolve2, reject) => {
29215
- const timer = setTimeout(() => {
29216
- unsub();
29217
- reject(new Error(`dialog.waitAndAccept: timed out after ${timeoutMs}ms`));
29218
- }, timeoutMs);
29219
- const unsub = this.onDialog(tabId, async (data) => {
29220
- clearTimeout(timer);
29221
- unsub();
29222
- await this.accept(tabId, text);
29223
- resolve2(data);
29224
- });
29225
- });
29531
+ storage(tabId = "default") {
29532
+ return this.client.send("capture.storage", { tabId });
29226
29533
  }
29227
- waitAndDismiss(tabId = "default", timeoutMs = 30000) {
29228
- return new Promise((resolve2, reject) => {
29229
- const timer = setTimeout(() => {
29230
- unsub();
29231
- reject(new Error(`dialog.waitAndDismiss: timed out after ${timeoutMs}ms`));
29232
- }, timeoutMs);
29233
- const unsub = this.onDialog(tabId, async (data) => {
29234
- clearTimeout(timer);
29235
- unsub();
29236
- await this.dismiss(tabId);
29237
- resolve2(data);
29238
- });
29239
- });
29534
+ clear(tabId = "default") {
29535
+ return this.client.send("capture.clear", { tabId });
29240
29536
  }
29241
29537
  }
29242
- function createDialogAPI(client) {
29243
- return new DialogClient(client);
29538
+ function createCaptureAPI(client) {
29539
+ return new CaptureClient(client);
29244
29540
  }
29245
29541
 
29246
29542
  // piggy/export/index.ts
@@ -29318,100 +29614,6 @@ function createExportAPI(client) {
29318
29614
  return new ExportClient(client);
29319
29615
  }
29320
29616
 
29321
- // piggy/find/index.ts
29322
- class FindClient {
29323
- client;
29324
- constructor(client) {
29325
- this.client = client;
29326
- }
29327
- css(selector, tabId = "default") {
29328
- return this.client.send("find.css", { selector, tabId });
29329
- }
29330
- all(selector, tabId = "default") {
29331
- return this.client.send("find.all", { selector, tabId });
29332
- }
29333
- first(selector, tabId = "default") {
29334
- return this.client.send("find.first", { selector, tabId });
29335
- }
29336
- byText(opts, tabId = "default") {
29337
- return this.client.send("find.byText", { ...opts, tabId });
29338
- }
29339
- byAttr(opts, tabId = "default") {
29340
- return this.client.send("find.byAttr", { ...opts, tabId });
29341
- }
29342
- byTag(tag, tabId = "default") {
29343
- return this.client.send("find.byTag", { tag, tabId });
29344
- }
29345
- byPlaceholder(text, tabId = "default") {
29346
- return this.client.send("find.byPlaceholder", { text, tabId });
29347
- }
29348
- byRole(opts, tabId = "default") {
29349
- return this.client.send("find.byRole", { ...opts, tabId });
29350
- }
29351
- children(selector, tabId = "default") {
29352
- return this.client.send("find.children", { selector, tabId });
29353
- }
29354
- filter(opts, tabId = "default") {
29355
- return this.client.send("find.filter", { ...opts, tabId });
29356
- }
29357
- closest(opts, tabId = "default") {
29358
- return this.client.send("find.closest", { ...opts, tabId });
29359
- }
29360
- parent(selector, tabId = "default") {
29361
- return this.client.send("find.parent", { selector, tabId });
29362
- }
29363
- count(selector, tabId = "default") {
29364
- return this.client.send("find.count", { selector, tabId });
29365
- }
29366
- exists(selector, tabId = "default") {
29367
- return this.client.send("find.exists", { selector, tabId });
29368
- }
29369
- visible(selector, tabId = "default") {
29370
- return this.client.send("find.visible", { selector, tabId });
29371
- }
29372
- enabled(selector, tabId = "default") {
29373
- return this.client.send("find.enabled", { selector, tabId });
29374
- }
29375
- checked(selector, tabId = "default") {
29376
- return this.client.send("find.checked", { selector, tabId });
29377
- }
29378
- }
29379
- function createFindAPI(client) {
29380
- return new FindClient(client);
29381
- }
29382
-
29383
- // piggy/iframe/index.ts
29384
- class IframeClient {
29385
- client;
29386
- constructor(client) {
29387
- this.client = client;
29388
- }
29389
- list(tabId = "default") {
29390
- return this.client.send("iframe.list", { tabId });
29391
- }
29392
- evaluate(opts, tabId = "default") {
29393
- return this.client.send("iframe.evaluate", { ...opts, tabId });
29394
- }
29395
- click(opts, tabId = "default") {
29396
- return this.client.send("iframe.click", { ...opts, tabId });
29397
- }
29398
- type(opts, tabId = "default") {
29399
- return this.client.send("iframe.type", { ...opts, tabId });
29400
- }
29401
- text(opts, tabId = "default") {
29402
- return this.client.send("iframe.text", { ...opts, tabId });
29403
- }
29404
- html(opts, tabId = "default") {
29405
- return this.client.send("iframe.html", { ...opts, tabId });
29406
- }
29407
- waitSel(opts, tabId = "default") {
29408
- return this.client.send("iframe.waitSel", { ...opts, tabId });
29409
- }
29410
- }
29411
- function createIframeAPI(client) {
29412
- return new IframeClient(client);
29413
- }
29414
-
29415
29617
  // piggy/interactions/index.ts
29416
29618
  class InteractionsClient {
29417
29619
  client;
@@ -29538,62 +29740,6 @@ function createNavigationAPI(client) {
29538
29740
  return new NavigationClient(client);
29539
29741
  }
29540
29742
 
29541
- // piggy/provide/index.ts
29542
- class ProvideClient {
29543
- client;
29544
- constructor(client) {
29545
- this.client = client;
29546
- }
29547
- text(selector, tabId = "default") {
29548
- return this.client.send("provide.text", { selector, tabId });
29549
- }
29550
- textAll(selector, tabId = "default") {
29551
- return this.client.send("provide.textAll", { selector, tabId });
29552
- }
29553
- attr(selector, attr, tabId = "default") {
29554
- return this.client.send("provide.attr", { selector, attr, tabId });
29555
- }
29556
- attrAll(selector, attr, tabId = "default") {
29557
- return this.client.send("provide.attrAll", { selector, attr, tabId });
29558
- }
29559
- html(selector, tabId = "default") {
29560
- return this.client.send("provide.html", { selector, tabId });
29561
- }
29562
- table(selector, tabId = "default") {
29563
- return this.client.send("provide.table", { selector, tabId });
29564
- }
29565
- list(selector, itemSel, tabId = "default") {
29566
- return this.client.send("provide.list", { selector, itemSel, tabId });
29567
- }
29568
- links(selector, tabId = "default") {
29569
- return this.client.send("provide.links", { selector, tabId });
29570
- }
29571
- images(selector, tabId = "default") {
29572
- return this.client.send("provide.images", { selector, tabId });
29573
- }
29574
- form(selector, tabId = "default") {
29575
- return this.client.send("provide.form", { selector, tabId });
29576
- }
29577
- page(tabId = "default") {
29578
- return this.client.send("provide.page", { tabId });
29579
- }
29580
- div(selector, tabId = "default") {
29581
- return this.client.send("provide.div", { selector, tabId });
29582
- }
29583
- meta(tabId = "default") {
29584
- return this.client.send("provide.meta", { tabId });
29585
- }
29586
- select(selector, tabId = "default") {
29587
- return this.client.send("provide.select", { selector, tabId });
29588
- }
29589
- json(selector, tabId = "default") {
29590
- return this.client.send("provide.json", { selector, tabId });
29591
- }
29592
- }
29593
- function createProvideAPI(client) {
29594
- return new ProvideClient(client);
29595
- }
29596
-
29597
29743
  // piggy/proxy/index.ts
29598
29744
  class ProxyClient {
29599
29745
  client;
@@ -29653,57 +29799,6 @@ function createProxyAPI(client) {
29653
29799
  return new ProxyClient(client);
29654
29800
  }
29655
29801
 
29656
- // piggy/session/index.ts
29657
- class SessionClient {
29658
- client;
29659
- constructor(client) {
29660
- this.client = client;
29661
- }
29662
- reload(tabId = "default") {
29663
- return this.client.send("session.reload", { tabId });
29664
- }
29665
- paths() {
29666
- return this.client.send("session.paths", {});
29667
- }
29668
- cookiesPath() {
29669
- return this.client.send("session.cookies.path", {});
29670
- }
29671
- profilePath() {
29672
- return this.client.send("session.profile.path", {});
29673
- }
29674
- wsPath() {
29675
- return this.client.send("session.ws.path", {});
29676
- }
29677
- pingsPath() {
29678
- return this.client.send("session.pings.path", {});
29679
- }
29680
- setWsSave(enabled) {
29681
- return this.client.send("session.ws.save", { enabled });
29682
- }
29683
- setPingsSave(enabled) {
29684
- return this.client.send("session.pings.save", { enabled });
29685
- }
29686
- async export(tabId = "default") {
29687
- const raw = await this.client.send("session.export", { tabId });
29688
- return typeof raw === "string" ? JSON.parse(raw) : raw;
29689
- }
29690
- import(data, tabId = "default") {
29691
- return this.client.send("session.import", {
29692
- data: JSON.stringify(data),
29693
- tabId
29694
- });
29695
- }
29696
- setCookie(opts, tabId = "default") {
29697
- return this.client.send("cookie.set", { ...opts, tabId });
29698
- }
29699
- deleteCookie(opts, tabId = "default") {
29700
- return this.client.send("cookie.delete", { ...opts, tabId });
29701
- }
29702
- }
29703
- function createSessionAPI(client) {
29704
- return new SessionClient(client);
29705
- }
29706
-
29707
29802
  // piggy/tabs/index.ts
29708
29803
  class TabsClient {
29709
29804
  client;
@@ -29713,7 +29808,8 @@ class TabsClient {
29713
29808
  new() {
29714
29809
  return this.client.send("tab.new", {});
29715
29810
  }
29716
- close(tabId) {
29811
+ close(opts) {
29812
+ const tabId = typeof opts === "string" ? opts : opts.tabId;
29717
29813
  return this.client.send("tab.close", { tabId });
29718
29814
  }
29719
29815
  list() {
@@ -29939,6 +30035,9 @@ var piggy = {
29939
30035
  get tabs() {
29940
30036
  return _router?.tabs ?? createTabsAPI(guardClient());
29941
30037
  },
30038
+ get tab() {
30039
+ return _router?.tabs ?? createTabsAPI(guardClient());
30040
+ },
29942
30041
  get navigation() {
29943
30042
  return _router?.navigation ?? createNavigationAPI(guardClient());
29944
30043
  },