@the-convocation/twitter-scraper 0.14.0 → 0.15.0

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.
@@ -27,6 +27,23 @@ class ApiError extends Error {
27
27
  }
28
28
  }
29
29
 
30
+ class WaitingRateLimitStrategy {
31
+ async onRateLimit({ response: res }) {
32
+ const xRateLimitRemaining = res.headers.get("x-rate-limit-remaining");
33
+ const xRateLimitReset = res.headers.get("x-rate-limit-reset");
34
+ if (xRateLimitRemaining == "0" && xRateLimitReset) {
35
+ const currentTime = (/* @__PURE__ */ new Date()).valueOf() / 1e3;
36
+ const timeDeltaMs = 1e3 * (parseInt(xRateLimitReset) - currentTime);
37
+ await new Promise((resolve) => setTimeout(resolve, timeDeltaMs));
38
+ }
39
+ }
40
+ }
41
+ class ErrorRateLimitStrategy {
42
+ onRateLimit({ response: res }) {
43
+ throw ApiError.fromResponse(res);
44
+ }
45
+ }
46
+
30
47
  const genericPlatform = new class {
31
48
  randomizeCiphers() {
32
49
  return Promise.resolve();
@@ -71,12 +88,16 @@ async function requestApi(url, auth, method = "GET", platform = new Platform())
71
88
  await platform.randomizeCiphers();
72
89
  let res;
73
90
  do {
74
- try {
75
- res = await auth.fetch(url, {
91
+ const fetchParameters = [
92
+ url,
93
+ {
76
94
  method,
77
95
  headers,
78
96
  credentials: "include"
79
- });
97
+ }
98
+ ];
99
+ try {
100
+ res = await auth.fetch(...fetchParameters);
80
101
  } catch (err) {
81
102
  if (!(err instanceof Error)) {
82
103
  throw err;
@@ -88,13 +109,10 @@ async function requestApi(url, auth, method = "GET", platform = new Platform())
88
109
  }
89
110
  await updateCookieJar(auth.cookieJar(), res.headers);
90
111
  if (res.status === 429) {
91
- const xRateLimitRemaining = res.headers.get("x-rate-limit-remaining");
92
- const xRateLimitReset = res.headers.get("x-rate-limit-reset");
93
- if (xRateLimitRemaining == "0" && xRateLimitReset) {
94
- const currentTime = (/* @__PURE__ */ new Date()).valueOf() / 1e3;
95
- const timeDeltaMs = 1e3 * (parseInt(xRateLimitReset) - currentTime);
96
- await new Promise((resolve) => setTimeout(resolve, timeDeltaMs));
97
- }
112
+ await auth.onRateLimit({
113
+ fetchParameters,
114
+ response: res
115
+ });
98
116
  }
99
117
  } while (res.status === 429);
100
118
  if (!res.ok) {
@@ -195,9 +213,13 @@ class TwitterGuestAuth {
195
213
  constructor(bearerToken, options) {
196
214
  this.options = options;
197
215
  this.fetch = withTransform(options?.fetch ?? fetch, options?.transform);
216
+ this.rateLimitStrategy = options?.rateLimitStrategy ?? new WaitingRateLimitStrategy();
198
217
  this.bearerToken = bearerToken;
199
218
  this.jar = new CookieJar();
200
219
  }
220
+ async onRateLimit(event) {
221
+ await this.rateLimitStrategy.onRateLimit(event);
222
+ }
201
223
  cookieJar() {
202
224
  return this.jar;
203
225
  }
@@ -2089,7 +2111,8 @@ class Scraper {
2089
2111
  getAuthOptions() {
2090
2112
  return {
2091
2113
  fetch: this.options?.fetch,
2092
- transform: this.options?.transform
2114
+ transform: this.options?.transform,
2115
+ rateLimitStrategy: this.options?.rateLimitStrategy
2093
2116
  };
2094
2117
  }
2095
2118
  handleResponse(res) {
@@ -2100,5 +2123,5 @@ class Scraper {
2100
2123
  }
2101
2124
  }
2102
2125
 
2103
- export { Scraper, SearchMode };
2126
+ export { ApiError, ErrorRateLimitStrategy, Scraper, SearchMode, WaitingRateLimitStrategy };
2104
2127
  //# sourceMappingURL=index.mjs.map