nothing-browser 0.0.21 → 0.1.1

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.
Files changed (68) hide show
  1. package/LICENSE +1 -1
  2. package/dist/human/index.js +25 -1
  3. package/dist/piggy/captcha/index.d.ts +39 -0
  4. package/dist/piggy/captcha/index.d.ts.map +1 -0
  5. package/dist/piggy/capture/index.d.ts +48 -0
  6. package/dist/piggy/capture/index.d.ts.map +1 -0
  7. package/dist/piggy/dialog/index.d.ts +28 -0
  8. package/dist/piggy/dialog/index.d.ts.map +1 -0
  9. package/dist/piggy/export/index.d.ts +62 -0
  10. package/dist/piggy/export/index.d.ts.map +1 -0
  11. package/dist/piggy/find/index.d.ts +52 -0
  12. package/dist/piggy/find/index.d.ts.map +1 -0
  13. package/dist/piggy/http/index.d.ts +14 -0
  14. package/dist/piggy/http/index.d.ts.map +1 -0
  15. package/dist/piggy/human/index.d.ts +36 -4
  16. package/dist/piggy/human/index.d.ts.map +1 -1
  17. package/dist/piggy/iframe/index.d.ts +53 -0
  18. package/dist/piggy/iframe/index.d.ts.map +1 -0
  19. package/dist/piggy/interactions/index.d.ts +24 -0
  20. package/dist/piggy/interactions/index.d.ts.map +1 -0
  21. package/dist/piggy/media/index.d.ts +11 -0
  22. package/dist/piggy/media/index.d.ts.map +1 -0
  23. package/dist/piggy/navigation/index.d.ts +16 -0
  24. package/dist/piggy/navigation/index.d.ts.map +1 -0
  25. package/dist/piggy/provide/index.d.ts +98 -0
  26. package/dist/piggy/provide/index.d.ts.map +1 -0
  27. package/dist/piggy/proxy/index.d.ts +94 -0
  28. package/dist/piggy/proxy/index.d.ts.map +1 -0
  29. package/dist/piggy/register/index.d.ts.map +1 -1
  30. package/dist/piggy/router/index.d.ts +38 -0
  31. package/dist/piggy/router/index.d.ts.map +1 -0
  32. package/dist/piggy/session/index.d.ts +27 -0
  33. package/dist/piggy/session/index.d.ts.map +1 -0
  34. package/dist/piggy/tabs/index.d.ts +10 -0
  35. package/dist/piggy/tabs/index.d.ts.map +1 -0
  36. package/dist/piggy/wait/index.d.ts +28 -0
  37. package/dist/piggy/wait/index.d.ts.map +1 -0
  38. package/dist/piggy.d.ts.map +1 -1
  39. package/dist/piggy.js +898 -181
  40. package/dist/register/index.js +39 -86
  41. package/package.json +1 -1
  42. package/piggy/captcha/index.d.ts +35 -0
  43. package/piggy/captcha/index.ts +93 -0
  44. package/piggy/capture/index.ts +76 -0
  45. package/piggy/dialog/index.d.ts +29 -0
  46. package/piggy/dialog/index.ts +85 -0
  47. package/piggy/export/index.d.ts +117 -0
  48. package/piggy/export/index.ts +147 -0
  49. package/piggy/find/index.ts +118 -0
  50. package/piggy/http/index.ts +65 -0
  51. package/piggy/human/index.ts +115 -53
  52. package/piggy/iframe/index.ts +79 -0
  53. package/piggy/interactions/index.ts +79 -0
  54. package/piggy/media/index.ts +46 -0
  55. package/piggy/navigation/index.ts +52 -0
  56. package/piggy/provide/index.ts +170 -0
  57. package/piggy/proxy/index.ts +154 -0
  58. package/piggy/register/index.ts +41 -59
  59. package/piggy/router/index.ts +69 -0
  60. package/piggy/session/index.ts +76 -0
  61. package/piggy/tabs/index.ts +22 -0
  62. package/piggy/wait/index.ts +90 -0
  63. package/piggy.ts +94 -39
  64. package/dist/piggy/open/index.d.ts +0 -4
  65. package/dist/piggy/open/index.d.ts.map +0 -1
  66. package/piggy/open/index.d.ts +0 -4
  67. package/piggy/open/index.d.ts.map +0 -1
  68. package/piggy/open/index.ts +0 -5
