nothing-browser 0.0.8 → 0.0.9

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.
@@ -889,6 +889,9 @@ class PiggyClient {
889
889
  async evaluate(js, tabId = "default") {
890
890
  return this.send("evaluate", { js, tabId });
891
891
  }
892
+ async addInitScript(js, tabId = "default") {
893
+ await this.send("addInitScript", { js, tabId });
894
+ }
892
895
  async click(selector, tabId = "default") {
893
896
  return this.send("click", { selector, tabId });
894
897
  }
@@ -1039,9 +1042,8 @@ class PiggyClient {
1039
1042
  }
1040
1043
  async unexposeFunction(name, tabId = "default") {
1041
1044
  const handlers = this.eventHandlers.get(tabId);
1042
- if (handlers) {
1045
+ if (handlers)
1043
1046
  handlers.delete(name);
1044
- }
1045
1047
  logger_default.info(`[${tabId}] unexposed function: ${name}`);
1046
1048
  }
1047
1049
  async clearExposedFunctions(tabId = "default") {
package/dist/piggy.js CHANGED
@@ -6417,6 +6417,9 @@ class PiggyClient {
6417
6417
  async evaluate(js, tabId = "default") {
6418
6418
  return this.send("evaluate", { js, tabId });
6419
6419
  }
6420
+ async addInitScript(js, tabId = "default") {
6421
+ await this.send("addInitScript", { js, tabId });
6422
+ }
6420
6423
  async click(selector, tabId = "default") {
6421
6424
  return this.send("click", { selector, tabId });
6422
6425
  }
@@ -6567,9 +6570,8 @@ class PiggyClient {
6567
6570
  }
6568
6571
  async unexposeFunction(name, tabId = "default") {
6569
6572
  const handlers = this.eventHandlers.get(tabId);
6570
- if (handlers) {
6573
+ if (handlers)
6571
6574
  handlers.delete(name);
6572
- }
6573
6575
  logger_default.info(`[${tabId}] unexposed function: ${name}`);
6574
6576
  }
6575
6577
  async clearExposedFunctions(tabId = "default") {
@@ -21261,6 +21263,12 @@ function createSiteObject(name, registeredUrl, client, tabId) {
21261
21263
  },
21262
21264
  waitForVisible: (selector, timeout = 30000) => client.waitForSelector(selector, timeout, tabId),
21263
21265
  waitForResponse: (pattern, timeout = 30000) => client.waitForResponse(pattern, timeout, tabId),
21266
+ addInitScript: async (js) => {
21267
+ const code = typeof js === "function" ? `(${js.toString()})();` : js;
21268
+ await client.addInitScript(code, tabId);
21269
+ logger_default.success(`[${name}] init script added`);
21270
+ return site;
21271
+ },
21264
21272
  click: (selector, opts) => withErrScreen(() => retry(name, async () => {
21265
21273
  if (humanMode)
21266
21274
  await randomDelay(80, 220);
@@ -21370,9 +21378,9 @@ function createSiteObject(name, registeredUrl, client, tabId) {
21370
21378
  logger_default.info(`[${name}] images unblocked`);
21371
21379
  },
21372
21380
  cookies: {
21373
- set: async (name2, value, domain, path = "/") => {
21374
- await client.setCookie(name2, value, domain, path, tabId);
21375
- logger_default.info(`[${name2}] cookie set: ${name2} @ ${domain}`);
21381
+ set: async (cookieName, value, domain, path = "/") => {
21382
+ await client.setCookie(cookieName, value, domain, path, tabId);
21383
+ logger_default.info(`[${name}] cookie set: ${cookieName} @ ${domain}`);
21376
21384
  },
21377
21385
  get: (cookieName) => client.getCookie(cookieName, tabId),
21378
21386
  delete: async (cookieName) => {
@@ -16775,6 +16775,12 @@ function createSiteObject(name, registeredUrl, client, tabId) {
16775
16775
  },
16776
16776
  waitForVisible: (selector, timeout = 30000) => client.waitForSelector(selector, timeout, tabId),
16777
16777
  waitForResponse: (pattern, timeout = 30000) => client.waitForResponse(pattern, timeout, tabId),
16778
+ addInitScript: async (js) => {
16779
+ const code = typeof js === "function" ? `(${js.toString()})();` : js;
16780
+ await client.addInitScript(code, tabId);
16781
+ logger_default.success(`[${name}] init script added`);
16782
+ return site;
16783
+ },
16778
16784
  click: (selector, opts) => withErrScreen(() => retry(name, async () => {
16779
16785
  if (humanMode)
16780
16786
  await randomDelay(80, 220);
@@ -16884,9 +16890,9 @@ function createSiteObject(name, registeredUrl, client, tabId) {
16884
16890
  logger_default.info(`[${name}] images unblocked`);
16885
16891
  },
16886
16892
  cookies: {
16887
- set: async (name2, value, domain, path = "/") => {
16888
- await client.setCookie(name2, value, domain, path, tabId);
16889
- logger_default.info(`[${name2}] cookie set: ${name2} @ ${domain}`);
16893
+ set: async (cookieName, value, domain, path = "/") => {
16894
+ await client.setCookie(cookieName, value, domain, path, tabId);
16895
+ logger_default.info(`[${name}] cookie set: ${cookieName} @ ${domain}`);
16890
16896
  },
16891
16897
  get: (cookieName) => client.getCookie(cookieName, tabId),
16892
16898
  delete: async (cookieName) => {
@@ -16999,9 +17005,8 @@ function createExposedAPI(site, apiName, handlers) {
16999
17005
  const wrappedHandler = async (call) => {
17000
17006
  const { method, args } = call;
17001
17007
  const handler = handlers[method];
17002
- if (!handler) {
17008
+ if (!handler)
17003
17009
  throw new Error(`Unknown method: ${method}`);
17004
- }
17005
17010
  try {
17006
17011
  return await handler(args);
17007
17012
  } catch (err) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nothing-browser",
3
- "version": "0.0.8",
3
+ "version": "0.0.9",
4
4
  "description": "Browser automation library powered by Nothing Browser",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",
@@ -45,13 +45,11 @@ export class PiggyClient {
45
45
  try {
46
46
  const msg = JSON.parse(line);
47
47
 
48
- // Handle events
49
48
  if (msg.type === "event") {
50
49
  this.handleEvent(msg);
51
50
  continue;
52
51
  }
53
52
 
54
- // Handle command responses
55
53
  const p = this.pending.get(msg.id);
56
54
  if (p) {
57
55
  this.pending.delete(msg.id);
@@ -103,7 +101,6 @@ export class PiggyClient {
103
101
  }).catch(e => logger.error(`Failed to send exposed error: ${e}`));
104
102
  }
105
103
  } else {
106
- // Handler returned raw value
107
104
  this.send("exposed.result", {
108
105
  tabId: effectiveTabId,
109
106
  callId,
@@ -192,6 +189,12 @@ export class PiggyClient {
192
189
  return this.send("evaluate", { js, tabId });
193
190
  }
194
191
 
192
+ // ── Init Script ───────────────────────────────────────────────────────────────
193
+ // HERE IT IS - ADD THIS METHOD TO THE CLIENT
194
+ async addInitScript(js: string, tabId = "default"): Promise<void> {
195
+ await this.send("addInitScript", { js, tabId });
196
+ }
197
+
195
198
  // ── Interactions ──────────────────────────────────────────────────────────────
196
199
 
197
200
  async click(selector: string, tabId = "default"): Promise<boolean> {
@@ -318,13 +321,7 @@ export class PiggyClient {
318
321
 
319
322
  // ── Cookies ───────────────────────────────────────────────────────────────────
320
323
 
321
- async setCookie(
322
- name: string,
323
- value: string,
324
- domain: string,
325
- path = "/",
326
- tabId = "default"
327
- ): Promise<void> {
324
+ async setCookie(name: string, value: string, domain: string, path = "/", tabId = "default"): Promise<void> {
328
325
  await this.send("cookie.set", { name, value, domain, path, tabId });
329
326
  }
330
327
 
@@ -342,12 +339,7 @@ export class PiggyClient {
342
339
 
343
340
  // ── Interception ──────────────────────────────────────────────────────────────
344
341
 
345
- async addInterceptRule(
346
- action: "block" | "redirect" | "modifyHeaders",
347
- pattern: string,
348
- options: { redirectUrl?: string; headers?: Record<string, string> } = {},
349
- tabId = "default"
350
- ): Promise<void> {
342
+ async addInterceptRule(action: "block" | "redirect" | "modifyHeaders", pattern: string, options: { redirectUrl?: string; headers?: Record<string, string> } = {}, tabId = "default"): Promise<void> {
351
343
  await this.send("intercept.rule.add", { action, pattern, ...options, tabId });
352
344
  }
353
345
 
@@ -397,15 +389,10 @@ export class PiggyClient {
397
389
 
398
390
  // ── Expose Function ───────────────────────────────────────────────────────────
399
391
 
400
- async exposeFunction(
401
- name: string,
402
- handler: (data: any) => Promise<any> | any,
403
- tabId = "default"
404
- ): Promise<void> {
392
+ async exposeFunction(name: string, handler: (data: any) => Promise<any> | any, tabId = "default"): Promise<void> {
405
393
  if (!this.eventHandlers.has(tabId)) {
406
394
  this.eventHandlers.set(tabId, new Map());
407
395
  }
408
-
409
396
  this.eventHandlers.get(tabId)!.set(name, async (data: any) => {
410
397
  try {
411
398
  const result = await handler(data);
@@ -417,16 +404,13 @@ export class PiggyClient {
417
404
  return { success: false, error: err.message || String(err) };
418
405
  }
419
406
  });
420
-
421
407
  await this.send("expose.function", { name, tabId });
422
408
  logger.success(`[${tabId}] exposed function: ${name}`);
423
409
  }
424
410
 
425
411
  async unexposeFunction(name: string, tabId = "default"): Promise<void> {
426
412
  const handlers = this.eventHandlers.get(tabId);
427
- if (handlers) {
428
- handlers.delete(name);
429
- }
413
+ if (handlers) handlers.delete(name);
430
414
  logger.info(`[${tabId}] unexposed function: ${name}`);
431
415
  }
432
416
 
@@ -10,12 +10,7 @@ export let humanMode = false;
10
10
  export function setClient(c: PiggyClient | null) { globalClient = c; }
11
11
  export function setHumanMode(v: boolean) { humanMode = v; }
12
12
 
13
- async function retry<T>(
14
- label: string,
15
- fn: () => Promise<T>,
16
- retries = 2,
17
- backoff = 150
18
- ): Promise<T> {
13
+ async function retry<T>(label: string, fn: () => Promise<T>, retries = 2, backoff = 150): Promise<T> {
19
14
  let last!: Error;
20
15
  for (let i = 0; i <= retries; i++) {
21
16
  try { return await fn(); } catch (e: any) {
@@ -29,12 +24,7 @@ async function retry<T>(
29
24
  throw last;
30
25
  }
31
26
 
32
- export function createSiteObject(
33
- name: string,
34
- registeredUrl: string,
35
- client: PiggyClient,
36
- tabId: string
37
- ) {
27
+ export function createSiteObject(name: string, registeredUrl: string, client: PiggyClient, tabId: string) {
38
28
  let _currentUrl: string = registeredUrl;
39
29
 
40
30
  const withErrScreen = async <T>(fn: () => Promise<T>, label: string): Promise<T> => {
@@ -51,7 +41,6 @@ export function createSiteObject(
51
41
  _tabId: tabId,
52
42
 
53
43
  // ── Navigation ─────────────────────────────────────────────────────────────
54
-
55
44
  navigate: (url?: string, opts?: { retries?: number }) => {
56
45
  const target = url ?? registeredUrl;
57
46
  return retry(name, async () => {
@@ -86,8 +75,16 @@ export function createSiteObject(
86
75
  waitForVisible: (selector: string, timeout = 30000) => client.waitForSelector(selector, timeout, tabId),
87
76
  waitForResponse: (pattern: string, timeout = 30000) => client.waitForResponse(pattern, timeout, tabId),
88
77
 
89
- // ── Interactions ───────────────────────────────────────────────────────────
78
+ // ── Init Script ─────────────────────────────────────────────────────────────
79
+ // HERE IT IS - ADD THIS METHOD TO THE SITE OBJECT
80
+ addInitScript: async (js: string | (() => void)) => {
81
+ const code = typeof js === 'function' ? `(${js.toString()})();` : js;
82
+ await client.addInitScript(code, tabId);
83
+ logger.success(`[${name}] init script added`);
84
+ return site;
85
+ },
90
86
 
87
+ // ── Interactions ───────────────────────────────────────────────────────────
91
88
  click: (selector: string, opts?: { retries?: number; timeout?: number }) =>
92
89
  withErrScreen(() =>
93
90
  retry(name, async () => {
@@ -173,7 +170,6 @@ export function createSiteObject(
173
170
  },
174
171
 
175
172
  // ── Fetch ──────────────────────────────────────────────────────────────────
176
-
177
173
  fetchText: (selector: string) => client.fetchText(selector, tabId),
178
174
  fetchLinks: async (selector: string) => {
179
175
  const links = await client.fetchLinks(selector, tabId);
@@ -192,7 +188,6 @@ export function createSiteObject(
192
188
  },
193
189
 
194
190
  // ── Screenshot / PDF ───────────────────────────────────────────────────────
195
-
196
191
  screenshot: async (filePath?: string) => {
197
192
  const r = await client.screenshot(filePath, tabId);
198
193
  logger.success(`[${name}] screenshot → ${filePath ?? "base64"}`);
@@ -208,11 +203,10 @@ export function createSiteObject(
208
203
  unblockImages: async () => { await client.unblockImages(tabId); logger.info(`[${name}] images unblocked`); },
209
204
 
210
205
  // ── Cookies ────────────────────────────────────────────────────────────────
211
-
212
206
  cookies: {
213
- set: async (name: string, value: string, domain: string, path = "/") => {
214
- await client.setCookie(name, value, domain, path, tabId);
215
- logger.info(`[${name}] cookie set: ${name} @ ${domain}`);
207
+ set: async (cookieName: string, value: string, domain: string, path = "/") => {
208
+ await client.setCookie(cookieName, value, domain, path, tabId);
209
+ logger.info(`[${name}] cookie set: ${cookieName} @ ${domain}`);
216
210
  },
217
211
  get: (cookieName: string) => client.getCookie(cookieName, tabId),
218
212
  delete: async (cookieName: string) => {
@@ -223,7 +217,6 @@ export function createSiteObject(
223
217
  },
224
218
 
225
219
  // ── Interception ───────────────────────────────────────────────────────────
226
-
227
220
  intercept: {
228
221
  block: async (pattern: string) => {
229
222
  await client.addInterceptRule("block", pattern, {}, tabId);
@@ -244,7 +237,6 @@ export function createSiteObject(
244
237
  },
245
238
 
246
239
  // ── Network capture ────────────────────────────────────────────────────────
247
-
248
240
  capture: {
249
241
  start: async () => {
250
242
  await client.captureStart(tabId);
@@ -265,7 +257,6 @@ export function createSiteObject(
265
257
  },
266
258
 
267
259
  // ── Session ────────────────────────────────────────────────────────────────
268
-
269
260
  session: {
270
261
  export: async () => {
271
262
  const data = await client.sessionExport(tabId);
@@ -279,7 +270,6 @@ export function createSiteObject(
279
270
  },
280
271
 
281
272
  // ── Expose Function ─────────────────────────────────────────────────────────
282
-
283
273
  exposeFunction: async (fnName: string, handler: (data: any) => Promise<any> | any) => {
284
274
  await client.exposeFunction(fnName, handler, tabId);
285
275
  logger.success(`[${name}] exposed function: ${fnName}`);
@@ -298,29 +288,16 @@ export function createSiteObject(
298
288
  return site;
299
289
  },
300
290
 
301
- exposeAndInject: async (
302
- fnName: string,
303
- handler: (data: any) => Promise<any> | any,
304
- injectionJs: string | ((fnName: string) => string)
305
- ) => {
291
+ exposeAndInject: async (fnName: string, handler: (data: any) => Promise<any> | any, injectionJs: string | ((fnName: string) => string)) => {
306
292
  await client.exposeFunction(fnName, handler, tabId);
307
-
308
- const js = typeof injectionJs === "function"
309
- ? injectionJs(fnName)
310
- : injectionJs;
311
-
293
+ const js = typeof injectionJs === "function" ? injectionJs(fnName) : injectionJs;
312
294
  await client.evaluate(js, tabId);
313
295
  logger.success(`[${name}] exposed and injected: ${fnName}`);
314
296
  return site;
315
297
  },
316
298
 
317
299
  // ── Elysia API ─────────────────────────────────────────────────────────────
318
-
319
- api: (
320
- path: string,
321
- handler: RouteHandler,
322
- opts?: { ttl?: number; before?: BeforeMiddleware[]; method?: "GET" | "POST" | "PUT" | "DELETE" }
323
- ) => {
300
+ api: (path: string, handler: RouteHandler, opts?: { ttl?: number; before?: BeforeMiddleware[]; method?: "GET" | "POST" | "PUT" | "DELETE" }) => {
324
301
  const key = `${name}:${path}`;
325
302
  if (routeRegistry.has(key)) {
326
303
  logger.warn(`[${name}] route ${path} already registered`);
@@ -351,21 +328,11 @@ export function createSiteObject(
351
328
  return site;
352
329
  }
353
330
 
354
- // ── Helper for creating structured APIs ───────────────────────────────────────
355
-
356
- export function createExposedAPI<T extends Record<string, (data: any) => any>>(
357
- site: any,
358
- apiName: string,
359
- handlers: T
360
- ): Promise<void> {
331
+ export function createExposedAPI<T extends Record<string, (data: any) => any>>(site: any, apiName: string, handlers: T): Promise<void> {
361
332
  const wrappedHandler = async (call: any) => {
362
333
  const { method, args } = call;
363
334
  const handler = handlers[method as keyof T];
364
-
365
- if (!handler) {
366
- throw new Error(`Unknown method: ${method}`);
367
- }
368
-
335
+ if (!handler) throw new Error(`Unknown method: ${method}`);
369
336
  try {
370
337
  return await handler(args);
371
338
  } catch (err) {
@@ -373,6 +340,5 @@ export function createExposedAPI<T extends Record<string, (data: any) => any>>(
373
340
  throw err;
374
341
  }
375
342
  };
376
-
377
343
  return site.exposeFunction(apiName, wrappedHandler);
378
344
  }