@letsscrapedata/controller 0.0.1 → 0.0.3

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/index.js CHANGED
@@ -1,4 +1,3 @@
1
- "use strict";
2
1
  var __create = Object.create;
3
2
  var __defProp = Object.defineProperty;
4
3
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
@@ -28,13 +27,12 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
28
27
  isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
29
28
  mod
30
29
  ));
31
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
32
30
 
33
31
  // ../../node_modules/boolbase/index.js
34
32
  var require_boolbase = __commonJS({
35
- "../../node_modules/boolbase/index.js"(exports2, module2) {
33
+ "../../node_modules/boolbase/index.js"(exports, module) {
36
34
  "use strict";
37
- module2.exports = {
35
+ module.exports = {
38
36
  trueFunc: function trueFunc2() {
39
37
  return true;
40
38
  },
@@ -45,23 +43,6 @@ var require_boolbase = __commonJS({
45
43
  }
46
44
  });
47
45
 
48
- // src/index.ts
49
- var src_exports = {};
50
- __export(src_exports, {
51
- CheerioElement: () => CheerioElement,
52
- CheerioPage: () => CheerioPage,
53
- PlaywrightBrowser: () => PlaywrightBrowser,
54
- PlaywrightBrowserContext: () => PlaywrightBrowserContext,
55
- PlaywrightElement: () => PlaywrightElement,
56
- PlaywrightPage: () => PlaywrightPage,
57
- PuppeteerBrowser: () => PuppeteerBrowser,
58
- PuppeteerBrowserContext: () => PuppeteerBrowserContext,
59
- PuppeteerElement: () => PuppeteerElement,
60
- PuppeteerPage: () => PuppeteerPage,
61
- defaultProxy: () => defaultProxy
62
- });
63
- module.exports = __toCommonJS(src_exports);
64
-
65
46
  // src/types/types.ts
66
47
  var defaultProxy = {
67
48
  server: "default",
@@ -73,18 +54,18 @@ var defaultProxy = {
73
54
  };
74
55
 
75
56
  // src/playwright/browser.ts
76
- var import_node_events3 = __toESM(require("events"));
57
+ import EventEmitter3 from "events";
77
58
 
78
59
  // src/playwright/context.ts
79
- var import_node_events2 = __toESM(require("events"));
80
- var import_utils3 = require("@letsscrapedata/utils");
60
+ import EventEmitter2 from "events";
61
+ import { getCurrentUnixTime as getCurrentUnixTime2, logerr as logerr2, loginfo as loginfo2, logwarn as logwarn2, sleep } from "@letsscrapedata/utils";
81
62
 
82
63
  // src/playwright/page.ts
83
- var import_node_events = __toESM(require("events"));
84
- var import_utils2 = require("@letsscrapedata/utils");
64
+ import EventEmitter from "events";
65
+ import { getCurrentUnixTime, logerr, loginfo, logwarn, unreachable as unreachable2 } from "@letsscrapedata/utils";
85
66
 
86
67
  // src/playwright/element.ts
87
- var import_utils = require("@letsscrapedata/utils");
68
+ import { unreachable } from "@letsscrapedata/utils";
88
69
  var PlaywrightElement = class _PlaywrightElement {
89
70
  #frame;
90
71
  #locator;
@@ -300,39 +281,21 @@ var PlaywrightElement = class _PlaywrightElement {
300
281
  }
301
282
  break;
302
283
  default:
303
- (0, import_utils.unreachable)(type);
284
+ unreachable(type);
304
285
  }
305
286
  return true;
306
287
  }
307
288
  async screenshot(options) {
308
289
  return await this.#locator.screenshot(options);
309
290
  }
310
- async scrollBy(x, y) {
311
- await this.#locator.page().evaluate(
312
- ([x2, y2]) => {
313
- window.scrollBy(x2, y2);
314
- },
315
- [x, y]
316
- );
317
- return true;
318
- }
319
291
  async scrollIntoView() {
320
292
  await this.#locator.scrollIntoViewIfNeeded();
321
293
  return true;
322
294
  }
323
- async scrollTo(x, y) {
324
- await this.#locator.page().evaluate(
325
- ([x2, y2]) => {
326
- window.scrollTo(x2, y2);
327
- },
328
- [x, y]
329
- );
330
- return true;
331
- }
332
295
  };
333
296
 
334
297
  // src/playwright/page.ts
335
- var PlaywrightPage = class extends import_node_events.default {
298
+ var PlaywrightPage = class extends EventEmitter {
336
299
  #lsdBrowserContext;
337
300
  #page;
338
301
  #status;
@@ -354,7 +317,7 @@ var PlaywrightPage = class extends import_node_events.default {
354
317
  const cookieItems = await this.#getCookies(page);
355
318
  const domainSet = new Set(cookieItems.map((c) => c.domain));
356
319
  if (domainSet.size !== 1) {
357
- (0, import_utils2.logwarn)(`Domains in clearCookies: ${Array.from(domainSet.values())}`);
320
+ logwarn(`Domains in clearCookies: ${Array.from(domainSet.values())}`);
358
321
  }
359
322
  for (const domain of domainSet.values()) {
360
323
  await browserContext.clearCookies({ domain });
@@ -506,9 +469,9 @@ var PlaywrightPage = class extends import_node_events.default {
506
469
  const page = this.#page;
507
470
  const pageId = this.#pageId;
508
471
  page.on("close", async () => {
509
- (0, import_utils2.loginfo)(`##browser ${pageId} closed`);
472
+ loginfo(`##browser ${pageId} closed`);
510
473
  if (!page.pageInfo) {
511
- (0, import_utils2.logerr)(`Logic error in page.on("close")`);
474
+ logerr(`Logic error in page.on("close")`);
512
475
  }
513
476
  this.emit("pageClose");
514
477
  this.#lsdBrowserContext.emit("pageClose", this);
@@ -522,12 +485,12 @@ var PlaywrightPage = class extends import_node_events.default {
522
485
  popupPageId = `page-${browserIdx}-${browserContextIdx}-${pageIdx}`;
523
486
  pageInfo.openType = "popup";
524
487
  } else {
525
- (0, import_utils2.logerr)(`##browser ${pageId} has popup without page.pageInfo`);
488
+ logerr(`##browser ${pageId} has popup without page.pageInfo`);
526
489
  }
527
- (0, import_utils2.loginfo)(`##browser ${pageId} has popup ${popupPageId}`);
490
+ loginfo(`##browser ${pageId} has popup ${popupPageId}`);
528
491
  this.emit("pagePopup", pageInfo);
529
492
  } else {
530
- (0, import_utils2.logerr)(`##browser ${pageId} has popup page with null page`);
493
+ logerr(`##browser ${pageId} has popup page with null page`);
531
494
  }
532
495
  });
533
496
  }
@@ -539,7 +502,7 @@ var PlaywrightPage = class extends import_node_events.default {
539
502
  this.#lsdBrowserContext = browserContext;
540
503
  this.#page = page;
541
504
  this.#status = "free";
542
- const currentTime = (0, import_utils2.getCurrentUnixTime)();
505
+ const currentTime = getCurrentUnixTime();
543
506
  const { browserIdx = 0, browserContextIdx = 0, pageIdx = 0, openType = "other", openTime = currentTime, lastStatusUpdateTime = currentTime, taskId = 0 } = pageInfo ? pageInfo : {};
544
507
  this.#page.pageInfo = { browserIdx, browserContextIdx, pageIdx, openType, openTime, lastStatusUpdateTime, taskId };
545
508
  this.#pageId = `page${browserIdx}-${browserContextIdx}-${pageIdx}`;
@@ -587,7 +550,7 @@ var PlaywrightPage = class extends import_node_events.default {
587
550
  }
588
551
  return true;
589
552
  } catch (err) {
590
- (0, import_utils2.logerr)(err);
553
+ logerr(err);
591
554
  return false;
592
555
  }
593
556
  }
@@ -685,12 +648,19 @@ var PlaywrightPage = class extends import_node_events.default {
685
648
  await this.clearResponseInterceptions();
686
649
  return true;
687
650
  }
651
+ #getWaitUntil(origWaitUntil) {
652
+ if (origWaitUntil === "networkidle0" || origWaitUntil === "networkidle2") {
653
+ return "networkidle";
654
+ } else {
655
+ return origWaitUntil;
656
+ }
657
+ }
688
658
  async goto(url, options) {
689
659
  if (!this.#page) {
690
660
  throw new Error("No valid page");
691
661
  }
692
662
  if (options) {
693
- const { referer, timeout, waitUntil } = options;
663
+ const { referer, timeout, waitUntil = "load" } = options;
694
664
  const newOptions = {};
695
665
  if (referer) {
696
666
  newOptions.referer = referer;
@@ -698,9 +668,7 @@ var PlaywrightPage = class extends import_node_events.default {
698
668
  if (timeout) {
699
669
  newOptions.timeout = timeout;
700
670
  }
701
- if (waitUntil && waitUntil !== "commit") {
702
- newOptions.waitUntil = waitUntil === "networkidle" ? "networkidle0" : waitUntil;
703
- }
671
+ newOptions.waitUntil = this.#getWaitUntil(waitUntil);
704
672
  await this.#page.goto(url, newOptions);
705
673
  } else {
706
674
  await this.#page.goto(url);
@@ -771,6 +739,30 @@ var PlaywrightPage = class extends import_node_events.default {
771
739
  }
772
740
  return await this.#page.screenshot(options);
773
741
  }
742
+ async scrollBy(x, y) {
743
+ if (!this.#page) {
744
+ throw new Error("No valid page");
745
+ }
746
+ await this.#page.evaluate(
747
+ ([x2, y2]) => {
748
+ window.scrollBy(x2, y2);
749
+ },
750
+ [x, y]
751
+ );
752
+ return true;
753
+ }
754
+ async scrollTo(x, y) {
755
+ if (!this.#page) {
756
+ throw new Error("No valid page");
757
+ }
758
+ await this.#page.evaluate(
759
+ ([x2, y2]) => {
760
+ window.scrollTo(x2, y2);
761
+ },
762
+ [x, y]
763
+ );
764
+ return true;
765
+ }
774
766
  async setCookies(cookies) {
775
767
  if (!this.#page) {
776
768
  throw new Error("No valid page");
@@ -831,7 +823,7 @@ var PlaywrightPage = class extends import_node_events.default {
831
823
  }
832
824
  return true;
833
825
  } catch (err) {
834
- (0, import_utils2.logerr)(err);
826
+ logerr(err);
835
827
  return false;
836
828
  }
837
829
  }
@@ -841,7 +833,7 @@ var PlaywrightPage = class extends import_node_events.default {
841
833
  }
842
834
  const actOptions = Array.isArray(options) ? options : [options];
843
835
  if (actOptions.length <= 0) {
844
- (0, import_utils2.logwarn)("Invalid paras in setRequestInterception");
836
+ logwarn("Invalid paras in setRequestInterception");
845
837
  return false;
846
838
  }
847
839
  const firstRequestInterception = this.#resquestInterceptionOptions.length <= 0;
@@ -852,7 +844,7 @@ var PlaywrightPage = class extends import_node_events.default {
852
844
  this.#resquestInterceptionOptions.push(option);
853
845
  break;
854
846
  default:
855
- (0, import_utils2.unreachable)(option.action);
847
+ unreachable2(option.action);
856
848
  }
857
849
  }
858
850
  if (firstRequestInterception && this.#resquestInterceptionOptions.length > 0) {
@@ -876,7 +868,7 @@ var PlaywrightPage = class extends import_node_events.default {
876
868
  });
877
869
  break;
878
870
  default:
879
- (0, import_utils2.unreachable)(action);
871
+ unreachable2(action);
880
872
  }
881
873
  return true;
882
874
  } else {
@@ -885,7 +877,7 @@ var PlaywrightPage = class extends import_node_events.default {
885
877
  await route.continue();
886
878
  return true;
887
879
  } catch (err) {
888
- (0, import_utils2.logerr)(err);
880
+ logerr(err);
889
881
  return false;
890
882
  }
891
883
  });
