@crawlee/core 4.0.0-beta.105 → 4.0.0-beta.106

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.
Files changed (75) hide show
  1. package/autoscaling/autoscaled_pool.d.ts +3 -21
  2. package/autoscaling/autoscaled_pool.js +85 -85
  3. package/autoscaling/client_load_signal.d.ts +1 -5
  4. package/autoscaling/client_load_signal.js +20 -20
  5. package/autoscaling/concurrency_system.d.ts +5 -20
  6. package/autoscaling/concurrency_system.js +81 -80
  7. package/autoscaling/cpu_load_signal.d.ts +1 -2
  8. package/autoscaling/cpu_load_signal.js +10 -10
  9. package/autoscaling/event_loop_load_signal.d.ts +1 -4
  10. package/autoscaling/event_loop_load_signal.js +18 -18
  11. package/autoscaling/load_signal.d.ts +1 -1
  12. package/autoscaling/load_signal.js +12 -11
  13. package/autoscaling/memory_load_signal.d.ts +3 -12
  14. package/autoscaling/memory_load_signal.js +40 -41
  15. package/autoscaling/snapshotter.d.ts +1 -4
  16. package/autoscaling/snapshotter.js +12 -12
  17. package/autoscaling/system_status.d.ts +1 -3
  18. package/autoscaling/system_status.js +11 -11
  19. package/configuration.d.ts +1 -1
  20. package/configuration.js +3 -3
  21. package/crawlers/context_pipeline.js +6 -6
  22. package/crawlers/statistics.d.ts +1 -8
  23. package/crawlers/statistics.js +45 -44
  24. package/events/event_manager.d.ts +1 -1
  25. package/events/event_manager.js +3 -3
  26. package/events/local_event_manager.d.ts +1 -1
  27. package/events/local_event_manager.js +3 -3
  28. package/log.js +5 -1
  29. package/memory-storage/memory-storage.d.ts +1 -5
  30. package/memory-storage/memory-storage.js +2 -2
  31. package/memory-storage/resource-clients/dataset.d.ts +1 -1
  32. package/memory-storage/resource-clients/dataset.js +6 -5
  33. package/memory-storage/resource-clients/key-value-store.d.ts +1 -1
  34. package/memory-storage/resource-clients/key-value-store.js +13 -12
  35. package/memory-storage/resource-clients/request-queue.d.ts +4 -23
  36. package/memory-storage/resource-clients/request-queue.js +59 -58
  37. package/owned_or_injected.d.ts +1 -3
  38. package/owned_or_injected.js +17 -17
  39. package/package.json +5 -5
  40. package/proxy_configuration.d.ts +1 -3
  41. package/proxy_configuration.js +8 -8
  42. package/recoverable_state.d.ts +1 -10
  43. package/recoverable_state.js +41 -41
  44. package/request.d.ts +1 -2
  45. package/request.js +10 -13
  46. package/router.d.ts +1 -4
  47. package/router.js +23 -23
  48. package/serialization.js +8 -9
  49. package/service_locator.d.ts +1 -10
  50. package/service_locator.js +48 -48
  51. package/session_pool/session.d.ts +1 -12
  52. package/session_pool/session.js +50 -50
  53. package/session_pool/session_pool.d.ts +2 -11
  54. package/session_pool/session_pool.js +59 -58
  55. package/storages/dataset.d.ts +1 -1
  56. package/storages/dataset.js +5 -5
  57. package/storages/key_value_store.d.ts +1 -4
  58. package/storages/key_value_store.js +21 -20
  59. package/storages/request_dedup_cache.d.ts +1 -2
  60. package/storages/request_dedup_cache.js +9 -9
  61. package/storages/request_list.d.ts +2 -22
  62. package/storages/request_list.js +74 -73
  63. package/storages/request_manager_tandem.d.ts +1 -10
  64. package/storages/request_manager_tandem.js +27 -27
  65. package/storages/request_queue.d.ts +2 -18
  66. package/storages/request_queue.js +37 -35
  67. package/storages/sitemap_request_loader.d.ts +1 -44
  68. package/storages/sitemap_request_loader.js +87 -87
  69. package/storages/storage_instance_manager.d.ts +1 -2
  70. package/storages/storage_instance_manager.js +17 -17
  71. package/storages/storage_stats.d.ts +1 -1
  72. package/storages/storage_stats.js +4 -4
  73. package/storages/transaction.d.ts +1 -3
  74. package/storages/transaction.js +17 -17
  75. package/system-info/runtime.js +7 -7
