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