@crawlee/basic 4.0.0-beta.210 → 4.0.0-beta.212

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.
@@ -95,49 +95,12 @@ export declare class SitemapRequestLoader implements IRequestLoader {
95
95
  inProgress: Set<string>;
96
96
  /** @internal */
97
97
  private constructor();
98
- /**
99
- * Creates a new object stream with the specified highWaterMark.
100
- * @param highWaterMark High water mark for the stream (the maximum number of objects the stream will buffer).
101
- * @returns A new object stream.
102
- */
103
- private createNewStream;
104
- /**
105
- * Returns a function that checks whether the provided pattern matches the closure URL.
106
- * @param url URL to be checked.
107
- * @returns A matcher function that checks whether the pattern matches the closure URL.
108
- */
109
- private matchesUrl;
110
- /**
111
- * Checks whether the URL matches the `include` / `exclude` patterns provided in the `options`.
112
- * @param url URL to be checked.
113
- * @returns `true` if the URL matches the patterns, `false` otherwise.
114
- */
115
- private isUrlMatchingPatterns;
116
- /**
117
- * Adds a URL to the queue of parsed URLs.
118
- *
119
- * Blocks if the stream is full until it is drained.
120
- */
121
- private pushNextUrl;
122
- /**
123
- * Reads the next URL from the queue of parsed URLs.
124
- *
125
- * If the stream is empty, blocks until a new URL is pushed.
126
- * @returns The next URL from the queue or `null` if we have read all URLs.
127
- */
128
- private readNextUrl;
129
98
  /**
130
99
  * Indicates whether the background processing of sitemap contents has successfully finished.
131
100
  *
132
101
  * If this is `false`, the background processing is either still in progress or was aborted.
133
102
  */
134
103
  isSitemapFullyLoaded(): boolean;
135
- /**
136
- * Start processing the sitemaps and loading the URLs.
137
- *
138
- * Resolves once all the sitemaps URLs have been fully loaded (sets `isSitemapFullyLoaded` to `true`).
139
- */
140
- private load;
141
104
  /**
142
105
  * Open a sitemap and start processing it.
143
106
  *
@@ -172,7 +135,6 @@ export declare class SitemapRequestLoader implements IRequestLoader {
172
135
  * @inheritDoc
173
136
  */
174
137
  persistState(): Promise<void>;
175
- private restoreState;
176
138
  /**
177
139
  * @inheritDoc
178
140
  */
@@ -192,6 +154,5 @@ export declare class SitemapRequestLoader implements IRequestLoader {
192
154
  * @inheritDoc
193
155
  */
194
156
  markRequestAsHandled(request: Request): Promise<void>;
195
- private ensureInProgress;
196
157
  }
197
158
  export {};
@@ -107,7 +107,7 @@ export class SitemapRequestLoader {
107
107
  this.#persistenceOptions = { enable: true, ...persistenceOptions };
108
108
  this.#proxyUrl = proxyUrl;
109
109
  this.#enqueueStrategy = enqueueStrategy;
110
- this.#urlQueueStream = this.createNewStream(maxBufferSize);
110
+ this.#urlQueueStream = this.#createNewStream(maxBufferSize);
111
111
  this.#sitemapParsingProgress.pendingSitemapUrls = new Set(sitemapUrls);
112
112
  this.#events = serviceLocator.getEventManager();
113
113
  this.persistState = this.persistState.bind(this);
@@ -117,7 +117,7 @@ export class SitemapRequestLoader {
117
117
  * @param highWaterMark High water mark for the stream (the maximum number of objects the stream will buffer).
118
118
  * @returns A new object stream.
119
119
  */
120
- createNewStream(highWaterMark) {
120
+ #createNewStream(highWaterMark) {
121
121
  return new Transform({
122
122
  objectMode: true,
123
123
  highWaterMark,
@@ -128,7 +128,7 @@ export class SitemapRequestLoader {
128
128
  * @param url URL to be checked.
129
129
  * @returns A matcher function that checks whether the pattern matches the closure URL.
130
130
  */
131
- matchesUrl(url) {
131
+ #matchesUrl(url) {
132
132
  return (patternObject) => {
133
133
  const { regexp, glob } = patternObject;
134
134
  const matchesRegex = (regexp && url.match(regexp)) || false;
@@ -141,18 +141,18 @@ export class SitemapRequestLoader {
141
141
  * @param url URL to be checked.
142
142
  * @returns `true` if the URL matches the patterns, `false` otherwise.
143
143
  */
144
- isUrlMatchingPatterns(url) {
145
- return (!this.#urlExcludePatternObjects.some(this.matchesUrl(url)) &&
146
- (this.#urlPatternObjects.length === 0 || this.#urlPatternObjects.some(this.matchesUrl(url))));
144
+ #isUrlMatchingPatterns(url) {
145
+ return (!this.#urlExcludePatternObjects.some(this.#matchesUrl(url)) &&
146
+ (this.#urlPatternObjects.length === 0 || this.#urlPatternObjects.some(this.#matchesUrl(url))));
147
147
  }
148
148
  /**
149
149
  * Adds a URL to the queue of parsed URLs.
150
150
  *
151
151
  * Blocks if the stream is full until it is drained.
152
152
  */
153
- async pushNextUrl(url) {
153
+ async #pushNextUrl(url) {
154
154
  return new Promise((resolve) => {
155
- if (this.#closed || (url && !this.isUrlMatchingPatterns(url))) {
155
+ if (this.#closed || (url && !this.#isUrlMatchingPatterns(url))) {
156
156
  resolve();
157
157
  return;
158
158
  }
@@ -173,7 +173,7 @@ export class SitemapRequestLoader {
173
173
  * If the stream is empty, blocks until a new URL is pushed.
174
174
  * @returns The next URL from the queue or `null` if we have read all URLs.
175
175
  */
176
- async readNextUrl() {
176
+ async #readNextUrl() {
177
177
  return new Promise((resolve) => {
178
178
  if (this.#closed) {
179
179
  resolve(null);
@@ -206,7 +206,7 @@ export class SitemapRequestLoader {
206
206
  *
207
207
  * Resolves once all the sitemaps URLs have been fully loaded (sets `isSitemapFullyLoaded` to `true`).
208
208
  */
209
- async load({ parseSitemapOptions, }) {
209
+ async #load({ parseSitemapOptions, }) {
210
210
  while (!this.isSitemapFullyLoaded() && !this.#abortLoading) {
211
211
  const sitemapUrl = this.#sitemapParsingProgress.inProgressSitemapUrl ??
212
212
  this.#sitemapParsingProgress.pendingSitemapUrls.values().next().value;
@@ -223,7 +223,7 @@ export class SitemapRequestLoader {
223
223
  continue;
224
224
  }
225
225
  if (!this.#sitemapParsingProgress.inProgressEntries.has(item.loc)) {
226
- await this.pushNextUrl(item.loc);
226
+ await this.#pushNextUrl(item.loc);
227
227
  this.#sitemapParsingProgress.inProgressEntries.add(item.loc);
228
228
  }
229
229
  }
@@ -250,8 +250,8 @@ export class SitemapRequestLoader {
250
250
  ...restOptions,
251
251
  persistStateKey: options.persistStateKey ?? STATE_PERSISTENCE_KEY,
252
252
  });
253
- await requestList.restoreState();
254
- void requestList.load({
253
+ await requestList.#restoreState();
254
+ void requestList.#load({
255
255
  parseSitemapOptions: { logger: serviceLocator.getLogger(), ...options.parseSitemapOptions, httpClient },
256
256
  });
257
257
  if (requestList.#persistenceOptions.enable) {
@@ -328,7 +328,7 @@ export class SitemapRequestLoader {
328
328
  // Create a new stream, as we have read all the URLs from the current one.
329
329
  // Pushing the urls back to the original stream might not be possible if it has been ended.
330
330
  const previousStream = this.#urlQueueStream;
331
- const newStream = this.createNewStream(previousStream.readableHighWaterMark);
331
+ const newStream = this.#createNewStream(previousStream.readableHighWaterMark);
332
332
  for (const url of urlQueue) {
333
333
  newStream.push(url);
334
334
  }
@@ -355,7 +355,7 @@ export class SitemapRequestLoader {
355
355
  closed: this.#closed,
356
356
  });
357
357
  }
358
- async restoreState() {
358
+ async #restoreState() {
359
359
  await purgeDefaultStorages({ onlyPurgeOnce: true });
360
360
  if (this.#persistStateKey === undefined) {
361
361
  return;
@@ -381,7 +381,7 @@ export class SitemapRequestLoader {
381
381
  * @inheritDoc
382
382
  */
383
383
  async fetchNextRequest() {
384
- const nextUrl = await this.readNextUrl();
384
+ const nextUrl = await this.#readNextUrl();
385
385
  if (!nextUrl) {
386
386
  return null;
387
387
  }
@@ -420,11 +420,11 @@ export class SitemapRequestLoader {
420
420
  */
421
421
  async markRequestAsHandled(request) {
422
422
  this.#handledUrlCount += 1;
423
- this.ensureInProgress(request.url);
423
+ this.#ensureInProgress(request.url);
424
424
  this.inProgress.delete(request.url);
425
425
  this.#requestData.delete(request.url);
426
426
  }
427
- ensureInProgress(url) {
427
+ #ensureInProgress(url) {
428
428
  if (!this.inProgress.has(url)) {
429
429
  throw new Error(`The request is not being processed (url: ${url})`);
430
430
  }
@@ -153,7 +153,6 @@ export interface ThrottlingRequestManagerOptions<T extends IRequestManager = IRe
153
153
  */
154
154
  export declare class ThrottlingRequestManager<T extends IRequestManager = IRequestManager> implements IRequestManager {
155
155
  #private;
156
- private readonly config;
157
156
  constructor(options: ThrottlingRequestManagerOptions<T>, config?: Configuration);
158
157
  /**
159
158
  * The wrapped manager, holding every request whose domain is not throttled. `undefined` until an `inner`
@@ -91,7 +91,6 @@ const MAX_INNER_MIGRATIONS = 1000;
91
91
  * @category Sources
92
92
  */
93
93
  export class ThrottlingRequestManager {
94
- config;
95
94
  #innerFactory;
96
95
  #innerPromise;
97
96
  #resolvedInner;
@@ -104,6 +103,7 @@ export class ThrottlingRequestManager {
104
103
  #throttleBy;
105
104
  #maxThrottledDomains;
106
105
  #persistStateKey;
106
+ #config;
107
107
  #subManagers = new Map();
108
108
  #domainStates = new Map();
109
109
  #log;
@@ -142,12 +142,12 @@ export class ThrottlingRequestManager {
142
142
  return this.#listedDomains.size > 0 || this.#throttlesEveryDomain;
143
143
  }
144
144
  constructor(options, config = serviceLocator.getConfiguration()) {
145
- this.config = config;
145
+ this.#config = config;
146
146
  parseArgument(options, throttlingRequestManagerOptionsSchema, 'ThrottlingRequestManagerOptions');
147
147
  if (options.inner === undefined) {
148
148
  // Deferred like any other factory, so a manager nobody fetches from opens no storage. The opener is
149
149
  // assigned below and read only when this runs.
150
- this.#innerFactory = () => this.#requestManagerOpener(null, { configuration: this.config });
150
+ this.#innerFactory = () => this.#requestManagerOpener(null, { configuration: this.#config });
151
151
  }
152
152
  else if (typeof options.inner === 'function') {
153
153
  this.#innerFactory = options.inner;
@@ -301,7 +301,7 @@ export class ThrottlingRequestManager {
301
301
  subManager = this.#requestManagerOpener(
302
302
  // Backends use the alias as a directory name, and an IPv6 literal is full of characters
303
303
  // Windows will not accept. Ordinary hostnames survive this untouched.
304
- { alias: `throttled-${encodeURIComponent(domain)}` }, { configuration: this.config });
304
+ { alias: `throttled-${encodeURIComponent(domain)}` }, { configuration: this.#config });
305
305
  this.#subManagers.set(domain, subManager);
306
306
  this.#ensureDomainState(domain);
307
307
  }
@@ -333,7 +333,7 @@ export class ThrottlingRequestManager {
333
333
  async #ensureSubManagers() {
334
334
  this.#subManagersReady ??= (async () => {
335
335
  if (this.#throttlesEveryDomain) {
336
- this.#domainListStore = await KeyValueStore.open(null, { configuration: this.config });
336
+ this.#domainListStore = await KeyValueStore.open(null, { configuration: this.#config });
337
337
  for (const domain of (await this.#domainListStore.getValue(this.#persistStateKey)) ?? []) {
338
338
  this.#discoveredDomains.add(domain);
339
339
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@crawlee/basic",
3
- "version": "4.0.0-beta.210",
3
+ "version": "4.0.0-beta.212",
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": "^3.0.1",
43
43
  "@apify/timeout": "^1.0.1",
44
44
  "@apify/utilities": "^3.0.1",
45
- "@crawlee/core": "4.0.0-beta.210",
46
- "@crawlee/http-client": "4.0.0-beta.210",
47
- "@crawlee/types": "4.0.0-beta.210",
48
- "@crawlee/utils": "4.0.0-beta.210",
45
+ "@crawlee/core": "4.0.0-beta.212",
46
+ "@crawlee/http-client": "4.0.0-beta.212",
47
+ "@crawlee/types": "4.0.0-beta.212",
48
+ "@crawlee/utils": "4.0.0-beta.212",
49
49
  "@sapphire/async-queue": "^1.5.5",
50
50
  "@standard-schema/spec": "^1.0.0",
51
51
  "csv-stringify": "^6.5.2",
@@ -57,7 +57,7 @@
57
57
  "zod": "^4.5.4"
58
58
  },
59
59
  "optionalDependencies": {
60
- "@crawlee/impit-client": "4.0.0-beta.210"
60
+ "@crawlee/impit-client": "4.0.0-beta.212"
61
61
  },
62
62
  "lerna": {
63
63
  "command": {
@@ -66,5 +66,5 @@
66
66
  }
67
67
  }
68
68
  },
69
- "gitHead": "037dff5d651d88e96749cc79d17bc6d1e154f4e1"
69
+ "gitHead": "171a63a5d7f2a6d74cbce58479204ac20d30b87e"
70
70
  }