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.
- package/README.md +31 -5
- package/dist/{index-DQ_jDTcQ.d.cts → index-Cg0sNluO.d.cts} +22 -0
- package/dist/{index-DQ_jDTcQ.d.ts → index-Cg0sNluO.d.ts} +22 -0
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +111 -19
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +111 -19
- package/dist/index.mjs.map +1 -1
- package/dist/twitter/index.d.cts +1 -1
- package/dist/twitter/index.d.ts +1 -1
- package/dist/twitter/index.js +49 -10
- package/dist/twitter/index.js.map +1 -1
- package/dist/twitter/index.mjs +49 -10
- package/dist/twitter/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/twitter/index.mjs
CHANGED
|
@@ -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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
}
|