@@ -903,7 +895,7 @@ var PlaywrightPage = class extends import_node_events.default {
903
895
  return;
904
896
  }
905
897
  for (const option of this.#responseInterceptionOptions) {
906
- const { requestMatch, responseMatch, cacheArray, handler, handlerOptions } = option;
898
+ const { requestMatch, responseMatch, responseItems, handler, handlerOptions } = option;
907
899
  let matchedFlag = !requestMatch || this.#checkRequestMatch(request, requestMatch);
908
900
  if (matchedFlag && responseMatch) {
909
901
  const { minLength, maxLength } = responseMatch;
@@ -916,20 +908,20 @@ var PlaywrightPage = class extends import_node_events.default {
916
908
  if (!matchedFlag) {
917
909
  continue;
918
910
  }
919
- if (Array.isArray(cacheArray)) {
911
+ if (Array.isArray(responseItems)) {
920
912
  const requestMethod = request.method();
921
913
  const requestUrl = request.url();
922
914
  const reqData2 = request.postData();
923
915
  const requestData = reqData2 ? reqData2 : "";
924
916
  const responseData = await response.text();
925
- cacheArray.push({
917
+ responseItems.push({
926
918
  pageUrl,
927
919
  requestMethod,
928
920
  requestUrl,
929
921
  requestData,
930
922
  responseData
931
923
  });
932
- (0, import_utils2.loginfo)(`##browser cache matched response: ${requestUrl}`);
924
+ loginfo(`##browser cache matched response: ${requestUrl}`);
933
925
  }
934
926
  if (typeof handler === "function") {
935
927
  await handler(response, handlerOptions);
@@ -937,7 +929,7 @@ var PlaywrightPage = class extends import_node_events.default {
937
929
  }
938
930
  return;
939
931
  } catch (err) {
940
- (0, import_utils2.logerr)(err);
932
+ logerr(err);
941
933
  return;
942
934
  }
943
935
  }
@@ -952,7 +944,7 @@ var PlaywrightPage = class extends import_node_events.default {
952
944
  }
953
945
  const firstResponseInterception = this.#responseInterceptionOptions.length <= 0;
954
946
  for (const option of actOptions) {
955
- if (option?.cacheArray || option?.handler) {
947
+ if (option?.responseItems || option?.handler) {
956
948
  this.#responseInterceptionOptions.push(option);
957
949
  } else {
958
950
  throw new Error(`Invalid ResponseInterceptionOption`);
@@ -1009,6 +1001,30 @@ var PlaywrightPage = class extends import_node_events.default {
1009
1001
  this.#status = "busy";
1010
1002
  return true;
1011
1003
  }
1004
+ async waitForElement(selector, options = {}) {
1005
+ if (!this.#page) {
1006
+ throw new Error("No valid page");
1007
+ }
1008
+ const locator = this.#page.locator(selector);
1009
+ const { timeout = 3e4, state = "visible" } = options;
1010
+ await locator.waitFor({ state, timeout });
1011
+ return true;
1012
+ }
1013
+ async waitForNavigation(options) {
1014
+ if (!this.#page) {
1015
+ throw new Error("No valid page");
1016
+ }
1017
+ const { url = "", timeout = 3e4, waitUntil = "load" } = options;
1018
+ const newWaitUntil = this.#getWaitUntil(waitUntil);
1019
+ if (url) {
1020
+ await this.#page.waitForURL(url, { timeout, waitUntil: newWaitUntil });
1021
+ } else if (newWaitUntil === "commit") {
1022
+ throw new Error("commit is not supported in PlaywrightPage.waitForNavigation");
1023
+ } else {
1024
+ await this.#page.waitForLoadState(newWaitUntil, { timeout });
1025
+ }
1026
+ return true;
1027
+ }
1012
1028
  async windowMember(keys) {
1013
1029
  if (!this.#page) {
1014
1030
  throw new Error("No valid page");
@@ -1037,7 +1053,7 @@ var PlaywrightPage = class extends import_node_events.default {
1037
1053
  };
1038
1054
 
1039
1055
  // src/playwright/context.ts
1040
- var PlaywrightBrowserContext = class extends import_node_events2.default {
1056
+ var PlaywrightBrowserContext = class extends EventEmitter2 {
1041
1057
  #lsdBrowser;
1042
1058
  #browserIdx;
1043
1059
  #browserContextIdx;
@@ -1056,12 +1072,12 @@ var PlaywrightBrowserContext = class extends import_node_events2.default {
1056
1072
  }
1057
1073
  const pages = this.#browserContext.pages();
1058
1074
  const openType = this.#lsdBrowser.browserCreationMethod();
1059
- const lastStatusUpdateTime = (0, import_utils3.getCurrentUnixTime)();
1075
+ const lastStatusUpdateTime = getCurrentUnixTime2();
1060
1076
  for (const page of pages) {
1061
1077
  const pageInfo = { browserIdx: this.#browserIdx, browserContextIdx: this.#browserContextIdx, pageIdx: this.#nextPageIdx++, openType, openTime: this.#createTime, lastStatusUpdateTime, taskId: 0 };
1062
1078
  const lsdPage = new PlaywrightPage(this, page, pageInfo);
1063
1079
  this.#lsdPages.push(lsdPage);
1064
- (0, import_utils3.loginfo)(`##browser ${lsdPage.id()} ${openType}ed`);
1080
+ loginfo2(`##browser ${lsdPage.id()} ${openType}ed`);
1065
1081
  }
1066
1082
  }
1067
1083
  constructor(lsdBrowser, browserContext, incognito = false, proxy = null, browserIdx = 0, browserContextIdx = 0, maxPagesPerBrowserContext = 20, maxPageFreeSeconds = 0) {
@@ -1076,7 +1092,7 @@ var PlaywrightBrowserContext = class extends import_node_events2.default {
1076
1092
  this.#browserIdx = browserIdx;
1077
1093
  this.#browserContextIdx = browserContextIdx;
1078
1094
  this.#browserContext = browserContext;
1079
- this.#createTime = (0, import_utils3.getCurrentUnixTime)();
1095
+ this.#createTime = getCurrentUnixTime2();
1080
1096
  this.#incognito = incognito === false ? false : true;
1081
1097
  this.#proxy = proxy?.server ? proxy : null;
1082
1098
  this.#maxPagesPerBrowserContext = maxPagesPerBrowserContext;
@@ -1089,29 +1105,29 @@ var PlaywrightBrowserContext = class extends import_node_events2.default {
1089
1105
  const pageInfo = page.pageInfo;
1090
1106
  if (pageInfo) {
1091
1107
  const { browserIdx: browserIdx2, browserContextIdx: browserContextIdx2, pageIdx } = pageInfo;
1092
- (0, import_utils3.logwarn)(`##browser page-${browserIdx2}-${browserContextIdx2}-${pageIdx} has been already created`);
1108
+ logwarn2(`##browser page-${browserIdx2}-${browserContextIdx2}-${pageIdx} has been already created`);
1093
1109
  } else {
1094
- const currentTime = (0, import_utils3.getCurrentUnixTime)();
1110
+ const currentTime = getCurrentUnixTime2();
1095
1111
  const pageInfo2 = { browserIdx: this.#browserIdx, browserContextIdx: this.#browserContextIdx, pageIdx: this.#nextPageIdx++, openType: "other", openTime: currentTime, lastStatusUpdateTime: currentTime, taskId: 0 };
1096
1112
  const lsdPage = new PlaywrightPage(this, page, pageInfo2);
1097
1113
  this.#lsdPages.push(lsdPage);
1098
- (0, import_utils3.loginfo)(`##browser ${lsdPage.id()} created`);
1114
+ loginfo2(`##browser ${lsdPage.id()} created`);
1099
1115
  }
1100
1116
  });
1101
1117
  browserContext.on("close", (bc) => {
1102
1118
  if (browserContext !== bc) {
1103
- (0, import_utils3.logerr)(`##browser different browserContext in browserContext.on("close")`);
1119
+ logerr2(`##browser different browserContext in browserContext.on("close")`);
1104
1120
  }
1105
1121
  this.#lsdBrowser.emit("browserContextClose", this);
1106
1122
  });
1107
1123
  this.on("pageClose", (lsdPage) => {
1108
1124
  if (!(lsdPage instanceof PlaywrightPage)) {
1109
- (0, import_utils3.logerr)(`Invalid data in LsdBrowserContext.on("pageClose)`);
1125
+ logerr2(`Invalid data in LsdBrowserContext.on("pageClose)`);
1110
1126
  return;
1111
1127
  }
1112
1128
  const idx = this.#lsdPages.findIndex((p) => p === lsdPage);
1113
1129
  if (idx < 0) {
1114
- (0, import_utils3.logerr)(`Invalid lsdPage in LsdBrowserContext.on("pageClose)`);
1130
+ logerr2(`Invalid lsdPage in LsdBrowserContext.on("pageClose)`);
1115
1131
  return;
1116
1132
  }
1117
1133
  this.#lsdPages.splice(idx, 1);
@@ -1134,15 +1150,15 @@ var PlaywrightBrowserContext = class extends import_node_events2.default {
1134
1150
  this.#gettingPage = true;
1135
1151
  return true;
1136
1152
  } else {
1137
- await (0, import_utils3.sleep)(200);
1153
+ await sleep(200);
1138
1154
  }
1139
1155
  }
1140
- (0, import_utils3.logwarn)(`Cannot get the gettingLock.`);
1156
+ logwarn2(`Cannot get the gettingLock.`);
1141
1157
  return false;
1142
1158
  }
1143
1159
  #freeGettingLock() {
1144
1160
  if (!this.#gettingPage) {
1145
- (0, import_utils3.logwarn)(`Getting lock is already free now.`);
1161
+ logwarn2(`Getting lock is already free now.`);
1146
1162
  }
1147
1163
  this.#gettingPage = false;
1148
1164
  }
@@ -1151,7 +1167,7 @@ var PlaywrightBrowserContext = class extends import_node_events2.default {
1151
1167
  maxPageFreeSeconds = this.#maxPageFreeSeconds;
1152
1168
  }
1153
1169
  if (maxPageFreeSeconds <= 0) {
1154
- (0, import_utils3.logwarn)(`Please set valid maxPageFreeSeconds to close free pages`);
1170
+ logwarn2(`Please set valid maxPageFreeSeconds to close free pages`);
1155
1171
  return false;
1156
1172
  }
1157
1173
  const gotLock = await this.#tryToGetGettingLock();
@@ -1159,7 +1175,7 @@ var PlaywrightBrowserContext = class extends import_node_events2.default {
1159
1175
  return false;
1160
1176
  }
1161
1177
  try {
1162
- const maxUpdateTime = (0, import_utils3.getCurrentUnixTime)() - this.#maxPageFreeSeconds;
1178
+ const maxUpdateTime = getCurrentUnixTime2() - this.#maxPageFreeSeconds;
1163
1179
  let freePages = this.#lsdPages.filter((p) => p.isFree() && p.pageInfo().lastStatusUpdateTime < maxUpdateTime);
1164
1180
  if (freePages.length === this.#lsdPages.length) {
1165
1181
  freePages = freePages.slice(1);
@@ -1170,7 +1186,7 @@ var PlaywrightBrowserContext = class extends import_node_events2.default {
1170
1186
  this.#freeGettingLock();
1171
1187
  return true;
1172
1188
  } catch (err) {
1173
- (0, import_utils3.logerr)(err);
1189
+ logerr2(err);
1174
1190
  this.#freeGettingLock();
1175
1191
  return false;
1176
1192
  }
@@ -1211,7 +1227,7 @@ var PlaywrightBrowserContext = class extends import_node_events2.default {
1211
1227
  return null;
1212
1228
  }
1213
1229
  } catch (err) {
1214
- (0, import_utils3.logerr)(err);
1230
+ logerr2(err);
1215
1231
  this.#freeGettingLock();
1216
1232
  return null;
1217
1233
  }
@@ -1274,8 +1290,8 @@ var PlaywrightBrowserContext = class extends import_node_events2.default {
1274
1290
  };
1275
1291
 
1276
1292
  // src/playwright/browser.ts
1277
- var import_utils4 = require("@letsscrapedata/utils");
1278
- var PlaywrightBrowser = class extends import_node_events3.default {
1293
+ import { logerr as logerr3, loginfo as loginfo3, logwarn as logwarn3 } from "@letsscrapedata/utils";
1294
+ var PlaywrightBrowser = class extends EventEmitter3 {
1279
1295
  #browser;
1280
1296
  #browserIdx;
1281
1297
  #lsdBrowserContexts;
@@ -1320,38 +1336,38 @@ var PlaywrightBrowser = class extends import_node_events3.default {
1320
1336
  this.#executablePath = executablePath;
1321
1337
  this.#nextBrowserContextIdx = 1;
1322
1338
  this.#closeFreePagesIntervalId = null;
1323
- (0, import_utils4.loginfo)(`##browser ${this.#browserType} ${this.id()} ${this.#browserCreationMethod}ed by ${this.#browserControllerType}`);
1339
+ loginfo3(`##browser ${this.#browserType} ${this.id()} ${this.#browserCreationMethod}ed by ${this.#browserControllerType}`);
1324
1340
  const browserContexts = browser.contexts();
1325
1341
  if (browserContexts.length > 0) {
1326
- (0, import_utils4.logwarn)(`There are ${browserContexts.length} new browserContexts when playwright launches new browser`);
1342
+ logwarn3(`There are ${browserContexts.length} new browserContexts when playwright launches new browser`);
1327
1343
  }
1328
1344
  const incognito = typeof options?.incognito === "boolean" ? options.incognito : true;
1329
1345
  for (const browserContext of browserContexts) {
1330
1346
  const lsdBrowserContext = new PlaywrightBrowserContext(this, browserContext, incognito, this.#proxy, this.#browserIdx++, this.#nextBrowserContextIdx++, this.#maxPagesPerBrowserContext(), this.#maxPageFreeSeconds());
1331
1347
  this.#lsdBrowserContexts.push(lsdBrowserContext);
1332
- (0, import_utils4.loginfo)(`##browser ${lsdBrowserContext.id()} ${this.#browserCreationMethod}ed`);
1348
+ loginfo3(`##browser ${lsdBrowserContext.id()} ${this.#browserCreationMethod}ed`);
1333
1349
  }
1334
1350
  browser.on("disconnected", () => {
1335
- (0, import_utils4.loginfo)(`##browser ${this.id()} disconnected`);
1351
+ loginfo3(`##browser ${this.id()} disconnected`);
1336
1352
  if (this.#lsdBrowserContexts.length > 0) {
1337
- (0, import_utils4.logerr)(`${this.id()} has browserContexts when disconnected`);
1353
+ logerr3(`${this.id()} has browserContexts when disconnected`);
1338
1354
  }
1339
1355
  });
1340
1356
  this.on("browserContextClose", (lsdBrowserContext) => {
1341
1357
  if (!(lsdBrowserContext instanceof PlaywrightBrowserContext)) {
1342
- (0, import_utils4.logerr)(`Invalid data in LsdBrowser.on("browserContextClose)`);
1358
+ logerr3(`Invalid data in LsdBrowser.on("browserContextClose)`);
1343
1359
  return;
1344
1360
  }
1345
1361
  const idx = this.#lsdBrowserContexts.findIndex((bc) => bc === lsdBrowserContext);
1346
1362
  if (idx < 0) {
1347
- (0, import_utils4.logerr)(`Invalid lsdBrowserContext in LsdBrowser.on("browserContextClose)`);
1363
+ logerr3(`Invalid lsdBrowserContext in LsdBrowser.on("browserContextClose)`);
1348
1364
  return;
1349
1365
  }
1350
- (0, import_utils4.loginfo)(`##browser ${lsdBrowserContext.id()} closed
1366
+ loginfo3(`##browser ${lsdBrowserContext.id()} closed
1351
1367
  `);
1352
1368
  this.#lsdBrowserContexts.splice(idx, 1);
1353
1369
  if (this.#lsdBrowserContexts.length === 0) {
1354
- (0, import_utils4.loginfo)(`##browser ${this.id()} has no browserContexts now`);
1370
+ loginfo3(`##browser ${this.id()} has no browserContexts now`);
1355
1371
  }
1356
1372
  return;
1357
1373
  });
@@ -1369,7 +1385,7 @@ var PlaywrightBrowser = class extends import_node_events3.default {
1369
1385
  // 常用方法(按常见调用顺序排序)
1370
1386
  async newBrowserContext(options) {
1371
1387
  if (this.#lsdBrowserContexts.length >= this.#maxBrowserContextsPerBrowser()) {
1372
- (0, import_utils4.logwarn)(`##browser ${this.id()} can not create more new browserContext`);
1388
+ logwarn3(`##browser ${this.id()} can not create more new browserContext`);
1373
1389
  return null;
1374
1390
  }
1375
1391
  const browserContextOptions = {};
@@ -1384,7 +1400,7 @@ var PlaywrightBrowser = class extends import_node_events3.default {
1384
1400
  const browserContext = await this.#browser.newContext(browserContextOptions);
1385
1401
  const lsdBrowserContext = new PlaywrightBrowserContext(this, browserContext, true, proxy, this.#browserIdx++, this.#nextBrowserContextIdx++, this.#maxPagesPerBrowserContext(), this.#maxPageFreeSeconds());
1386
1402
  this.#lsdBrowserContexts.push(lsdBrowserContext);
1387
- (0, import_utils4.loginfo)(`##browser ${lsdBrowserContext.id()} created`);
1403
+ loginfo3(`##browser ${lsdBrowserContext.id()} created`);
1388
1404
  return lsdBrowserContext;
1389
1405
  }
1390
1406
  async close() {
@@ -1435,16 +1451,16 @@ var PlaywrightBrowser = class extends import_node_events3.default {
1435
1451
  };
1436
1452
 
1437
1453
  // src/puppeteer/browser.ts
1438
- var import_node_events6 = __toESM(require("events"));
1454
+ import EventEmitter6 from "events";
1439
1455
 
1440
1456
  // src/puppeteer/context.ts
1441
- var import_node_events5 = __toESM(require("events"));
1457
+ import EventEmitter5 from "events";
1442
1458
 
1443
1459
  // src/puppeteer/page.ts
1444
- var import_node_events4 = __toESM(require("events"));
1460
+ import EventEmitter4 from "events";
1445
1461
 
1446
1462
  // src/puppeteer/element.ts
1447
- var import_utils5 = require("@letsscrapedata/utils");
1463
+ import { logerr as logerr4, unreachable as unreachable3 } from "@letsscrapedata/utils";
1448
1464
  var PuppeteerElement = class _PuppeteerElement {
1449
1465
  #frame;
1450
1466
  #$ele;
@@ -1532,7 +1548,7 @@ var PuppeteerElement = class _PuppeteerElement {
1532
1548
  }
1533
1549
  return retObj;
1534
1550
  } catch (err) {
1535
- (0, import_utils5.logerr)(err);
1551
+ logerr4(err);
1536
1552
  return retObj;
1537
1553
  }
1538
1554
  }
@@ -1682,44 +1698,24 @@ var PuppeteerElement = class _PuppeteerElement {
1682
1698
  }
1683
1699
  break;
1684
1700
  default:
1685
- (0, import_utils5.unreachable)(type);
1701
+ unreachable3(type);
1686
1702
  }
1687
1703
  return true;
1688
1704
  }
1689
1705
  async screenshot(options) {
1690
1706
  return await this.#$ele.screenshot(options);
1691
1707
  }
1692
- async scrollBy(x, y) {
1693
- await this.#frame.evaluate(
1694
- (x2, y2) => {
1695
- window.scrollBy(x2, y2);
1696
- },
1697
- x,
1698
- y
1699
- );
1700
- return true;
1701
- }
1702
1708
  async scrollIntoView() {
1703
1709
  await this.#frame.evaluate((ele) => {
1704
1710
  ele.scrollIntoView();
1705
1711
  }, this.#$ele);
1706
1712
  return true;
1707
1713
  }
1708
- async scrollTo(x, y) {
1709
- await this.#frame.evaluate(
1710
- (x2, y2) => {
1711
- window.scrollTo(x2, y2);
1712
- },
1713
- x,
1714
- y
1715
- );
1716
- return true;
1717
- }
1718
1714
  };
1719
1715
 
1720
1716
  // src/puppeteer/page.ts
1721
- var import_utils6 = require("@letsscrapedata/utils");
1722
- var PuppeteerPage = class extends import_node_events4.default {
1717
+ import { getCurrentUnixTime as getCurrentUnixTime3, logerr as logerr5, loginfo as loginfo4, unreachable as unreachable4 } from "@letsscrapedata/utils";
1718
+ var PuppeteerPage = class extends EventEmitter4 {
1723
1719
  #lsdBrowserContext;
1724
1720
  #page;
1725
1721
  #status;
@@ -1878,9 +1874,9 @@ var PuppeteerPage = class extends import_node_events4.default {
1878
1874
  const page = this.#page;
1879
1875
  const pageId = this.#pageId;
1880
1876
  page.on("close", async () => {
1881
- (0, import_utils6.loginfo)(`##browser ${pageId} closed`);
1877
+ loginfo4(`##browser ${pageId} closed`);
1882
1878
  if (!page.pageInfo) {
1883
- (0, import_utils6.logerr)(`Logic error in page.on("close")`);
1879
+ logerr5(`Logic error in page.on("close")`);
1884
1880
  }
1885
1881
  this.emit("pageClose");
1886
1882
  this.#lsdBrowserContext.emit("pageClose", this);
@@ -1894,12 +1890,12 @@ var PuppeteerPage = class extends import_node_events4.default {
1894
1890
  popupPageId = `page-${browserIdx}-${browserContextIdx}-${pageIdx}`;
1895
1891
  pageInfo.openType = "popup";
1896
1892
  } else {
1897
- (0, import_utils6.logerr)(`##browser ${pageId} has popup without page.pageInfo`);
1893
+ logerr5(`##browser ${pageId} has popup without page.pageInfo`);
1898
1894
  }
1899
- (0, import_utils6.loginfo)(`##browser ${pageId} has popup ${popupPageId}`);
1895
+ loginfo4(`##browser ${pageId} has popup ${popupPageId}`);
1900
1896
  this.emit("pagePopup", pageInfo);
1901
1897
  } else {
1902
- (0, import_utils6.logerr)(`##browser ${pageId} has popup page with null page`);
1898
+ logerr5(`##browser ${pageId} has popup page with null page`);
1903
1899
  }
1904
1900
  });
1905
1901
  }
@@ -1911,7 +1907,7 @@ var PuppeteerPage = class extends import_node_events4.default {
1911
1907
  this.#lsdBrowserContext = browserContext;
1912
1908
  this.#page = page;
1913
1909
  this.#status = "free";
1914
- const currentTime = (0, import_utils6.getCurrentUnixTime)();
1910
+ const currentTime = getCurrentUnixTime3();
1915
1911
  const { browserIdx = 0, browserContextIdx = 0, pageIdx = 0, openType = "other", openTime = currentTime, lastStatusUpdateTime = currentTime, taskId = 0 } = pageInfo ? pageInfo : {};
1916
1912
  this.#page.pageInfo = { browserIdx, browserContextIdx, pageIdx, openType, openTime, lastStatusUpdateTime, taskId };
1917
1913
  this.#pageId = `page${browserIdx}-${browserContextIdx}-${pageIdx}`;
@@ -2056,12 +2052,21 @@ var PuppeteerPage = class extends import_node_events4.default {
2056
2052
  await this.clearResponseInterceptions();
2057
2053
  return true;
2058
2054
  }
2055
+ #getWaitUntil(origWaitUntil) {
2056
+ if (origWaitUntil === "networkidle") {
2057
+ return "networkidle0";
2058
+ } else if (origWaitUntil === "commit") {
2059
+ throw new Error("commit is not supported in PuppeteerPage");
2060
+ } else {
2061
+ return origWaitUntil;
2062
+ }
2063
+ }
2059
2064
  async goto(url, options) {
2060
2065
  if (!this.#page) {
2061
2066
  throw new Error("No valid page");
2062
2067
  }
2063
2068
  if (options) {
2064
- const { referer, timeout, waitUntil } = options;
2069
+ const { referer, timeout, waitUntil = "load" } = options;
2065
2070
  const newOptions = {};
2066
2071
  if (referer) {
2067
2072
  newOptions.referer = referer;
@@ -2070,7 +2075,7 @@ var PuppeteerPage = class extends import_node_events4.default {
2070
2075
  newOptions.timeout = timeout;
2071
2076
  }
2072
2077
  if (waitUntil && waitUntil !== "commit") {
2073
- newOptions.waitUntil = waitUntil === "networkidle" ? "networkidle0" : waitUntil;
2078
+ newOptions.waitUntil = this.#getWaitUntil(waitUntil);
2074
2079
  }
2075
2080
  await this.#page.goto(url, newOptions);
2076
2081
  } else {
@@ -2142,6 +2147,30 @@ var PuppeteerPage = class extends import_node_events4.default {
2142
2147
  }
2143
2148
  return await this.#page.screenshot(options);
2144
2149
  }
2150
+ async scrollBy(x, y) {
2151
+ if (!this.#page) {
2152
+ throw new Error("No valid page");
2153
+ }
2154
+ await this.#page.evaluate(
2155
+ ([x2, y2]) => {
2156
+ window.scrollBy(x2, y2);
2157
+ },
2158
+ [x, y]
2159
+ );
2160
+ return true;
2161
+ }
2162
+ async scrollTo(x, y) {
2163
+ if (!this.#page) {
2164
+ throw new Error("No valid page");
2165
+ }
2166
+ await this.#page.evaluate(
2167
+ ([x2, y2]) => {
2168
+ window.scrollTo(x2, y2);
2169
+ },
2170
+ [x, y]
2171
+ );
2172
+ return true;
2173
+ }
2145
2174
  async setCookies(cookies) {
2146
2175
  if (!this.#page) {
2147
2176
  throw new Error("No valid page");
@@ -2239,7 +2268,7 @@ var PuppeteerPage = class extends import_node_events4.default {
2239
2268
  });
2240
2269
  break;
2241
2270
  default:
2242
- (0, import_utils6.unreachable)(action);
2271
+ unreachable4(action);
2243
2272
  }
2244
2273
  return true;
2245
2274
  }
@@ -2274,7 +2303,7 @@ var PuppeteerPage = class extends import_node_events4.default {
2274
2303
  return false;
2275
2304
  }
2276
2305
  for (const option of actOptions) {
2277
- const { requestMatch, responseMatch, cacheArray, handler, handlerOptions } = option;
2306
+ const { requestMatch, responseMatch, responseItems, handler, handlerOptions } = option;
2278
2307
  let matchedFlag = !requestMatch || this.#checkRequestMatch(request, requestMatch);
2279
2308
  if (matchedFlag && responseMatch) {
2280
2309
  const { minLength, maxLength } = responseMatch;
@@ -2287,13 +2316,13 @@ var PuppeteerPage = class extends import_node_events4.default {
2287
2316
  if (!matchedFlag) {
2288
2317
  continue;
2289
2318
  }
2290
- if (Array.isArray(cacheArray)) {
2319
+ if (Array.isArray(responseItems)) {
2291
2320
  const requestMethod = request.method();
2292
2321
  const requestUrl = request.url();
2293
2322
  const reqData2 = request.postData();
2294
2323
  const requestData = reqData2 ? reqData2 : "";
2295
2324
  const responseData = await response.text();
2296
- cacheArray.push({
2325
+ responseItems.push({
2297
2326
  pageUrl,
2298
2327
  requestMethod,
2299
2328
  requestUrl,
@@ -2360,6 +2389,33 @@ var PuppeteerPage = class extends import_node_events4.default {
2360
2389
  this.#status = "busy";
2361
2390
  return true;
2362
2391
  }
2392
+ async waitForElement(selector, options = {}) {
2393
+ if (!this.#page) {
2394
+ throw new Error("No valid page");
2395
+ }
2396
+ const { timeout = 3e4, state = "visible" } = options;
2397
+ if (state === "visible") {
2398
+ await this.#page.waitForSelector(selector, { timeout, visible: true });
2399
+ } else if (state === "hidden") {
2400
+ await this.#page.waitForSelector(selector, { timeout, hidden: true });
2401
+ } else {
2402
+ throw new Error(`${state} is not supported in PuppeteerPage.waitForElement`);
2403
+ }
2404
+ return true;
2405
+ }
2406
+ async waitForNavigation(options) {
2407
+ if (!this.#page) {
2408
+ throw new Error("No valid page");
2409
+ }
2410
+ const { url = "", timeout = 3e4, waitUntil = "load" } = options;
2411
+ const newWaitUntil = this.#getWaitUntil(waitUntil);
2412
+ if (url) {
2413
+ throw new Error("url is not supported in PuppeteerPage.waitForNavigation");
2414
+ } else {
2415
+ await this.#page.waitForNavigation({ timeout, waitUntil: newWaitUntil });
2416
+ }
2417
+ return true;
2418
+ }
2363
2419
  async windowMember(keys) {
2364
2420
  if (!this.#page) {
2365
2421
  throw new Error("No valid page");
@@ -2388,8 +2444,8 @@ var PuppeteerPage = class extends import_node_events4.default {
2388
2444
  };
2389
2445
 
2390
2446
  // src/puppeteer/context.ts
2391
- var import_utils7 = require("@letsscrapedata/utils");
2392
- var PuppeteerBrowserContext = class extends import_node_events5.default {
2447
+ import { getCurrentUnixTime as getCurrentUnixTime4, logerr as logerr6, loginfo as loginfo5, logwarn as logwarn4, sleep as sleep2 } from "@letsscrapedata/utils";
2448
+ var PuppeteerBrowserContext = class extends EventEmitter5 {
2393
2449
  #lsdBrowser;
2394
2450
  #browserIdx;
2395
2451
  #browserContextIdx;
@@ -2413,7 +2469,7 @@ var PuppeteerBrowserContext = class extends import_node_events5.default {
2413
2469
  }
2414
2470
  const pages = await this.#browserContext.pages();
2415
2471
  const openType = this.#lsdBrowser.browserCreationMethod();
2416
- const lastStatusUpdateTime = (0, import_utils7.getCurrentUnixTime)();
2472
+ const lastStatusUpdateTime = getCurrentUnixTime4();
2417
2473
  for (const page of pages) {
2418
2474
  const pageInfo = { browserIdx: this.#browserIdx, browserContextIdx: this.#browserContextIdx, pageIdx: this.#nextPageIdx++, openType, openTime: this.#createTime, lastStatusUpdateTime, taskId: 0 };
2419
2475
  const lsdPage = new PuppeteerPage(this, page, pageInfo);
@@ -2421,7 +2477,7 @@ var PuppeteerBrowserContext = class extends import_node_events5.default {
2421
2477
  await lsdPage.setUserAgent(this.#userAgent);
2422
2478
  }
2423
2479
  this.#lsdPages.push(lsdPage);
2424
- (0, import_utils7.loginfo)(`##browser ${lsdPage.id()} ${openType}ed`);
2480
+ loginfo5(`##browser ${lsdPage.id()} ${openType}ed`);
2425
2481
  }
2426
2482
  }
2427
2483
  constructor(lsdBrowser, browserContext, incognito = false, proxy = null, browserIdx = 0, browserContextIdx = 0, maxPagesPerBrowserContext = 20, maxPageFreeSeconds = 0, userAgent = "") {
@@ -2437,7 +2493,7 @@ var PuppeteerBrowserContext = class extends import_node_events5.default {
2437
2493
  this.#browserContextIdx = browserContextIdx;
2438
2494
  this.#browserContext = browserContext;
2439
2495
  this.#userAgent = userAgent;
2440
- this.#createTime = (0, import_utils7.getCurrentUnixTime)();
2496
+ this.#createTime = getCurrentUnixTime4();
2441
2497
  this.#incognito = incognito === false ? false : true;
2442
2498
  this.#proxy = proxy?.server ? proxy : null;
2443
2499
  this.#maxPagesPerBrowserContext = maxPagesPerBrowserContext;
@@ -2455,27 +2511,27 @@ var PuppeteerBrowserContext = class extends import_node_events5.default {
2455
2511
  const pageInfo = page.pageInfo;
2456
2512
  if (pageInfo) {
2457
2513
  const { browserIdx: browserIdx2, browserContextIdx: browserContextIdx2, pageIdx } = pageInfo;
2458
- (0, import_utils7.logwarn)(`##browser page-${browserIdx2}-${browserContextIdx2}-${pageIdx} has been already created`);
2514
+ logwarn4(`##browser page-${browserIdx2}-${browserContextIdx2}-${pageIdx} has been already created`);
2459
2515
  } else {
2460
- const currentTime = (0, import_utils7.getCurrentUnixTime)();
2516
+ const currentTime = getCurrentUnixTime4();
2461
2517
  const pageInfo2 = { browserIdx: this.#browserIdx, browserContextIdx: this.#browserContextIdx, pageIdx: this.#nextPageIdx++, openType: "other", openTime: currentTime, lastStatusUpdateTime: currentTime, taskId: 0 };
2462
2518
  const lsdPage = new PuppeteerPage(this, page, pageInfo2);
2463
2519
  if (this.#userAgent) {
2464
2520
  await lsdPage.setUserAgent(this.#userAgent);
2465
2521
  }
2466
2522
  this.#lsdPages.push(lsdPage);
2467
- (0, import_utils7.loginfo)(`##browser ${lsdPage.id()} created`);
2523
+ loginfo5(`##browser ${lsdPage.id()} created`);
2468
2524
  }
2469
2525
  }
2470
2526
  });
2471
2527
  this.on("pageClose", (lsdPage) => {
2472
2528
  if (!(lsdPage instanceof PuppeteerPage)) {
2473
- (0, import_utils7.logerr)(`Invalid data in LsdBrowserContext.on("pageClose)`);
2529
+ logerr6(`Invalid data in LsdBrowserContext.on("pageClose)`);
2474
2530
  return;
2475
2531
  }
2476
2532
  const idx = this.#lsdPages.findIndex((p) => p === lsdPage);
2477
2533
  if (idx < 0) {
2478
- (0, import_utils7.logerr)(`Invalid lsdPage in LsdBrowserContext.on("pageClose)`);
2534
+ logerr6(`Invalid lsdPage in LsdBrowserContext.on("pageClose)`);
2479
2535
  return;
2480
2536
  }
2481
2537
  this.#lsdPages.splice(idx, 1);
@@ -2501,15 +2557,15 @@ var PuppeteerBrowserContext = class extends import_node_events5.default {
2501
2557
  this.#gettingPage = true;
2502
2558
  return true;
2503
2559
  } else {
2504
- await (0, import_utils7.sleep)(200);
2560
+ await sleep2(200);
2505
2561
  }
2506
2562
  }
2507
- (0, import_utils7.logwarn)(`Cannot get the gettingLock.`);
2563
+ logwarn4(`Cannot get the gettingLock.`);
2508
2564
  return false;
2509
2565
  }
2510
2566
  #freeGettingLock() {
2511
2567
  if (!this.#gettingPage) {
2512
- (0, import_utils7.logwarn)(`Getting lock is already free now.`);
2568
+ logwarn4(`Getting lock is already free now.`);
2513
2569
  }
2514
2570
  this.#gettingPage = false;
2515
2571
  }
@@ -2518,7 +2574,7 @@ var PuppeteerBrowserContext = class extends import_node_events5.default {
2518
2574
  maxPageFreeSeconds = this.#maxPageFreeSeconds;
2519
2575
  }
2520
2576
  if (maxPageFreeSeconds <= 0) {
2521
- (0, import_utils7.logwarn)(`Please set valid maxPageFreeSeconds to close free pages`);
2577
+ logwarn4(`Please set valid maxPageFreeSeconds to close free pages`);
2522
2578
  return false;
2523
2579
  }
2524
2580
  const gotLock = await this.#tryToGetGettingLock();
@@ -2526,7 +2582,7 @@ var PuppeteerBrowserContext = class extends import_node_events5.default {
2526
2582
  return false;
2527
2583
  }
2528
2584
  try {
2529
- const maxUpdateTime = (0, import_utils7.getCurrentUnixTime)() - this.#maxPageFreeSeconds;
2585
+ const maxUpdateTime = getCurrentUnixTime4() - this.#maxPageFreeSeconds;
2530
2586
  let freePages = this.#lsdPages.filter((p) => p.isFree() && p.pageInfo().lastStatusUpdateTime < maxUpdateTime);
2531
2587
  if (freePages.length === this.#lsdPages.length) {
2532
2588
  freePages = freePages.slice(1);
@@ -2537,7 +2593,7 @@ var PuppeteerBrowserContext = class extends import_node_events5.default {
2537
2593
  this.#freeGettingLock();
2538
2594
  return true;
2539
2595
  } catch (err) {
2540
- (0, import_utils7.logerr)(err);
2596
+ logerr6(err);
2541
2597
  this.#freeGettingLock();
2542
2598
  return false;
2543
2599
  }
@@ -2552,7 +2608,7 @@ var PuppeteerBrowserContext = class extends import_node_events5.default {
2552
2608
  }
2553
2609
  try {
2554
2610
  if (this.#lsdPages.length === 0) {
2555
- await (0, import_utils7.sleep)(1e3);
2611
+ await sleep2(1e3);
2556
2612
  }
2557
2613
  let lsdPage = this.#lsdPages.find((p) => p.isFree());
2558
2614
  if (lsdPage) {
@@ -2580,7 +2636,7 @@ var PuppeteerBrowserContext = class extends import_node_events5.default {
2580
2636
  return null;
2581
2637
  }
2582
2638
  } catch (err) {
2583
- (0, import_utils7.logerr)(err);
2639
+ logerr6(err);
2584
2640
  this.#freeGettingLock();
2585
2641
  return null;
2586
2642
  }
@@ -2643,8 +2699,8 @@ var PuppeteerBrowserContext = class extends import_node_events5.default {
2643
2699
  };
2644
2700
 
2645
2701
  // src/puppeteer/browser.ts
2646
- var import_utils8 = require("@letsscrapedata/utils");
2647
- var PuppeteerBrowser = class extends import_node_events6.default {
2702
+ import { logerr as logerr7, loginfo as loginfo6, logwarn as logwarn5 } from "@letsscrapedata/utils";
2703
+ var PuppeteerBrowser = class extends EventEmitter6 {
2648
2704
  #browser;
2649
2705
  #browserIdx;
2650
2706
  #lsdBrowserContexts;
@@ -2692,35 +2748,35 @@ var PuppeteerBrowser = class extends import_node_events6.default {
2692
2748
  this.#executablePath = executablePath;
2693
2749
  this.#nextBrowserContextIdx = 1;
2694
2750
  this.#closeFreePagesIntervalId = null;
2695
- (0, import_utils8.loginfo)(`##browser ${this.#browserType} ${this.id()} ${this.#browserCreationMethod}ed by ${this.#browserControllerType}`);
2751
+ loginfo6(`##browser ${this.#browserType} ${this.id()} ${this.#browserCreationMethod}ed by ${this.#browserControllerType}`);
2696
2752
  const browserContexts = browser.browserContexts();
2697
2753
  const incognito = typeof options?.incognito === "boolean" ? options.incognito : false;
2698
2754
  for (const browserContext of browserContexts) {
2699
2755
  const lsdBrowserContext = new PuppeteerBrowserContext(this, browserContext, incognito, this.#proxy, this.#browserIdx, this.#nextBrowserContextIdx++, this.#maxPagesPerBrowserContext(), this.#maxPageFreeSeconds(), this.#userAgent());
2700
2756
  this.#lsdBrowserContexts.push(lsdBrowserContext);
2701
- (0, import_utils8.loginfo)(`##browser ${lsdBrowserContext.id()} ${this.#browserCreationMethod}ed`);
2757
+ loginfo6(`##browser ${lsdBrowserContext.id()} ${this.#browserCreationMethod}ed`);
2702
2758
  }
2703
2759
  browser.on("disconnected", () => {
2704
- (0, import_utils8.loginfo)(`##browser ${this.id()} disconnected`);
2760
+ loginfo6(`##browser ${this.id()} disconnected`);
2705
2761
  if (this.#lsdBrowserContexts.length > 0) {
2706
- (0, import_utils8.logerr)(`${this.id()} has browserContexts when disconnected`);
2762
+ logerr7(`${this.id()} has browserContexts when disconnected`);
2707
2763
  }
2708
2764
  });
2709
2765
  this.on("browserContextClose", (lsdBrowserContext) => {
2710
2766
  if (!(lsdBrowserContext instanceof PuppeteerBrowserContext)) {
2711
- (0, import_utils8.logerr)(`Invalid data in LsdBrowser.on("browserContextClose)`);
2767
+ logerr7(`Invalid data in LsdBrowser.on("browserContextClose)`);
2712
2768
  return;
2713
2769
  }
2714
2770
  const idx = this.#lsdBrowserContexts.findIndex((bc) => bc === lsdBrowserContext);
2715
2771
  if (idx < 0) {
2716
- (0, import_utils8.logerr)(`Invalid lsdBrowserContext in LsdBrowser.on("browserContextClose)`);
2772
+ logerr7(`Invalid lsdBrowserContext in LsdBrowser.on("browserContextClose)`);
2717
2773
  return;
2718
2774
  }
2719
- (0, import_utils8.loginfo)(`##browser ${lsdBrowserContext.id()} closed
2775
+ loginfo6(`##browser ${lsdBrowserContext.id()} closed
2720
2776
  `);
2721
2777
  this.#lsdBrowserContexts.splice(idx, 1);
2722
2778
  if (this.#lsdBrowserContexts.length === 0) {
2723
- (0, import_utils8.loginfo)(`##browser ${this.id()} has no browserContexts now`);
2779
+ loginfo6(`##browser ${this.id()} has no browserContexts now`);
2724
2780
  }
2725
2781
  return;
2726
2782
  });
@@ -2738,7 +2794,7 @@ var PuppeteerBrowser = class extends import_node_events6.default {
2738
2794
  // 常用方法(按常见调用顺序排序)
2739
2795
  async newBrowserContext(options) {
2740
2796
  if (this.#lsdBrowserContexts.length >= this.#maxBrowserContextsPerBrowser()) {
2741
- (0, import_utils8.logwarn)(`##browser ${this.id()} can not create more new browserContext`);
2797
+ logwarn5(`##browser ${this.id()} can not create more new browserContext`);
2742
2798
  return null;
2743
2799
  }
2744
2800
  const browserContextOptions = {};
@@ -2750,7 +2806,7 @@ var PuppeteerBrowser = class extends import_node_events6.default {
2750
2806
  const userAgent = options?.userAgent ? options.userAgent : "";
2751
2807
  const lsdBrowserContext = new PuppeteerBrowserContext(this, browserContext, true, proxy, this.#browserIdx, this.#nextBrowserContextIdx++, this.#maxPagesPerBrowserContext(), this.#maxPageFreeSeconds(), userAgent);
2752
2808
  this.#lsdBrowserContexts.push(lsdBrowserContext);
2753
- (0, import_utils8.loginfo)(`##browser ${lsdBrowserContext.id()} created`);
2809
+ loginfo6(`##browser ${lsdBrowserContext.id()} created`);
2754
2810
  return lsdBrowserContext;
2755
2811
  }
2756
2812
  async close() {
@@ -2803,7 +2859,7 @@ var PuppeteerBrowser = class extends import_node_events6.default {
2803
2859
  };
2804
2860
 
2805
2861
  // src/cheerio/page.ts
2806
- var import_node_events7 = __toESM(require("events"));
2862
+ import EventEmitter7 from "events";
2807
2863
 
2808
2864
  // ../../node_modules/cheerio/lib/esm/options.js
2809
2865
  var defaultOpts = {
@@ -16675,29 +16731,34 @@ var CheerioElement = class _CheerioElement {
16675
16731
  return Array.from(Object.keys(element.attribs));
16676
16732
  }
16677
16733
  }
16678
- #findNodes(selector) {
16734
+ #findNodes(selector, absolute) {
16679
16735
  if (selector.startsWith("./") || selector.startsWith("/")) {
16680
16736
  throw new Error("Do not support XPath in cheerio.");
16681
16737
  }
16682
16738
  if (selector === ".") {
16683
16739
  return [this.#node];
16684
16740
  }
16685
- const cheerioNode = this.#node.find(selector);
16686
- if (cheerioNode.length > 0) {
16687
- const nodes = [];
16741
+ const nodes = [];
16742
+ const cheerioNode = !absolute ? this.#node.find(selector) : this.#node._root?.find(selector);
16743
+ if (!cheerioNode) {
16744
+ return nodes;
16745
+ } else if (cheerioNode.length > 0) {
16688
16746
  const len = cheerioNode.length;
16689
16747
  for (let i = 0; i < len; i++) {
16690
16748
  nodes.push(cheerioNode.eq(i));
16691
16749
  }
16692
16750
  return nodes;
16693
16751
  } else {
16694
- return [];
16752
+ return nodes;
16695
16753
  }
16696
16754
  }
16697
- async findElement(selectorOrXpath) {
16755
+ async findElement(selectorOrXpath, iframeOptions = [], absolute = false) {
16756
+ if (!iframeOptions) {
16757
+ return null;
16758
+ }
16698
16759
  const selectors = typeof selectorOrXpath === "string" ? [selectorOrXpath] : selectorOrXpath;
16699
16760
  for (const selector of selectors) {
16700
- const nodes = this.#findNodes(selector);
16761
+ const nodes = this.#findNodes(selector, absolute);
16701
16762
  if (nodes.length > 0) {
16702
16763
  const cheerioElement = new _CheerioElement(nodes[0]);
16703
16764
  return cheerioElement;
@@ -16705,10 +16766,13 @@ var CheerioElement = class _CheerioElement {
16705
16766
  }
16706
16767
  return null;
16707
16768
  }
16708
- async findElements(selectorOrXpath) {
16769
+ async findElements(selectorOrXpath, iframeOptions = [], absolute = false) {
16770
+ if (!iframeOptions) {
16771
+ return [];
16772
+ }
16709
16773
  const selectors = typeof selectorOrXpath === "string" ? [selectorOrXpath] : selectorOrXpath;
16710
16774
  for (const selector of selectors) {
16711
- const nodes = this.#findNodes(selector);
16775
+ const nodes = this.#findNodes(selector, absolute);
16712
16776
  if (nodes.length > 0) {
16713
16777
  const cheerioElements = nodes.map((node) => new _CheerioElement(node));
16714
16778
  return cheerioElements;
@@ -16757,19 +16821,13 @@ var CheerioElement = class _CheerioElement {
16757
16821
  async screenshot() {
16758
16822
  throw new Error("Not supported in CheerioElement.");
16759
16823
  }
16760
- async scrollBy() {
16761
- throw new Error("Not supported in CheerioElement.");
16762
- }
16763
16824
  async scrollIntoView() {
16764
16825
  throw new Error("Not supported in CheerioElement.");
16765
16826
  }
16766
- async scrollTo() {
16767
- throw new Error("Not supported in CheerioElement.");
16768
- }
16769
16827
  };
16770
16828
 
16771
16829
  // src/cheerio/page.ts
16772
- var CheerioPage = class extends import_node_events7.default {
16830
+ var CheerioPage = class extends EventEmitter7 {
16773
16831
  #document;
16774
16832
  constructor(html3 = "") {
16775
16833
  super();
@@ -16886,6 +16944,12 @@ var CheerioPage = class extends import_node_events7.default {
16886
16944
  async screenshot() {
16887
16945
  throw new Error("Not supported in CheerioPage.");
16888
16946
  }
16947
+ async scrollBy() {
16948
+ throw new Error("Not supported in CheerioElement.");
16949
+ }
16950
+ async scrollTo() {
16951
+ throw new Error("Not supported in CheerioElement.");
16952
+ }
16889
16953
  async setCookies() {
16890
16954
  throw new Error("Not supported in CheerioPage.");
16891
16955
  }
@@ -16928,16 +16992,22 @@ var CheerioPage = class extends import_node_events7.default {
16928
16992
  use() {
16929
16993
  throw new Error("Not supported in CheerioPage.");
16930
16994
  }
16995
+ waitForElement() {
16996
+ throw new Error("Not supported in CheerioPage.");
16997
+ }
16998
+ waitForNavigation() {
16999
+ throw new Error("Not supported in CheerioPage.");
17000
+ }
16931
17001
  async windowMember() {
16932
17002
  throw new Error("Not supported in CheerioPage.");
16933
17003
  }
16934
17004
  };
16935
17005
 
16936
17006
  // src/controller/controller.ts
16937
- var import_os = __toESM(require("os"));
16938
- var import_puppeteer = __toESM(require("puppeteer"));
16939
- var import_playwright = __toESM(require("playwright"));
16940
- var import_utils15 = require("@letsscrapedata/utils");
17007
+ import os from "os";
17008
+ import puppeteer from "puppeteer";
17009
+ import playwright from "playwright";
17010
+ import { logwarn as logwarn6 } from "@letsscrapedata/utils";
16941
17011
  var LsdBrowserController = class _LsdBrowserController {
16942
17012
  static #forbidConstructor = false;
16943
17013
  #nextBrowserIdx;
@@ -16949,19 +17019,19 @@ var LsdBrowserController = class _LsdBrowserController {
16949
17019
  if (_LsdBrowserController.#forbidConstructor) {
16950
17020
  throw new Error("Only one LsdBrowserController instance can be created!");
16951
17021
  }
16952
- this.#osPlatform = import_os.default.platform();
17022
+ this.#osPlatform = os.platform();
16953
17023
  this.#nextBrowserIdx = 1;
16954
17024
  _LsdBrowserController.#forbidConstructor = true;
16955
17025
  }
16956
17026
  #playwrightBrowserType(browserType, connectFlag = false) {
16957
17027
  if (browserType === "chromium") {
16958
- return import_playwright.default.chromium;
17028
+ return playwright.chromium;
16959
17029
  } else if (connectFlag) {
16960
17030
  throw new Error(`playwright only can connect to chromium browser, not support ${browserType} browser`);
16961
17031
  } else if (browserType === "firefox") {
16962
- return import_playwright.default.firefox;
17032
+ return playwright.firefox;
16963
17033
  } else if (browserType === "webkit") {
16964
- return import_playwright.default.webkit;
17034
+ return playwright.webkit;
16965
17035
  } else {
16966
17036
  throw new Error(`Invalid playwright browserType ${browserType}`);
16967
17037
  }
@@ -16993,17 +17063,17 @@ var LsdBrowserController = class _LsdBrowserController {
16993
17063
  const actOptions = { closeFreePagesIntervalSeconds, maxBrowserContextsPerBrowser, maxPagesPerBrowserContext, maxPageFreeSeconds, timeout, args, executablePath, headless, incognito, proxy, proxyPerBrowserContext, userDataDir, userAgent };
16994
17064
  let idx = args.findIndex((arg) => arg.toLowerCase().startsWith("--incoginto"));
16995
17065
  if (idx >= 0) {
16996
- (0, import_utils15.logwarn)(`Please use options.incognito instead when launching new browser.`);
17066
+ logwarn6(`Please use options.incognito instead when launching new browser.`);
16997
17067
  args.splice(idx, 1);
16998
17068
  }
16999
17069
  idx = args.findIndex((arg) => arg.toLowerCase().startsWith("--proxy-server"));
17000
17070
  if (idx >= 0) {
17001
- (0, import_utils15.logwarn)(`Please use options.proxy instead when launching new browser.`);
17071
+ logwarn6(`Please use options.proxy instead when launching new browser.`);
17002
17072
  args.splice(idx, 1);
17003
17073
  }
17004
17074
  idx = args.findIndex((arg) => arg.toLowerCase().startsWith("--user-data-dir"));
17005
17075
  if (idx >= 0) {
17006
- (0, import_utils15.logwarn)(`Please use options.userDataDir instead when launching new browser.`);
17076
+ logwarn6(`Please use options.userDataDir instead when launching new browser.`);
17007
17077
  args.splice(idx, 1);
17008
17078
  }
17009
17079
  if (browserControllerType === "playwright") {
@@ -17055,9 +17125,9 @@ var LsdBrowserController = class _LsdBrowserController {
17055
17125
  launchOptions.args = args;
17056
17126
  }
17057
17127
  if (!actOptions.executablePath) {
17058
- actOptions.executablePath = import_puppeteer.default.executablePath();
17128
+ actOptions.executablePath = puppeteer.executablePath();
17059
17129
  }
17060
- const browser = await import_puppeteer.default.launch(launchOptions);
17130
+ const browser = await puppeteer.launch(launchOptions);
17061
17131
  const lsdBrowser = new PuppeteerBrowser(browser, browserType, "launch", actOptions, this.#nextBrowserIdx++);
17062
17132
  return lsdBrowser;
17063
17133
  } else {
@@ -17076,7 +17146,7 @@ var LsdBrowserController = class _LsdBrowserController {
17076
17146
  return lsdBrowser;
17077
17147
  } else if (browserControllerType === "puppeteer") {
17078
17148
  this.#puppeteerProduct(browserType);
17079
- const browser = await import_puppeteer.default.connect({ browserURL: browserUrl });
17149
+ const browser = await puppeteer.connect({ browserURL: browserUrl });
17080
17150
  const lsdBrowser = new PuppeteerBrowser(browser, browserType, "connect", options, this.#nextBrowserIdx++);
17081
17151
  ;
17082
17152
  return lsdBrowser;
@@ -17086,8 +17156,7 @@ var LsdBrowserController = class _LsdBrowserController {
17086
17156
  }
17087
17157
  };
17088
17158
  var controller = new LsdBrowserController();
17089
- // Annotate the CommonJS export names for ESM import in node:
17090
- 0 && (module.exports = {
17159
+ export {
17091
17160
  CheerioElement,
17092
17161
  CheerioPage,
17093
17162
  PlaywrightBrowser,
@@ -17099,4 +17168,4 @@ var controller = new LsdBrowserController();
17099
17168
  PuppeteerElement,
17100
17169
  PuppeteerPage,
17101
17170
  defaultProxy
17102
- });
17171
+ };