@@ -0,0 +1,69 @@
1
+ // piggy/router/index.ts
2
+ // Mirrors PiggyCommandRouter.cpp.
3
+ // This is the single entry point that composes all sub-clients
4
+ // into one object — the same way the C++ router dispatches to sub-handlers.
5
+
6
+ import { PiggyClient } from "../client";
7
+ import { CaptureClient, createCaptureAPI } from "../capture";
8
+ import { CaptchaClient, createCaptchaAPI } from "../captcha";
9
+ import { DialogClient, createDialogAPI } from "../dialog";
10
+ import { ExportClient, createExportAPI } from "../export";
11
+ import { FindClient, createFindAPI } from "../find";
12
+ import { HumanClient, createHumanAPI } from "../human";
13
+ import { IframeClient, createIframeAPI } from "../iframe";
14
+ import { InteractionsClient, createInteractionsAPI } from "../interactions";
15
+ import { MediaClient, createMediaAPI } from "../media";
16
+ import { NavigationClient, createNavigationAPI } from "../navigation";
17
+ import { ProvideClient, createProvideAPI } from "../provide";
18
+ import { ProxyClient, createProxyAPI } from "../proxy";
19
+ import { SessionClient, createSessionAPI } from "../session";
20
+ import { TabsClient, createTabsAPI } from "../tabs";
21
+ import { WaitClient, EvaluateClient, FetchClient, createWaitAPI, createEvaluateAPI, createFetchAPI } from "../wait";
22
+
23
+ export interface PiggyRouter {
24
+ // Core transport
25
+ client: PiggyClient;
26
+
27
+ // Sub-routers — 1:1 with C++ files
28
+ tabs: TabsClient;
29
+ navigation: NavigationClient;
30
+ interactions: InteractionsClient;
31
+ media: MediaClient;
32
+ capture: CaptureClient;
33
+ find: FindClient;
34
+ provide: ProvideClient;
35
+ wait: WaitClient;
36
+ evaluate: EvaluateClient;
37
+ fetch: FetchClient;
38
+ proxy: ProxyClient;
39
+ captcha: CaptchaClient;
40
+ dialog: DialogClient;
41
+ human: HumanClient;
42
+ iframe: IframeClient;
43
+ session: SessionClient;
44
+ export: ExportClient;
45
+ }
46
+
47
+ export function createRouter(client: PiggyClient): PiggyRouter {
48
+ return {
49
+ client,
50
+ tabs: createTabsAPI(client),
51
+ navigation: createNavigationAPI(client),
52
+ interactions: createInteractionsAPI(client),
53
+ media: createMediaAPI(client),
54
+ capture: createCaptureAPI(client),
55
+ find: createFindAPI(client),
56
+ provide: createProvideAPI(client),
57
+ wait: createWaitAPI(client),
58
+ evaluate: createEvaluateAPI(client),
59
+ fetch: createFetchAPI(client),
60
+ proxy: createProxyAPI(client),
61
+ captcha: createCaptchaAPI(client),
62
+ dialog: createDialogAPI(client),
63
+ human: createHumanAPI(client),
64
+ iframe: createIframeAPI(client),
65
+ session: createSessionAPI(client),
66
+ export: createExportAPI(client),
67
+ };
68
+ }
69
+
@@ -0,0 +1,76 @@
1
+ // piggy/session/index.ts
2
+ import { PiggyClient } from "../client";
3
+ import type { CookieSetOptions, CookieDeleteOptions } from "../export";
4
+
5
+ export interface SessionPaths {
6
+ workDir: string;
7
+ cookies: string;
8
+ profile: string;
9
+ ws: string;
10
+ pings: string;
11
+ }
12
+
13
+ export class SessionClient {
14
+ constructor(private client: PiggyClient) {}
15
+
16
+ // Session lifecycle
17
+ reload(tabId = "default"): Promise<void> {
18
+ return this.client.send("session.reload", { tabId });
19
+ }
20
+
21
+ // Paths
22
+ paths(): Promise<SessionPaths> {
23
+ return this.client.send("session.paths", {});
24
+ }
25
+
26
+ cookiesPath(): Promise<string> {
27
+ return this.client.send("session.cookies.path", {});
28
+ }
29
+
30
+ profilePath(): Promise<string> {
31
+ return this.client.send("session.profile.path", {});
32
+ }
33
+
34
+ wsPath(): Promise<string> {
35
+ return this.client.send("session.ws.path", {});
36
+ }
37
+
38
+ pingsPath(): Promise<string> {
39
+ return this.client.send("session.pings.path", {});
40
+ }
41
+
42
+ // Opt-in persistence
43
+ setWsSave(enabled: boolean): Promise<void> {
44
+ return this.client.send("session.ws.save", { enabled });
45
+ }
46
+
47
+ setPingsSave(enabled: boolean): Promise<void> {
48
+ return this.client.send("session.pings.save", { enabled });
49
+ }
50
+
51
+ // Export / import
52
+ async export(tabId = "default"): Promise<any> {
53
+ const raw = await this.client.send<string>("session.export", { tabId });
54
+ return typeof raw === "string" ? JSON.parse(raw) : raw;
55
+ }
56
+
57
+ import(data: any, tabId = "default"): Promise<void> {
58
+ return this.client.send("session.import", {
59
+ data: JSON.stringify(data),
60
+ tabId,
61
+ });
62
+ }
63
+
64
+ // Cookies (using imported types from export)
65
+ setCookie(opts: CookieSetOptions, tabId = "default"): Promise<void> {
66
+ return this.client.send("cookie.set", { ...opts, tabId });
67
+ }
68
+
69
+ deleteCookie(opts: CookieDeleteOptions, tabId = "default"): Promise<void> {
70
+ return this.client.send("cookie.delete", { ...opts, tabId });
71
+ }
72
+ }
73
+
74
+ export function createSessionAPI(client: PiggyClient): SessionClient {
75
+ return new SessionClient(client);
76
+ }
@@ -0,0 +1,22 @@
1
+ // piggy/tabs/index.ts
2
+ import { PiggyClient } from "../client";
3
+
4
+ export class TabsClient {
5
+ constructor(private client: PiggyClient) {}
6
+
7
+ new(): Promise<string> {
8
+ return this.client.send("tab.new", {});
9
+ }
10
+
11
+ close(tabId: string): Promise<void> {
12
+ return this.client.send("tab.close", { tabId });
13
+ }
14
+
15
+ list(): Promise<string[]> {
16
+ return this.client.send("tab.list", {});
17
+ }
18
+ }
19
+
20
+ export function createTabsAPI(client: PiggyClient): TabsClient {
21
+ return new TabsClient(client);
22
+ }
@@ -0,0 +1,90 @@
1
+ // piggy/wait/index.ts
2
+ import { PiggyClient } from "../client";
3
+
4
+ export type WaitSelectorState = "attached" | "detached" | "visible" | "hidden";
5
+
6
+ // ─── WaitClient ───────────────────────────────────────────────────────────────
7
+ // Maps to PiggyWait.cpp
8
+
9
+ export class WaitClient {
10
+ constructor(private client: PiggyClient) {}
11
+
12
+ // wait.function — poll every 100ms until JS expr is truthy
13
+ function(js: string, timeout = 10000, tabId = "default"): Promise<void> {
14
+ return this.client.send("wait.function", { js, timeout, tabId });
15
+ }
16
+
17
+ // wait.selector — with full state support (attached|detached|visible|hidden)
18
+ selector(
19
+ selector: string,
20
+ state: WaitSelectorState = "attached",
21
+ timeout = 10000,
22
+ tabId = "default"
23
+ ): Promise<void> {
24
+ return this.client.send("wait.selector", { selector, state, timeout, tabId });
25
+ }
26
+ }
27
+
28
+ // ─── EvaluateClient ───────────────────────────────────────────────────────────
29
+ // Maps to the evaluate command in PiggyWait.cpp (with timeout support)
30
+ // and PiggyInteractions.cpp (without timeout)
31
+
32
+ export class EvaluateClient {
33
+ constructor(private client: PiggyClient) {}
34
+
35
+ // evaluate with optional wall-clock timeout
36
+ run(js: string, timeout?: number, tabId = "default"): Promise<unknown> {
37
+ return this.client.send("evaluate", {
38
+ js,
39
+ tabId,
40
+ ...(timeout !== undefined ? { timeout } : {}),
41
+ });
42
+ }
43
+ }
44
+
45
+ // ─── FetchClient ──────────────────────────────────────────────────────────────
46
+ // Maps to fetch.textAll / fetch.attr / fetch.attrAll in PiggyWait.cpp
47
+ // and fetch.text / fetch.links / fetch.image in PiggyExport.cpp
48
+
49
+ export class FetchClient {
50
+ constructor(private client: PiggyClient) {}
51
+
52
+ // fetch.text — single element innerText
53
+ text(selector: string, tabId = "default"): Promise<string | null> {
54
+ return this.client.send("fetch.text", { query: selector, tabId });
55
+ }
56
+
57
+ // fetch.textAll — all matching elements innerText
58
+ textAll(selector: string, tabId = "default"): Promise<string[]> {
59
+ return this.client.send("fetch.textAll", { selector, tabId });
60
+ }
61
+
62
+ // fetch.attr — single attribute from first match
63
+ attr(selector: string, attr: string, tabId = "default"): Promise<string | null> {
64
+ return this.client.send("fetch.attr", { selector, attr, tabId });
65
+ }
66
+
67
+ // fetch.attrAll — attribute from all matches
68
+ attrAll(selector: string, attr: string, tabId = "default"): Promise<string[]> {
69
+ return this.client.send("fetch.attrAll", { selector, attr, tabId });
70
+ }
71
+
72
+ // fetch.links — links inside a selector
73
+ links(selector: string, tabId = "default"): Promise<string[]> {
74
+ return this.client.send("fetch.links", { query: selector, tabId });
75
+ }
76
+
77
+ // fetch.links.all — all links on page
78
+ linksAll(tabId = "default"): Promise<string[]> {
79
+ return this.client.send("fetch.links.all", { tabId });
80
+ }
81
+
82
+ // fetch.image — images inside a selector
83
+ images(selector: string, tabId = "default"): Promise<string[]> {
84
+ return this.client.send("fetch.image", { query: selector, tabId });
85
+ }
86
+ }
87
+
88
+ export function createWaitAPI(client: PiggyClient): WaitClient { return new WaitClient(client); }
89
+ export function createEvaluateAPI(client: PiggyClient): EvaluateClient { return new EvaluateClient(client); }
90
+ export function createFetchAPI(client: PiggyClient): FetchClient { return new FetchClient(client); }
package/piggy.ts CHANGED
@@ -5,17 +5,49 @@ import { PiggyClient } from "./piggy/client";
5
5
  import { setClient, setHumanMode, createSiteObject, type SiteObject } from "./piggy/register";