@@ -72,7 +72,7 @@ const CONTENT_TYPE_BINARY = 'application/octet-stream';
72
72
  * @category Sources
73
73
  */
74
74
  export class RequestList {
75
- log = serviceLocator.getLogger().child({ prefix: 'RequestList' });
75
+ #log = serviceLocator.getLogger().child({ prefix: 'RequestList' });
76
76
  /**
77
77
  * Array of all requests from all sources, in the order as they appeared in sources.
78
78
  * All requests in the array have distinct uniqueKey!
@@ -80,9 +80,9 @@ export class RequestList {
80
80
  */
81
81
  requests = [];
82
82
  /** Index to the next item in requests array to fetch. All previous requests are either handled or in progress. */
83
- nextIndex = 0;
83
+ #nextIndex = 0;
84
84
  /** Dictionary, key is Request.uniqueKey, value is corresponding index in the requests array. */
85
- uniqueKeyToIndex = {};
85
+ #uniqueKeyToIndex = {};
86
86
  /**
87
87
  * Set of `uniqueKey`s of requests that were returned by fetchNextRequest().
88
88
  * @internal
@@ -93,7 +93,7 @@ export class RequestList {
93
93
  * re-crawled after a restart. They are served before advancing through the rest of the sources.
94
94
  * @internal
95
95
  */
96
- requestsToRetry = [];
96
+ #requestsToRetry = [];
97
97
  /**
98
98
  * Starts as true because until we handle the first request, the list is effectively persisted by doing nothing.
99
99
  * @internal
@@ -104,17 +104,18 @@ export class RequestList {
104
104
  * @internal
105
105
  */
106
106
  areRequestsPersisted = false;
107
- isLoading = false;
108
- isInitialized = false;
109
- persistStateKey;
110
- persistRequestsKey;
111
- initialState;
112
- store;
113
- keepDuplicateUrls;
107
+ #isLoading = false;
108
+ #isInitialized = false;
109
+ #persistStateKey;
110
+ #persistRequestsKey;
111
+ #initialState;
112
+ #store;
113
+ #keepDuplicateUrls;
114
+ // kept as TS-private: request_list tests read this field directly
114
115
  sources;
115
- sourcesFunction;
116
- proxyConfiguration;
117
- httpClient;
116
+ #sourcesFunction;
117
+ #proxyConfiguration;
118
+ #httpClient;
118
119
  /**
119
120
  * To create new instance of `RequestList` we need to use `RequestList.open()` factory method.
120
121
  * @param options All `RequestList` configuration options
@@ -139,17 +140,17 @@ export class RequestList {
139
140
  proxyConfiguration: ow.optional.object,
140
141
  httpClient: ow.optional.object,
141
142
  }));
142
- this.persistStateKey = persistStateKey ? `CRAWLEE_${persistStateKey}` : persistStateKey;
143
- this.persistRequestsKey = persistRequestsKey ? `CRAWLEE_${persistRequestsKey}` : persistRequestsKey;
144
- this.initialState = state;
145
- this.httpClient = httpClient;
143
+ this.#persistStateKey = persistStateKey ? `CRAWLEE_${persistStateKey}` : persistStateKey;
144
+ this.#persistRequestsKey = persistRequestsKey ? `CRAWLEE_${persistRequestsKey}` : persistRequestsKey;
145
+ this.#initialState = state;
146
+ this.#httpClient = httpClient;
146
147
  // If this option is set then all requests will get a pre-generated unique ID and duplicate URLs will be kept in the list.
147
- this.keepDuplicateUrls = keepDuplicateUrls;
148
+ this.#keepDuplicateUrls = keepDuplicateUrls;
148
149
  // Will be empty after initialization to save memory.
149
150
  this.sources = sources ? [...sources] : [];
150
- this.sourcesFunction = sourcesFunction;
151
+ this.#sourcesFunction = sourcesFunction;
151
152
  // The proxy configuration used for `requestsFromUrl` requests.
152
- this.proxyConfiguration = proxyConfiguration;
153
+ this.#proxyConfiguration = proxyConfiguration;
153
154
  this.persistState = this.persistState.bind(this);
154
155
  }
155
156
  /**
@@ -157,10 +158,10 @@ export class RequestList {
157
158
  * This function must be called before you can start using the instance in a meaningful way.
158
159
  */
159
160
  async initialize() {
160
- if (this.isLoading) {
161
+ if (this.#isLoading) {
161
162
  throw new Error('RequestList sources are already loading or were loaded.');
162
163
  }
163
- this.isLoading = true;
164
+ this.#isLoading = true;
164
165
  await purgeDefaultStorages({ onlyPurgeOnce: true });
165
166
  const [state, persistedRequests] = await this.loadStateAndPersistedRequests();
166
167
  // Add persisted requests / new sources in a memory efficient way because with very
@@ -172,10 +173,10 @@ export class RequestList {
172
173
  await this.addRequestsFromSources();
173
174
  }
174
175
  this.restoreState(state);
175
- this.isInitialized = true;
176
- if (this.persistRequestsKey && !this.areRequestsPersisted)
176
+ this.#isInitialized = true;
177
+ if (this.#persistRequestsKey && !this.areRequestsPersisted)
177
178
  await this.persistRequests();
178
- if (this.persistStateKey) {
179
+ if (this.#persistStateKey) {
179
180
  serviceLocator.getEventManager().on("persistState" /* EventType.PERSIST_STATE */, this.persistState);
180
181
  }
181
182
  return this;
@@ -224,9 +225,9 @@ export class RequestList {
224
225
  }
225
226
  // Drop the original array full of empty indexes.
226
227
  this.sources = [];
227
- if (this.sourcesFunction) {
228
+ if (this.#sourcesFunction) {
228
229
  try {
229
- const sourcesFromFunction = await this.sourcesFunction();
230
+ const sourcesFromFunction = await this.#sourcesFunction();
230
231
  const sourcesFromFunctionCount = sourcesFromFunction.length;
231
232
  for (let i = 0; i < sourcesFromFunctionCount; i++) {
232
233
  const source = sourcesFromFunction[i];
@@ -246,19 +247,19 @@ export class RequestList {
246
247
  * @inheritDoc
247
248
  */
248
249
  async persistState() {
249
- if (!this.persistStateKey) {
250
+ if (!this.#persistStateKey) {
250
251
  throw new Error('Cannot persist state. options.persistStateKey is not set.');
251
252
  }
252
253
  if (this.isStatePersisted)
253
254
  return;
254
255
  try {
255
- this.store ??= await KeyValueStore.open();
256
- await this.store.setValue(this.persistStateKey, this.getState());
256
+ this.#store ??= await KeyValueStore.open();
257
+ await this.#store.setValue(this.#persistStateKey, this.getState());
257
258
  this.isStatePersisted = true;
258
259
  }
259
260
  catch (e) {
260
261
  const err = e;
261
- this.log.exception(err, 'Attempted to persist state, but failed.');
262
+ this.#log.exception(err, 'Attempted to persist state, but failed.');
262
263
  }
263
264
  }
264
265
  /**
@@ -268,7 +269,7 @@ export class RequestList {
268
269
  */
269
270
  async teardown() {
270
271
  serviceLocator.getEventManager().off("persistState" /* EventType.PERSIST_STATE */, this.persistState);
271
- if (this.persistStateKey) {
272
+ if (this.#persistStateKey) {
272
273
  await this.persistState();
273
274
  }
274
275
  }
@@ -279,8 +280,8 @@ export class RequestList {
279
280
  */
280
281
  async persistRequests() {
281
282
  const serializedRequests = await serializeArray(this.requests);
282
- this.store ??= await KeyValueStore.open();
283
- await this.store.setValue(this.persistRequestsKey, serializedRequests, { contentType: CONTENT_TYPE_BINARY });
283
+ this.#store ??= await KeyValueStore.open();
284
+ await this.#store.setValue(this.#persistRequestsKey, serializedRequests, { contentType: CONTENT_TYPE_BINARY });
284
285
  this.areRequestsPersisted = true;
285
286
  }
286
287
  /**
@@ -303,7 +304,7 @@ export class RequestList {
303
304
  }
304
305
  const deleteFromInProgress = [];
305
306
  state.inProgress.forEach((uniqueKey) => {
306
- const index = this.uniqueKeyToIndex[uniqueKey];
307
+ const index = this.#uniqueKeyToIndex[uniqueKey];
307
308
  if (typeof index !== 'number') {
308
309
  throw new Error('The state object is not consistent with RequestList. Unknown uniqueKey is present in the state.');
309
310
  }
@@ -311,7 +312,7 @@ export class RequestList {
311
312
  deleteFromInProgress.push(uniqueKey);
312
313
  }
313
314
  });
314
- this.nextIndex = state.nextIndex;
315
+ this.#nextIndex = state.nextIndex;
315
316
  this.inProgress = new Set(state.inProgress);
316
317
  // WORKAROUND:
317
318
  // It happened to some users that state object contained something like:
@@ -327,7 +328,7 @@ export class RequestList {
327
328
  // As a workaround, we just remove all inProgress requests whose index >= nextIndex,
328
329
  // since they will be crawled again.
329
330
  if (deleteFromInProgress.length) {
330
- this.log.warning("RequestList's in-progress field is not consistent, skipping invalid in-progress entries", {
331
+ this.#log.warning("RequestList's in-progress field is not consistent, skipping invalid in-progress entries", {
331
332
  deleteFromInProgress,
332
333
  });
333
334
  for (const uniqueKey of deleteFromInProgress) {
@@ -335,7 +336,7 @@ export class RequestList {
335
336
  }
336
337
  }
337
338
  // All in-progress requests were interrupted and need to be re-crawled.
338
- this.requestsToRetry = [...this.inProgress];
339
+ this.#requestsToRetry = [...this.inProgress];
339
340
  }
340
341
  /**
341
342
  * Attempts to load state and requests using the `RequestList` configuration
@@ -344,19 +345,19 @@ export class RequestList {
344
345
  async loadStateAndPersistedRequests() {
345
346
  let state;
346
347
  let persistedRequests;
347
- if (this.initialState) {
348
- state = this.initialState;
349
- this.log.debug('Loaded state from options.state argument.');
348
+ if (this.#initialState) {
349
+ state = this.#initialState;
350
+ this.#log.debug('Loaded state from options.state argument.');
350
351
  }
351
- else if (this.persistStateKey) {
352
- state = await this.getPersistedState(this.persistStateKey);
352
+ else if (this.#persistStateKey) {
353
+ state = await this.getPersistedState(this.#persistStateKey);
353
354
  if (state)
354
- this.log.debug('Loaded state from key value store using the persistStateKey.');
355
+ this.#log.debug('Loaded state from key value store using the persistStateKey.');
355
356
  }
356
- if (this.persistRequestsKey) {
357
- persistedRequests = await this.getPersistedState(this.persistRequestsKey);
357
+ if (this.#persistRequestsKey) {
358
+ persistedRequests = await this.getPersistedState(this.#persistRequestsKey);
358
359
  if (persistedRequests)
359
- this.log.debug('Loaded requests from key value store using the persistRequestsKey.');
360
+ this.#log.debug('Loaded requests from key value store using the persistRequestsKey.');
360
361
  }
361
362
  return [state, persistedRequests];
362
363
  }
@@ -367,8 +368,8 @@ export class RequestList {
367
368
  getState() {
368
369
  this.ensureIsInitialized();
369
370
  return {
370
- nextIndex: this.nextIndex,
371
- nextUniqueKey: this.nextIndex < this.requests.length ? this.requests[this.nextIndex].uniqueKey : null,
371
+ nextIndex: this.#nextIndex,
372
+ nextUniqueKey: this.#nextIndex < this.requests.length ? this.requests[this.#nextIndex].uniqueKey : null,
372
373
  inProgress: [...this.inProgress],
373
374
  };
374
375
  }
@@ -377,14 +378,14 @@ export class RequestList {
377
378
  */
378
379
  async isEmpty() {
379
380
  this.ensureIsInitialized();
380
- return this.requestsToRetry.length === 0 && this.nextIndex >= this.requests.length;
381
+ return this.#requestsToRetry.length === 0 && this.#nextIndex >= this.requests.length;
381
382
  }
382
383
  /**
383
384
  * @inheritDoc
384
385
  */
385
386
  async isFinished() {
386
387
  this.ensureIsInitialized();
387
- return this.inProgress.size === 0 && this.nextIndex >= this.requests.length;
388
+ return this.inProgress.size === 0 && this.#nextIndex >= this.requests.length;
388
389
  }
389
390
  /**
390
391
  * @inheritDoc
@@ -392,17 +393,17 @@ export class RequestList {
392
393
  async fetchNextRequest() {
393
394
  this.ensureIsInitialized();
394
395
  // First re-serve any requests that were interrupted before the last state persist.
395
- const uniqueKey = this.requestsToRetry.shift();
396
+ const uniqueKey = this.#requestsToRetry.shift();
396
397
  if (uniqueKey) {
397
- const index = this.uniqueKeyToIndex[uniqueKey];
398
+ const index = this.#uniqueKeyToIndex[uniqueKey];
398
399
  return this.ensureRequest(this.requests[index], index);
399
400
  }
400
401
  // Otherwise return next request.
401
- if (this.nextIndex < this.requests.length) {
402
- const index = this.nextIndex;
402
+ if (this.#nextIndex < this.requests.length) {
403
+ const index = this.#nextIndex;
403
404
  const request = this.requests[index];
404
405
  this.inProgress.add(request.uniqueKey);
405
- this.nextIndex++;
406
+ this.#nextIndex++;
406
407
  this.isStatePersisted = false;
407
408
  return this.ensureRequest(request, index);
408
409
  }
@@ -446,7 +447,7 @@ export class RequestList {
446
447
  fetchedRequests.forEach((request) => this.addRequest(request));
447
448
  const fetchedCount = fetchedRequests.length;
448
449
  const importedCount = this.requests.length - originalLength;
449
- this.log.info('Fetched and loaded Requests from a remote resource.', {
450
+ this.#log.info('Fetched and loaded Requests from a remote resource.', {
450
451
  requestsFromUrl,
451
452
  regex,
452
453
  fetchedCount,
@@ -456,8 +457,8 @@ export class RequestList {
456
457
  });
457
458
  }
458
459
  async getPersistedState(key) {
459
- this.store ??= await KeyValueStore.open();
460
- const state = await this.store.getValue(key);
460
+ this.#store ??= await KeyValueStore.open();
461
+ const state = await this.#store.getValue(key);
461
462
  return state;
462
463
  }
463
464
  /**
@@ -468,10 +469,10 @@ export class RequestList {
468
469
  // Download remote resource and parse URLs.
469
470
  let urlsArr;
470
471
  try {
471
- urlsArr = await this._downloadListOfUrls({
472
+ urlsArr = await this.downloadListOfUrls({
472
473
  url: requestsFromUrl,
473
474
  urlRegExp: regex,
474
- proxyUrl: (await this.proxyConfiguration?.newProxyInfo())?.url,
475
+ proxyUrl: (await this.#proxyConfiguration?.newProxyInfo())?.url,
475
476
  });
476
477
  }
477
478
  catch (err) {
@@ -479,7 +480,7 @@ export class RequestList {
479
480
  }
480
481
  // Skip if resource contained no URLs.
481
482
  if (!urlsArr.length) {
482
- this.log.warning('The fetched list contains no valid URLs.', { requestsFromUrl, regex });
483
+ this.#log.warning('The fetched list contains no valid URLs.', { requestsFromUrl, regex });
483
484
  return [];
484
485
  }
485
486
  return urlsArr.map((url) => ({ url, ...sharedOpts }));
@@ -507,18 +508,18 @@ export class RequestList {
507
508
  const hasUniqueKey = Reflect.has(Object(source), 'uniqueKey');
508
509
  request.uniqueKey ??= Request.computeUniqueKey(request);
509
510
  // Add index to uniqueKey if duplicates are to be kept
510
- if (this.keepDuplicateUrls && !hasUniqueKey) {
511
+ if (this.#keepDuplicateUrls && !hasUniqueKey) {
511
512
  request.uniqueKey += `-${this.requests.length}`;
512
513
  }
513
514
  const { uniqueKey } = request;
514
515
  this.ensureUniqueKeyValid(uniqueKey);
515
516
  // Skip requests with duplicate uniqueKey
516
- if (!Object.hasOwn(this.uniqueKeyToIndex, uniqueKey)) {
517
- this.uniqueKeyToIndex[uniqueKey] = this.requests.length;
517
+ if (!Object.hasOwn(this.#uniqueKeyToIndex, uniqueKey)) {
518
+ this.#uniqueKeyToIndex[uniqueKey] = this.requests.length;
518
519
  this.requests.push(request);
519
520
  }
520
- else if (this.keepDuplicateUrls) {
521
- this.log.warning(`Duplicate uniqueKey: ${uniqueKey} found while the keepDuplicateUrls option was set. Check your sources' unique keys.`);
521
+ else if (this.#keepDuplicateUrls) {
522
+ this.#log.warning(`Duplicate uniqueKey: ${uniqueKey} found while the keepDuplicateUrls option was set. Check your sources' unique keys.`);
522
523
  }
523
524
  }
524
525
  /**
@@ -542,7 +543,7 @@ export class RequestList {
542
543
  * Throws an error if request list wasn't initialized.
543
544
  */
544
545
  ensureIsInitialized() {
545
- if (!this.isInitialized) {
546
+ if (!this.#isInitialized) {
546
547
  throw new Error('RequestList is not initialized; you must call "await requestList.initialize()" before using it!');
547
548
  }
548
549
  }
@@ -558,7 +559,7 @@ export class RequestList {
558
559
  */
559
560
  async getPendingCount() {
560
561
  this.ensureIsInitialized();
561
- return this.requests.length - (this.nextIndex - this.inProgress.size);
562
+ return this.requests.length - (this.#nextIndex - this.inProgress.size);
562
563
  }
563
564
  /**
564
565
  * Combines this list with a request manager (a {@link RequestQueue} by default) into a
@@ -576,7 +577,7 @@ export class RequestList {
576
577
  */
577
578
  async getHandledCount() {
578
579
  this.ensureIsInitialized();
579
- return this.nextIndex - this.inProgress.size;
580
+ return this.#nextIndex - this.inProgress.size;
580
581
  }
581
582
  /**
582
583
  * Opens a request list and returns a promise resolving to an instance
@@ -654,10 +655,10 @@ export class RequestList {
654
655
  /**
655
656
  * @internal wraps public utility for mocking purposes
656
657
  */
657
- async _downloadListOfUrls(options) {
658
+ async downloadListOfUrls(options) {
658
659
  return downloadListOfUrls({
659
660
  ...options,
660
- httpClient: this.httpClient,
661
+ httpClient: this.#httpClient,
661
662
  });
662
663
  }
663
664
  }
@@ -9,16 +9,7 @@ import type { AddRequestsBatchedOptions, AddRequestsBatchedResult, RequestQueueO
9
9
  * It first reads requests from the loader and then, when needed, transfers them in batches to the manager.
10
10
  */
11
11
  export declare class RequestManagerTandem implements IRequestManager {
12
- private log;
13
- private requestLoader;
14
- private requestManagerPromise?;
15
- private resolvedRequestManager?;
16
- private requestManagerFactory;
17
- /**
18
- * The latest expected request-processing time hinted via {@link setExpectedRequestProcessingTimeSecs}.
19
- * Remembered so it can be applied to the writable manager once it is lazily resolved.
20
- */
21
- private expectedRequestProcessingSecs?;
12
+ #private;
22
13
  /**
23
14
  * @param requestLoader The read-only loader to read requests from first.
24
15
  * @param requestManager The writable manager to transfer requests into and enqueue new ones. May be passed as a
@@ -5,16 +5,16 @@ import { serviceLocator } from '../service_locator.js';
5
5
  * It first reads requests from the loader and then, when needed, transfers them in batches to the manager.
6
6
  */
7
7
  export class RequestManagerTandem {
8
- log;
9
- requestLoader;
10
- requestManagerPromise;
11
- resolvedRequestManager;
12
- requestManagerFactory;
8
+ #log;
9
+ #requestLoader;
10
+ #requestManagerPromise;
11
+ #resolvedRequestManager;
12
+ #requestManagerFactory;
13
13
  /**
14
14
  * The latest expected request-processing time hinted via {@link setExpectedRequestProcessingTimeSecs}.
15
15
  * Remembered so it can be applied to the writable manager once it is lazily resolved.
16
16
  */
17
- expectedRequestProcessingSecs;
17
+ #expectedRequestProcessingSecs;
18
18
  /**
19
19
  * @param requestLoader The read-only loader to read requests from first.
20
20
  * @param requestManager The writable manager to transfer requests into and enqueue new ones. May be passed as a
@@ -22,24 +22,24 @@ export class RequestManagerTandem {
22
22
  * (e.g. a lazily-opened default {@link RequestQueue}).
23
23
  */
24
24
  constructor(requestLoader, requestManager) {
25
- this.log = serviceLocator.getLogger().child({ prefix: 'RequestManagerTandem' });
26
- this.requestLoader = requestLoader;
27
- this.requestManagerFactory = typeof requestManager === 'function' ? requestManager : () => requestManager;
25
+ this.#log = serviceLocator.getLogger().child({ prefix: 'RequestManagerTandem' });
26
+ this.#requestLoader = requestLoader;
27
+ this.#requestManagerFactory = typeof requestManager === 'function' ? requestManager : () => requestManager;
28
28
  }
29
29
  /**
30
30
  * Resolves the writable request manager, opening it lazily (via the factory) on first use and memoizing the result.
31
31
  * @private
32
32
  */
33
33
  async getRequestManager() {
34
- if (this.resolvedRequestManager === undefined) {
35
- this.requestManagerPromise ??= Promise.resolve(this.requestManagerFactory());
36
- this.resolvedRequestManager = await this.requestManagerPromise;
34
+ if (this.#resolvedRequestManager === undefined) {
35
+ this.#requestManagerPromise ??= Promise.resolve(this.#requestManagerFactory());
36
+ this.#resolvedRequestManager = await this.#requestManagerPromise;
37
37
  // Apply any hint received before the manager was resolved.
38
- if (this.expectedRequestProcessingSecs !== undefined) {
39
- await this.resolvedRequestManager.setExpectedRequestProcessingTimeSecs?.(this.expectedRequestProcessingSecs);
38
+ if (this.#expectedRequestProcessingSecs !== undefined) {
39
+ await this.#resolvedRequestManager.setExpectedRequestProcessingTimeSecs?.(this.#expectedRequestProcessingSecs);
40
40
  }
41
41
  }
42
- return this.resolvedRequestManager;
42
+ return this.#resolvedRequestManager;
43
43
  }
44
44
  /**
45
45
  * Transfers a single request from the read-only loader to the writable manager.
@@ -50,7 +50,7 @@ export class RequestManagerTandem {
50
50
  * @private
51
51
  */
52
52
  async transferNextRequestToQueue() {
53
- const request = await this.requestLoader.fetchNextRequest();
53
+ const request = await this.#requestLoader.fetchNextRequest();
54
54
  if (request === null) {
55
55
  return true;
56
56
  }
@@ -60,12 +60,12 @@ export class RequestManagerTandem {
60
60
  return true;
61
61
  }
62
62
  catch (error) {
63
- this.log.exception(error, 'Adding request from the RequestLoader to the RequestManager failed, the request has been dropped.', { url: request.url, uniqueKey: request.uniqueKey });
63
+ this.#log.exception(error, 'Adding request from the RequestLoader to the RequestManager failed, the request has been dropped.', { url: request.url, uniqueKey: request.uniqueKey });
64
64
  return false;
65
65
  }
66
66
  finally {
67
67
  // Mark it as handled so that the request doesn't get stuck in the `inProgress` state in the loader.
68
- await this.requestLoader.markRequestAsHandled(request);
68
+ await this.#requestLoader.markRequestAsHandled(request);
69
69
  }
70
70
  }
71
71
  /**
@@ -76,8 +76,8 @@ export class RequestManagerTandem {
76
76
  async fetchNextRequest() {
77
77
  // First, try to transfer a request from the requestList
78
78
  const [listEmpty, listFinished] = await Promise.all([
79
- this.requestLoader.isEmpty(),
80
- this.requestLoader.isFinished(),
79
+ this.#requestLoader.isEmpty(),
80
+ this.#requestLoader.isFinished(),
81
81
  ]);
82
82
  if (!listEmpty && !listFinished) {
83
83
  // If the transfer failed, the request was dropped; don't fetch from the manager this round (matching
@@ -94,7 +94,7 @@ export class RequestManagerTandem {
94
94
  */
95
95
  async isFinished() {
96
96
  const requestManager = await this.getRequestManager();
97
- const storagesFinished = await Promise.all([this.requestLoader.isFinished(), requestManager.isFinished()]);
97
+ const storagesFinished = await Promise.all([this.#requestLoader.isFinished(), requestManager.isFinished()]);
98
98
  return storagesFinished.every(Boolean);
99
99
  }
100
100
  /**
@@ -102,7 +102,7 @@ export class RequestManagerTandem {
102
102
  */
103
103
  async isEmpty() {
104
104
  const requestManager = await this.getRequestManager();
105
- const storagesEmpty = await Promise.all([this.requestLoader.isEmpty(), requestManager.isEmpty()]);
105
+ const storagesEmpty = await Promise.all([this.#requestLoader.isEmpty(), requestManager.isEmpty()]);
106
106
  return storagesEmpty.every(Boolean);
107
107
  }
108
108
  /**
@@ -120,7 +120,7 @@ export class RequestManagerTandem {
120
120
  const [managerTotal, loaderTotal] = await Promise.all([
121
121
  requestManager.getTotalCount(),
122
122
  // count only pending to avoid double counting, requests marked as "handled" have been moved to requestManager
123
- this.requestLoader.getPendingCount(),
123
+ this.#requestLoader.getPendingCount(),
124
124
  ]);
125
125
  return managerTotal + loaderTotal;
126
126
  }
@@ -131,7 +131,7 @@ export class RequestManagerTandem {
131
131
  const requestManager = await this.getRequestManager();
132
132
  const [managerPending, loaderPending] = await Promise.all([
133
133
  requestManager.getPendingCount(),
134
- this.requestLoader.getPendingCount(),
134
+ this.#requestLoader.getPendingCount(),
135
135
  ]);
136
136
  return managerPending + loaderPending;
137
137
  }
@@ -175,7 +175,7 @@ export class RequestManagerTandem {
175
175
  * @inheritdoc
176
176
  */
177
177
  async persistState() {
178
- await this.requestLoader.persistState?.();
178
+ await this.#requestLoader.persistState?.();
179
179
  }
180
180
  /**
181
181
  * Purges the writable request manager so the tandem can be reused (e.g. across repeated `crawler.run()` calls).
@@ -191,7 +191,7 @@ export class RequestManagerTandem {
191
191
  * @inheritdoc
192
192
  */
193
193
  async setExpectedRequestProcessingTimeSecs(secs) {
194
- this.expectedRequestProcessingSecs = secs;
195
- await this.resolvedRequestManager?.setExpectedRequestProcessingTimeSecs?.(secs);
194
+ this.#expectedRequestProcessingSecs = secs;
195
+ await this.#resolvedRequestManager?.setExpectedRequestProcessingTimeSecs?.(secs);
196
196
  }
197
197
  }
@@ -44,29 +44,13 @@ import type { StorageOpenOptions } from './utils.js';
44
44
  * @category Sources
45
45
  */
46
46
  export declare class RequestQueue implements IStorage, IRequestManager {
47
+ #private;
47
48
  readonly id: string;
48
49
  readonly name?: string;
49
50
  readonly backend: RequestQueueBackend;
50
- private proxyConfiguration?;
51
51
  readonly log: CrawleeLogger;
52
52
  private requestCache;
53
- /**
54
- * Remembers the `requestId` of every request already submitted to the client — including background
55
- * batches that `requestCache` skips — so overlapping URL sets aren't re-submitted.
56
- * See {@link RequestDeduplicationCache} for why this is a separate, cheaper cache.
57
- */
58
- private requestSeenCache;
59
- private queuePausedForMigration;
60
53
  private inProgressRequestBatchCount;
61
- /**
62
- * The largest expected request-processing time (in seconds) seen so far via
63
- * {@link setExpectedRequestProcessingTimeSecs}. Used to ensure that value is only ever raised, never
64
- * lowered, before being forwarded to the storage backend.
65
- */
66
- private expectedRequestProcessingSecs;
67
- private httpClient?;
68
- private readonly events;
69
- private readonly statsTracker;
70
54
  /**
71
55
  * Backend-independent usage counters tracked for this request queue (write operations and
72
56
  * queue-head reads issued to the underlying storage backend). Counted per backend call.
@@ -276,7 +260,7 @@ export declare class RequestQueue implements IStorage, IRequestManager {
276
260
  /**
277
261
  * @internal wraps public utility for mocking purposes
278
262
  */
279
- private _downloadListOfUrls;
263
+ private downloadListOfUrls;
280
264
  /**
281
265
  * Opens a request queue and returns a promise resolving to an instance
282
266
  * of the {@link RequestQueue} class.