scrapebadger 0.3.0 → 0.3.1

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.
@@ -10,12 +10,26 @@ function createPaginatedResponse(data, cursor) {
10
10
  hasMore: !!cursor
11
11
  };
12
12
  }
13
+ var RATE_LIMIT_WARN_THRESHOLD = 0.2;
13
14
  async function* paginate(fetchPage, options = {}) {
14
15
  const { maxItems } = options;
15
16
  let cursor;
16
17
  let totalYielded = 0;
17
18
  do {
18
- const response = await fetchPage(cursor);
19
+ const { response, rateLimit } = await fetchPage(cursor);
20
+ if (rateLimit) {
21
+ const { limit, remaining, reset } = rateLimit;
22
+ if (limit > 0 && remaining / limit < RATE_LIMIT_WARN_THRESHOLD) {
23
+ const nowSec = Date.now() / 1e3;
24
+ const windowRemainingSec = Math.max(reset - nowSec, 1);
25
+ const delayMs = remaining > 0 ? windowRemainingSec / remaining * 1e3 : windowRemainingSec * 1e3;
26
+ const resetInSec = Math.round(windowRemainingSec);
27
+ console.warn(
28
+ `\x1B[33m\u26A0 ScrapeBadger: Rate limit: ${remaining}/${limit} remaining (resets in ${resetInSec}s), throttling pagination\x1B[0m`
29
+ );
30
+ await sleep(delayMs);
31
+ }
32
+ }
19
33
  for (const item of response.data) {
20
34
  yield item;
21
35
  totalYielded++;
@@ -26,6 +40,9 @@ async function* paginate(fetchPage, options = {}) {
26
40
  cursor = response.nextCursor;
27
41
  } while (cursor);
28
42
  }
43
+ function sleep(ms) {
44
+ return new Promise((resolve) => setTimeout(resolve, ms));
45
+ }
29
46
 
30
47
  // src/twitter/tweets.ts
31
48
  var TweetsClient = class {
@@ -223,7 +240,8 @@ var TweetsClient = class {
223
240
  */
224
241
  async *getQuotesAll(tweetId, options = {}) {
225
242
  const fetchPage = async (cursor) => {
226
- return this.getQuotes(tweetId, { ...options, cursor });
243
+ const { data, rateLimit } = await this.client.requestWithHeaders(`/v1/twitter/tweets/tweet/${tweetId}/quotes`, { params: { cursor } });
244
+ return { response: createPaginatedResponse(data.data ?? [], data.next_cursor), rateLimit };
227
245
  };
228
246
  yield* paginate(fetchPage, options);
229
247
  }
@@ -290,7 +308,15 @@ var TweetsClient = class {
290
308
  */
291
309
  async *searchAll(query, options = {}) {
292
310
  const fetchPage = async (cursor) => {
293
- return this.search(query, { ...options, cursor });
311
+ const { data, rateLimit } = await this.client.requestWithHeaders("/v1/twitter/tweets/advanced_search", {
312
+ params: {
313
+ query,
314
+ query_type: options.queryType ?? "Top",
315
+ count: options.count,
316
+ cursor
317
+ }
318
+ });
319
+ return { response: createPaginatedResponse(data.data ?? [], data.next_cursor), rateLimit };
294
320
  };
295
321
  yield* paginate(fetchPage, options);
296
322
  }
@@ -334,7 +360,8 @@ var TweetsClient = class {
334
360
  */
335
361
  async *getUserTweetsAll(username, options = {}) {
336
362
  const fetchPage = async (cursor) => {
337
- return this.getUserTweets(username, { ...options, cursor });
363
+ const { data, rateLimit } = await this.client.requestWithHeaders(`/v1/twitter/users/${username}/latest_tweets`, { params: { cursor } });
364
+ return { response: createPaginatedResponse(data.data ?? [], data.next_cursor), rateLimit };
338
365
  };
339
366
  yield* paginate(fetchPage, options);
340
367
  }
@@ -444,7 +471,8 @@ var UsersClient = class {
444
471
  */
445
472
  async *getFollowersAll(username, options = {}) {
446
473
  const fetchPage = async (cursor) => {
447
- return this.getFollowers(username, { ...options, cursor });
474
+ const { data, rateLimit } = await this.client.requestWithHeaders(`/v1/twitter/users/${username}/followers`, { params: { cursor } });
475
+ return { response: createPaginatedResponse(data.data ?? [], data.next_cursor), rateLimit };
448
476
  };
449
477
  yield* paginate(fetchPage, options);
450
478
  }
@@ -479,7 +507,8 @@ var UsersClient = class {
479
507
  */
480
508
  async *getFollowingAll(username, options = {}) {
481
509
  const fetchPage = async (cursor) => {
482
- return this.getFollowing(username, { ...options, cursor });
510
+ const { data, rateLimit } = await this.client.requestWithHeaders(`/v1/twitter/users/${username}/followings`, { params: { cursor } });
511
+ return { response: createPaginatedResponse(data.data ?? [], data.next_cursor), rateLimit };
483
512
  };
484
513
  yield* paginate(fetchPage, options);
485
514
  }
@@ -642,7 +671,8 @@ var UsersClient = class {
642
671
  */
643
672
  async *searchAll(query, options = {}) {
644
673
  const fetchPage = async (cursor) => {
645
- return this.search(query, { ...options, cursor });
674
+ const { data, rateLimit } = await this.client.requestWithHeaders("/v1/twitter/users/search_users", { params: { query, cursor } });
675
+ return { response: createPaginatedResponse(data.data ?? [], data.next_cursor), rateLimit };
646
676
  };
647
677
  yield* paginate(fetchPage, options);
648
678
  }
@@ -702,7 +732,8 @@ var ListsClient = class {
702
732
  */
703
733
  async *getTweetsAll(listId, options = {}) {
704
734
  const fetchPage = async (cursor) => {
705
- return this.getTweets(listId, { ...options, cursor });
735
+ const { data, rateLimit } = await this.client.requestWithHeaders(`/v1/twitter/lists/${listId}/tweets`, { params: { cursor } });
736
+ return { response: createPaginatedResponse(data.data ?? [], data.next_cursor), rateLimit };
706
737
  };
707
738
  yield* paginate(fetchPage, options);
708
739
  }
@@ -737,7 +768,8 @@ var ListsClient = class {
737
768
  */
738
769
  async *getMembersAll(listId, options = {}) {
739
770
  const fetchPage = async (cursor) => {
740
- return this.getMembers(listId, { ...options, cursor });
771
+ const { data, rateLimit } = await this.client.requestWithHeaders(`/v1/twitter/lists/${listId}/members`, { params: { cursor } });
772
+ return { response: createPaginatedResponse(data.data ?? [], data.next_cursor), rateLimit };
741
773
  };
742
774
  yield* paginate(fetchPage, options);
743
775
  }
@@ -885,7 +917,14 @@ var CommunitiesClient = class {
885
917
  */
886
918
  async *getTweetsAll(communityId, options = {}) {
887
919
  const fetchPage = async (cursor) => {
888
- return this.getTweets(communityId, { ...options, cursor });
920
+ const { data, rateLimit } = await this.client.requestWithHeaders(`/v1/twitter/communities/${communityId}/tweets`, {
921
+ params: {
922
+ tweet_type: options.tweetType ?? "Top",
923
+ count: options.count ?? 40,
924
+ cursor
925
+ }
926
+ });
927
+ return { response: createPaginatedResponse(data.data ?? [], data.next_cursor), rateLimit };
889
928
  };
890
929
  yield* paginate(fetchPage, options);
891
930
  }