6
6
  import { routeRegistry, keepAliveSites, startServer, stopServer } from "./piggy/server";
7
7
  import { TabPool } from "./piggy/pool";
8
+ import { createRouter, type PiggyRouter } from "./piggy/router";
9
+ import { createCaptureAPI } from "./piggy/capture";
10
+ import { createCaptchaAPI } from "./piggy/captcha";
11
+ import { createDialogAPI } from "./piggy/dialog";
12
+ import { createExportAPI } from "./piggy/export";
13
+ import { createFindAPI } from "./piggy/find";
14
+ import { createHumanAPI } from "./piggy/human";
15
+ import { createIframeAPI } from "./piggy/iframe";
16
+ import { createInteractionsAPI } from "./piggy/interactions";
17
+ import { createMediaAPI } from "./piggy/media";
18
+ import { createNavigationAPI } from "./piggy/navigation";
19
+ import { createProvideAPI } from "./piggy/provide";
20
+ import { createProxyAPI } from "./piggy/proxy";
21
+ import { createSessionAPI } from "./piggy/session";
22
+ import { createTabsAPI } from "./piggy/tabs";
23
+ import { createWaitAPI, createEvaluateAPI, createFetchAPI } from "./piggy/wait";
24
+ import { createHttpClient, type HttpClientOptions } from "./piggy/http";
8
25
  import logger from "./piggy/logger";
