@crawlee/basic 4.0.0-beta.151 → 4.0.0-beta.153

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.
@@ -1118,6 +1118,30 @@ export class BasicCrawler {
1118
1118
  // otherwise the URL alone is enough to build the callback argument and to log with.
1119
1119
  const hasSkippedRequestCallback = this.#onSkippedRequest !== undefined || options.onSkippedRequest !== undefined;
1120
1120
  const keepSkippedSource = (source) => (hasSkippedRequestCallback ? source : source.url);
1121
+ const reportSkippedRequests = async () => {
1122
+ const skippedRequests = allSkipped.splice(0);
1123
+ if (skippedRequests.length === 0) {
1124
+ return;
1125
+ }
1126
+ const skippedRobotsUrls = skippedRequests
1127
+ .filter((s) => s.reason === 'robotsTxt')
1128
+ .map(({ source }) => (typeof source === 'string' ? source : source.url));
1129
+ if (skippedRobotsUrls.length > 0) {
1130
+ this.log.warning(`Some requests were skipped because they were disallowed based on the robots.txt file`, { skipped: skippedRobotsUrls });
1131
+ }
1132
+ // Only log the limit message when an explicit `limit` was passed (not the internal
1133
+ // `maxRequestsPerCrawl`-derived one), and only once per call.
1134
+ if (options.limit !== undefined && skippedRequests.some((s) => s.reason === 'limit')) {
1135
+ this.log.info(requestLimit === options.limit
1136
+ ? `Skipping requests in this call due to the enqueueLinks limit of ${options.limit}.`
1137
+ : `Skipping requests in this call due to the remaining maxRequestsPerCrawl budget of ${requestLimit}, which is lower than the enqueueLinks limit of ${options.limit}.`);
1138
+ }
1139
+ await Promise.all(skippedRequests.map(async ({ source, reason }) => {
1140
+ const args = createSkippedRequestArgs(source, reason);
1141
+ await this.#handleSkippedRequest(args);
1142
+ await options.onSkippedRequest?.(args);
1143
+ }));
1144
+ };
1121
1145
  async function* filteredRequests() {
1122
1146
  for await (const request of requests) {
1123
1147
  const [requestOptions] = createRequestOptions([typeof request === 'string' ? request : request], { ...options, strategy });
@@ -1164,27 +1188,15 @@ export class BasicCrawler {
1164
1188
  for (const request of result.requestsOverLimit ?? []) {
1165
1189
  allSkipped.push({ source: request, reason: 'limit' });
1166
1190
  }
1167
- if (allSkipped.length > 0) {
1168
- const skippedRobotsUrls = allSkipped
1169
- .filter((s) => s.reason === 'robotsTxt')
1170
- .map(({ source }) => (typeof source === 'string' ? source : source.url));
1171
- if (skippedRobotsUrls.length > 0) {
1172
- this.log.warning(`Some requests were skipped because they were disallowed based on the robots.txt file`, { skipped: skippedRobotsUrls });
1173
- }
1174
- // Only log the limit message when an explicit `limit` was passed (not the internal
1175
- // `maxRequestsPerCrawl`-derived one), and only once per call.
1176
- if (options.limit !== undefined && allSkipped.some((s) => s.reason === 'limit')) {
1177
- this.log.info(requestLimit === options.limit
1178
- ? `Skipping requests in this call due to the enqueueLinks limit of ${options.limit}.`
1179
- : `Skipping requests in this call due to the remaining maxRequestsPerCrawl budget of ${requestLimit}, which is lower than the enqueueLinks limit of ${options.limit}.`);
1180
- }
1181
- await Promise.all(allSkipped.map(async ({ source, reason }) => {
1182
- const args = createSkippedRequestArgs(source, reason);
1183
- await this.#handleSkippedRequest(args);
1184
- await options.onSkippedRequest?.(args);
1185
- }));
1186
- }
1187
- return result;
1191
+ await reportSkippedRequests();
1192
+ const waitForAllRequestsToBeAdded = result.waitForAllRequestsToBeAdded.then(async (addedRequests) => {
1193
+ await reportSkippedRequests();
1194
+ return addedRequests;
1195
+ });
1196
+ // Keep callback failures observable to callers that await this promise without emitting an unhandled rejection
1197
+ // when callers intentionally leave background additions running, matching `drainRequestBatches` behavior.
1198
+ void waitForAllRequestsToBeAdded.catch(() => { });
1199
+ return { ...result, waitForAllRequestsToBeAdded };
1188
1200
  }
1189
1201
  /**
1190
1202
  * Pushes data to the specified {@link Dataset}, or the default crawler {@link Dataset} by calling {@link Dataset.pushData}.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@crawlee/basic",
3
- "version": "4.0.0-beta.151",
3
+ "version": "4.0.0-beta.153",
4
4
  "description": "The scalable web crawling and scraping library for JavaScript/Node.js. Enables development of data extraction and web automation jobs (not only) with headless Chrome and Puppeteer.",
5
5
  "engines": {
6
6
  "node": ">=22.0.0"
@@ -42,10 +42,10 @@
42
42
  "@apify/datastructures": "^2.0.0",
43
43
  "@apify/timeout": "^0.4.4",
44
44
  "@apify/utilities": "^2.15.5",
45
- "@crawlee/core": "4.0.0-beta.151",
46
- "@crawlee/http-client": "4.0.0-beta.151",
47
- "@crawlee/types": "4.0.0-beta.151",
48
- "@crawlee/utils": "4.0.0-beta.151",
45
+ "@crawlee/core": "4.0.0-beta.153",
46
+ "@crawlee/http-client": "4.0.0-beta.153",
47
+ "@crawlee/types": "4.0.0-beta.153",
48
+ "@crawlee/utils": "4.0.0-beta.153",
49
49
  "csv-stringify": "^6.5.2",
50
50
  "tldts": "^7.0.6",
51
51
  "tslib": "^2.8.1",
@@ -53,7 +53,7 @@
53
53
  "zod": "^4.4.3"
54
54
  },
55
55
  "optionalDependencies": {
56
- "@crawlee/impit-client": "^4.0.0-beta.151"
56
+ "@crawlee/impit-client": "^4.0.0-beta.153"
57
57
  },
58
58
  "lerna": {
59
59
  "command": {
@@ -62,5 +62,5 @@
62
62
  }
63
63
  }
64
64
  },
65
- "gitHead": "1865bf2b241da81d8ed6f1215c59f9d0b88ec553"
65
+ "gitHead": "ed8a71673d628a52574d82e30f098cad1fe7a451"
66
66
  }