arn-browser 0.1.22 → 0.1.24

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "arn-browser",
3
- "version": "0.1.22",
3
+ "version": "0.1.24",
4
4
  "description": "A lightweight, browser autmation helper.",
5
5
  "main": "src/index.js",
6
6
  "types": "src/index.d.ts",
@@ -30,10 +30,14 @@ export interface GeoDetails {
30
30
  export interface TrafficStats {
31
31
  /** Number of requests handled */
32
32
  req: number;
33
- /** Data sent to client (Formatted MB string) */
34
- Tx: string;
35
- /** Data received from client (Formatted MB string) */
36
- Rx: string;
33
+ /** Data sent to client (source Tx, formatted string) */
34
+ sTx: string;
35
+ /** Data received from client (source Rx, formatted string) */
36
+ sRx: string;
37
+ /** Data sent to upstream proxy (target Tx, formatted string). Only present when showTg is true. */
38
+ tTx?: string;
39
+ /** Data received from upstream proxy (target Rx, formatted string). Only present when showTg is true. */
40
+ tRx?: string;
37
41
  }
38
42
 
39
43
  /**
@@ -60,7 +64,7 @@ export interface ProxyServerOptions {
60
64
  */
61
65
  ip2LocationKey?: string;
62
66
 
63
- /** Retry delay in milliseconds between IP lookup attempts (default: 1500) */
67
+ /** Retry delay in milliseconds between IP lookup attempts (default: 1000) */
64
68
  retryDelayMs?: number;
65
69
 
66
70
  /** Enable verbose logging (default: false) */
@@ -69,6 +73,8 @@ export interface ProxyServerOptions {
69
73
  proxy_stats?: boolean;
70
74
  /** Track hostname usage statistics (default: true) */
71
75
  host_stats?: boolean;
76
+ /** Show target bytes (tTx/tRx) in stats output (default: false) */
77
+ tg_stats?: boolean;
72
78
  }
73
79
 
74
80
  /**
@@ -137,6 +143,6 @@ export function fetchPublicIP(proxyUrl: string | null): Promise<GeoDetails | nul
137
143
  * Fetches proxy details (IP, country, city, timezone) with retries.
138
144
  * @param proxyUrl The proxy URL string. Pass `null` for local fallback.
139
145
  * @param apiKey Optional IP2Location API key.
140
- * @param retryDelayMs Delay between retries in ms (default: 1500).
146
+ * @param retryDelayMs Delay between retries in ms (default: 1000).
141
147
  */
142
148
  export function fetchProxyDetails(proxyUrl: string | null, apiKey?: string | null, retryDelayMs?: number): Promise<GeoDetails | null>;
@@ -10,8 +10,8 @@ import { SocksProxyAgent } from "socks-proxy-agent";
10
10
  // SECTION 1: NETWORK HELPERS
11
11
  // ==========================================
12
12
 
13
- function nativeGet(url, agent = null, timeout = 5000) {
14
- return new Promise((resolve, reject) => {
13
+ async function nativeGet(url, agent = null, timeout = 5000, retries = 5) {
14
+ const attempt = () => new Promise((resolve, reject) => {
15
15
  const urlObj = new URL(url);
16
16
  const requestModule = urlObj.protocol === "https:" ? https : http;
17
17
 
@@ -40,6 +40,15 @@ function nativeGet(url, agent = null, timeout = 5000) {
40
40
  reject(new Error("Request Timed Out"));
41
41
  });
42
42
  });
43
+
44
+ for (let i = 1; i <= retries; i++) {
45
+ try {
46
+ return await attempt();
47
+ } catch (err) {
48
+ if (i === retries) throw err;
49
+ await sleep(1000);
50
+ }
51
+ }
43
52
  }
44
53
 
45
54
  const isPortAvailable = (port) => {
@@ -101,7 +110,7 @@ export async function fetchPublicIP(proxyUrl) {
101
110
  * 1. If proxyUrl is provided -> Fetch Real Data (IP + Timezone).
102
111
  * 2. If proxyUrl is NULL/Undefined -> Return "Local" Mock immediately.
103
112
  */
104
- export async function fetchProxyDetails(proxyUrl, apiKey = null, retryDelayMs = 1500) {
113
+ export async function fetchProxyDetails(proxyUrl, apiKey = null, retryDelayMs = 1000) {
105
114
  // --- AUTOMATIC LOCAL FALLBACK ---
106
115
  if (!proxyUrl) {
107
116
  return {
@@ -112,9 +121,9 @@ export async function fetchProxyDetails(proxyUrl, apiKey = null, retryDelayMs =
112
121
  };
113
122
  }
114
123
 
115
- // --- EXTERNAL LOOKUP with retry (10 attempts) ---
124
+ // --- EXTERNAL LOOKUP with retry (5 attempts) ---
116
125
  const providers = ["IP-API", "IP2Location"];
117
- const MAX_RETRIES = 10;
126
+ const MAX_RETRIES = 5;
118
127
 
119
128
  for (let attempt = 1; attempt <= MAX_RETRIES; attempt++) {
120
129
  for (const provider of providers) {
@@ -186,10 +195,11 @@ export async function startProxyServer({
186
195
  PROXY_2_HOSTS = [],
187
196
  NO_PROXY_HOSTS = [],
188
197
  ip2LocationKey = null,
189
- retryDelayMs = 1500,
198
+ retryDelayMs = 1000,
190
199
  debug = false,
191
200
  proxy_stats = true,
192
201
  host_stats = true,
202
+ tg_stats = false,
193
203
  }) {
194
204
  // 1. Matchers
195
205
  const matchers = {
@@ -360,16 +370,21 @@ export async function startProxyServer({
360
370
  return (bytes / (1024 * 1024)).toFixed(3) + " MB";
361
371
  };
362
372
 
373
+
374
+
363
375
  const getProxyStatsFormatted = () => {
364
376
  const formatted = {};
365
377
  for (const [key, val] of Object.entries(stats)) {
366
- formatted[key] = {
378
+ const entry = {
367
379
  req: val.request,
368
380
  sTx: formatBytes(val.srcTx),
369
381
  sRx: formatBytes(val.srcRx),
370
- tTx: formatBytes(val.trgTx),
371
- tRx: formatBytes(val.trgRx),
372
382
  };
383
+ if (tg_stats) {
384
+ entry.tTx = formatBytes(val.trgTx);
385
+ entry.tRx = formatBytes(val.trgRx);
386
+ }
387
+ formatted[key] = entry;
373
388
  }
374
389
  return formatted;
375
390
  };
@@ -380,13 +395,16 @@ export async function startProxyServer({
380
395
  const sortedHosts = Object.entries(hosts)
381
396
  .sort((a, b) => b[1].req - a[1].req)
382
397
  .reduce((acc, [host, hostData]) => {
383
- acc[host] = {
398
+ const entry = {
384
399
  req: hostData.req,
385
400
  sTx: formatBytes(hostData.srcTx),
386
401
  sRx: formatBytes(hostData.srcRx),
387
- tTx: formatBytes(hostData.trgTx),
388
- tRx: formatBytes(hostData.trgRx),
389
402
  };
403
+ if (tg_stats) {
404
+ entry.tTx = formatBytes(hostData.trgTx);
405
+ entry.tRx = formatBytes(hostData.trgRx);
406
+ }
407
+ acc[host] = entry;
390
408
  return acc;
391
409
  }, {});
392
410
 
@@ -425,11 +443,11 @@ export async function startProxyServer({
425
443
  await server.close(true);
426
444
  serverRunning = false;
427
445
 
428
- // Wait up to 2000ms (2 seconds) for all async 'connectionClosed' events to fire
446
+ // Wait up to 5000ms (5 seconds) for all async 'connectionClosed' events to fire
429
447
  // When sockets are destroyed, their 'close' events happen asynchronously
430
- let maxWait = 200; // 200 * 10ms = 2000ms
448
+ let maxWait = 250; // 250 * 20ms = 5000ms
431
449
  while (Object.keys(connectionMap).length > 0 && maxWait > 0) {
432
- await new Promise((resolve) => setTimeout(resolve, 10));
450
+ await new Promise((resolve) => setTimeout(resolve, 20));
433
451
  maxWait--;
434
452
  }
435
453