9
26
 
10
27
  type TabMode = "tab" | "process";
11
28
 
12
29
  let _client: PiggyClient | null = null;
30
+ let _router: PiggyRouter | null = null;
13
31
  let _tabMode: TabMode = "tab";
14
32
  const _extraProcs: { socket: string; client: PiggyClient }[] = [];
15
- const _sites: Record<string, SiteObject> = [];
33
+ const _sites: Record<string, SiteObject> = {};
34
+
35
+ // ── Internal guard ────────────────────────────────────────────────────────────
36
+
37
+ function guardClient(): PiggyClient {
38
+ if (!_client) throw new Error("No client. Call piggy.launch() or piggy.connect() first.");
39
+ return _client;
40
+ }
41
+
42
+ // ── Build sub-APIs from a client ──────────────────────────────────────────────
43
+
44
+ function buildAPIs(client: PiggyClient) {
45
+ _router = createRouter(client);
46
+ }
16
47
 
17
48
  const piggy: any = {
18
- // ── Local launch (socket) ─────────────────────────────────────────────────
49
+
50
+ // ── Local launch (unix socket) ────────────────────────────────────────────
19
51
  launch: async (opts?: { mode?: TabMode; binary?: BinaryMode }) => {
20
52
  _tabMode = opts?.mode ?? "tab";
21
53
  const binaryMode: BinaryMode = opts?.binary ?? "headless";
@@ -24,6 +56,7 @@ const piggy: any = {
24
56
  _client = new PiggyClient();
25
57
  await _client.connect();
26
58
  setClient(_client);
59
+ buildAPIs(_client);
27
60
  logger.info(`[piggy] launched — tab mode: "${_tabMode}", binary: "${binaryMode}"`);
28
61
  return piggy;
29
62
  },
@@ -34,36 +67,38 @@ const piggy: any = {
34
67
  _client = new PiggyClient({ host: opts.host, key: opts.key });
35
68
  await _client.connect();
36
69
  setClient(_client);
70
+ buildAPIs(_client);
37
71
  logger.info(`[piggy] connected (HTTP) → ${opts.host}`);
38
72
  return piggy;
39
73
  },
40
74
 
75
+ // ── HTTP client (port 2005 direct) ────────────────────────────────────────
76
+ // Use when you want to talk to the browser over HTTP without a socket client.
77
+ http: (opts: HttpClientOptions) => createHttpClient(opts),
78
+
41
79
  // ── Register ──────────────────────────────────────────────────────────────
42
80
  register: async (
43
81
  name: string,
44
82
  url: string,
45
- opts?: {
46
- binary?: BinaryMode;
47
- pool?: number;
48
- }
83
+ opts?: { binary?: BinaryMode; pool?: number }
49
84
  ) => {
50
85
  if (!url?.trim()) throw new Error(`No URL for site "${name}"`);
51
86
  const binaryMode: BinaryMode = opts?.binary ?? "headless";
52
87
  const poolSize = opts?.pool ?? 0;
53
88
 
54
89
  if (_tabMode === "tab") {
55
- if (!_client) throw new Error("No client. Call piggy.launch() or piggy.connect() first.");
90
+ const client = guardClient();
56
91
 
57
92
  if (poolSize > 1) {
58
- const pool = new TabPool(_client, poolSize, url, name);
93
+ const pool = new TabPool(client, poolSize, url, name);
59
94
  await pool.init();
60
- const siteObj = createSiteObject(name, url, _client, "default", pool);
95
+ const siteObj = createSiteObject(name, url, client, "default", pool);
61
96
  _sites[name] = siteObj;
62
97
  piggy[name] = siteObj;
63
98
  logger.success(`[${name}] registered with pool of ${poolSize} tabs`);
64
99
  } else {
65
- const tabId = await _client.newTab();
66
- const siteObj = createSiteObject(name, url, _client, tabId);
100
+ const tabId = await client.newTab();
101
+ const siteObj = createSiteObject(name, url, client, tabId);
67
102
  _sites[name] = siteObj;
68
103
  piggy[name] = siteObj;
69
104
  logger.success(`[${name}] registered as tab ${tabId}`);
@@ -84,6 +119,49 @@ const piggy: any = {
84
119
  return piggy;
85
120
  },
86
121
 
122
+ // ── Sub-APIs (1:1 with C++ files, available after launch/connect) ─────────
123
+
124
+ get tabs() { return _router?.tabs ?? createTabsAPI(guardClient()); },
125
+ get navigation() { return _router?.navigation ?? createNavigationAPI(guardClient()); },
126
+ get interactions() { return _router?.interactions ?? createInteractionsAPI(guardClient()); },
127
+ get media() { return _router?.media ?? createMediaAPI(guardClient()); },
128
+ get capture() { return _router?.capture ?? createCaptureAPI(guardClient()); },
129
+ get find() { return _router?.find ?? createFindAPI(guardClient()); },
130
+ get provide() { return _router?.provide ?? createProvideAPI(guardClient()); },
131
+ get wait() { return _router?.wait ?? createWaitAPI(guardClient()); },
132
+ get evaluate() { return _router?.evaluate ?? createEvaluateAPI(guardClient()); },
133
+ get fetch() { return _router?.fetch ?? createFetchAPI(guardClient()); },
134
+ get captcha() { return _router?.captcha ?? createCaptchaAPI(guardClient()); },
135
+ get dialog() { return _router?.dialog ?? createDialogAPI(guardClient()); },
136
+ get human() { return _router?.human ?? createHumanAPI(guardClient()); },
137
+ get iframe() { return _router?.iframe ?? createIframeAPI(guardClient()); },
138
+ get session() { return _router?.session ?? createSessionAPI(guardClient()); },
139
+ get export() { return _router?.export ?? createExportAPI(guardClient()); },
140
+
141
+ // ── Proxy (global, not per-tab) ───────────────────────────────────────────
142
+ get proxy() {
143
+ const api = _router?.proxy ?? createProxyAPI(guardClient());
144
+ return {
145
+ load: (path: string) => api.load(path),
146
+ fetch: (url: string) => api.fetch(url),
147
+ ovpn: (path: string) => api.ovpn(path),
148
+ set: (opts: Parameters<typeof api.set>[0]) => api.set(opts),
149
+ test: () => api.test(),
150
+ testStop: () => api.testStop(),
151
+ next: () => api.next(),
152
+ rotate: () => api.rotate(),
153
+ disable: () => api.disable(),
154
+ enable: () => api.enable(),
155
+ current: () => api.current(),
156
+ stats: () => api.stats(),
157
+ list: (limit?: number) => api.list(limit),
158
+ rotation: (mode: "none" | "timed" | "perrequest", interval?: number) => api.rotation(mode, interval),
159
+ config: (opts: { skipDead?: boolean; autoCheck?: boolean }) => api.config(opts),
160
+ save: (path: string, filter?: "alive" | "dead" | "all") => api.save(path, filter),
161
+ on: (event: string, handler: (data: any) => void) => guardClient().onProxyEvent(event, handler),
162
+ };
163
+ },
164
+
87
165
  // ── Global controls ───────────────────────────────────────────────────────
88
166
  actHuman: (enable: boolean) => {
89
167
  setHumanMode(enable);
@@ -93,41 +171,19 @@ const piggy: any = {
93
171
 
94
172
  mode: (m: TabMode) => { _tabMode = m; return piggy; },
95
173
 
96
- // ── Expose Function ───────────────────────────────────────────────────────
174
+ // ── Global expose ─────────────────────────────────────────────────────────
97
175
  expose: async (name: string, handler: (data: any) => Promise<any> | any, tabId = "default") => {
98
- if (!_client) throw new Error("No client. Call piggy.launch() or piggy.connect() first.");
99
- await _client.exposeFunction(name, handler, tabId);
176
+ await guardClient().exposeFunction(name, handler, tabId);
100
177
  logger.success(`[piggy] exposed global function: ${name}`);
101
178
  return piggy;
102
179
  },
103
180
 
104
181
  unexpose: async (name: string, tabId = "default") => {
105
- if (!_client) throw new Error("No client. Call piggy.launch() or piggy.connect() first.");
106
- await _client.unexposeFunction(name, tabId);
182
+ await guardClient().unexposeFunction(name, tabId);
107
183
  logger.info(`[piggy] unexposed function: ${name}`);
108
184
  return piggy;
109
185
  },
110
186
 
111
- // ── Proxy ─────────────────────────────────────────────────────────────────
112
- proxy: {
113
- load: (path: string) => { if (!_client) throw new Error("No client"); return _client.proxyLoad(path); },
114
- fetch: (url: string) => { if (!_client) throw new Error("No client"); return _client.proxyFetch(url); },
115
- ovpn: (path: string) => { if (!_client) throw new Error("No client"); return _client.proxyOvpn(path); },
116
- set: (opts: Parameters<PiggyClient["proxySet"]>[0]) => { if (!_client) throw new Error("No client"); return _client.proxySet(opts); },
117
- test: () => { if (!_client) throw new Error("No client"); return _client.proxyTest(); },
118
- testStop: () => { if (!_client) throw new Error("No client"); return _client.proxyTestStop(); },
119
- next: () => { if (!_client) throw new Error("No client"); return _client.proxyNext(); },
120
- disable: () => { if (!_client) throw new Error("No client"); return _client.proxyDisable(); },
121
- enable: () => { if (!_client) throw new Error("No client"); return _client.proxyEnable(); },
122
- current: () => { if (!_client) throw new Error("No client"); return _client.proxyCurrent(); },
123
- stats: () => { if (!_client) throw new Error("No client"); return _client.proxyStats(); },
124
- list: (limit?: number) => { if (!_client) throw new Error("No client"); return _client.proxyList(limit); },
125
- rotation: (mode: "none" | "timed" | "perrequest", interval?: number) => { if (!_client) throw new Error("No client"); return _client.proxyRotation(mode, interval); },
126
- config: (opts: { skipDead?: boolean; autoCheck?: boolean }) => { if (!_client) throw new Error("No client"); return _client.proxyConfig(opts); },
127
- save: (path: string, filter?: "alive" | "dead" | "all") => { if (!_client) throw new Error("No client"); return _client.proxySave(path, filter); },
128
- on: (event: string, handler: (data: any) => void) => { if (!_client) throw new Error("No client"); return _client.onProxyEvent(event, handler); },
129
- },
130
-
131
187
  // ── Elysia server ─────────────────────────────────────────────────────────
132
188
  serve: (
133
189
  port: number,
@@ -155,7 +211,7 @@ const piggy: any = {
155
211
  };
156
212
  }),
157
213
 
158
- // ── Multi-site ────────────────────────────────────────────────────────────
214
+ // ── Multi-site helpers ────────────────────────────────────────────────────
159
215
  all: (sites: SiteObject[]) =>
160
216
  new Proxy({} as any, {
161
217
  get: (_, method: string) =>
@@ -189,6 +245,7 @@ const piggy: any = {
189
245
  _extraProcs.length = 0;
190
246
  _client?.disconnect();
191
247
  _client = null;
248
+ _router = null;
192
249
  setClient(null);
193
250
  killBrowser();
194
251
  }
@@ -201,8 +258,6 @@ const piggy: any = {
201
258
  };
202
259
 
203
260
  // ── usePiggy ──────────────────────────────────────────────────────────────────
204
- // Typed accessor — call AFTER register() so sites exist on piggy.
205
- // const { amazon, ebay } = usePiggy<"amazon" | "ebay">()
206
261
 
207
262
  type TypedPiggy<Sites extends string> = typeof piggy & {
208
263
  [K in Sites]: SiteObject;
@@ -1,4 +0,0 @@
1
- export default function open(): {
2
- name: string;
3
- };
4
- //# sourceMappingURL=index.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../piggy/open/index.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,OAAO,UAAU,IAAI;;EAI3B"}
@@ -1,4 +0,0 @@
1
- export default function open(): {
2
- name: string;
3
- };
4
- //# sourceMappingURL=index.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,OAAO,UAAU,IAAI;;EAI3B"}
@@ -1,5 +0,0 @@
1
- export default function open() {
2
- return {
3
- name: 'piggy-open',
4
- };
5
- }