@crawlee/basic 4.0.0-beta.2 → 4.0.0-beta.200

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 (91) hide show
  1. package/README.md +17 -13
  2. package/index.d.ts +11 -2
  3. package/index.js +11 -2
  4. package/internals/autoscaling/autoscaled_pool.d.ts +198 -0
  5. package/internals/autoscaling/autoscaled_pool.js +388 -0
  6. package/internals/autoscaling/concurrency_system.d.ts +273 -0
  7. package/internals/autoscaling/concurrency_system.js +359 -0
  8. package/internals/autoscaling/cpu_load_signal.d.ts +43 -0
  9. package/internals/autoscaling/cpu_load_signal.js +46 -0
  10. package/internals/autoscaling/event_loop_load_signal.d.ts +51 -0
  11. package/internals/autoscaling/event_loop_load_signal.js +60 -0
  12. package/internals/autoscaling/index.d.ts +9 -0
  13. package/internals/autoscaling/index.js +9 -0
  14. package/internals/autoscaling/load_signal.d.ts +98 -0
  15. package/internals/autoscaling/load_signal.js +103 -0
  16. package/internals/autoscaling/memory_load_signal.d.ts +47 -0
  17. package/internals/autoscaling/memory_load_signal.js +104 -0
  18. package/internals/autoscaling/snapshotter.d.ts +84 -0
  19. package/internals/autoscaling/snapshotter.js +67 -0
  20. package/internals/autoscaling/storage_backend_load_signal.d.ts +56 -0
  21. package/internals/autoscaling/storage_backend_load_signal.js +73 -0
  22. package/internals/autoscaling/system_status.d.ts +122 -0
  23. package/internals/autoscaling/system_status.js +139 -0
  24. package/internals/autoscaling/weighted_avg.d.ts +5 -0
  25. package/internals/autoscaling/weighted_avg.js +14 -0
  26. package/internals/basic-crawler.d.ts +530 -346
  27. package/internals/basic-crawler.js +1484 -726
  28. package/internals/cookie_utils.d.ts +40 -0
  29. package/internals/cookie_utils.js +122 -0
  30. package/internals/crawler-run.d.ts +76 -0
  31. package/internals/crawler-run.js +142 -0
  32. package/internals/crawlers/context_pipeline.d.ts +71 -0
  33. package/internals/crawlers/context_pipeline.js +117 -0
  34. package/internals/crawlers/crawler_commons.d.ts +194 -0
  35. package/internals/crawlers/crawler_commons.js +1 -0
  36. package/internals/crawlers/error_snapshotter.d.ts +29 -0
  37. package/internals/crawlers/error_snapshotter.js +116 -0
  38. package/internals/crawlers/error_tracker.d.ts +52 -0
  39. package/internals/crawlers/error_tracker.js +316 -0
  40. package/internals/crawlers/index.d.ts +4 -0
  41. package/internals/crawlers/index.js +3 -0
  42. package/internals/crawlers/internals/types.d.ts +7 -0
  43. package/internals/crawlers/internals/types.js +1 -0
  44. package/internals/crawlers/statistics.d.ts +318 -0
  45. package/internals/crawlers/statistics.js +525 -0
  46. package/internals/crawling_request.d.ts +86 -0
  47. package/internals/crawling_request.js +127 -0
  48. package/internals/enqueue_links/enqueue_links.d.ts +152 -0
  49. package/internals/enqueue_links/enqueue_links.js +76 -0
  50. package/internals/enqueue_links/index.d.ts +3 -0
  51. package/internals/enqueue_links/index.js +3 -0
  52. package/internals/enqueue_links/shared.d.ts +104 -0
  53. package/internals/enqueue_links/shared.js +258 -0
  54. package/internals/errors.d.ts +55 -0
  55. package/internals/errors.js +67 -0
  56. package/internals/http.d.ts +9 -0
  57. package/internals/http.js +28 -0
  58. package/internals/request-timeout.d.ts +48 -0
  59. package/internals/request-timeout.js +73 -0
  60. package/internals/router.d.ts +308 -0
  61. package/internals/router.js +312 -0
  62. package/internals/send-request.d.ts +4 -6
  63. package/internals/send-request.js +22 -26
  64. package/internals/session_pool/consts.d.ts +1 -0
  65. package/internals/session_pool/consts.js +1 -0
  66. package/internals/session_pool/errors.d.ts +7 -0
  67. package/internals/session_pool/errors.js +11 -0
  68. package/internals/session_pool/fingerprint.d.ts +9 -0
  69. package/internals/session_pool/fingerprint.js +30 -0
  70. package/internals/session_pool/index.d.ts +4 -0
  71. package/internals/session_pool/index.js +4 -0
  72. package/internals/session_pool/session.d.ts +155 -0
  73. package/internals/session_pool/session.js +222 -0
  74. package/internals/session_pool/session_pool.d.ts +241 -0
  75. package/internals/session_pool/session_pool.js +439 -0
  76. package/internals/sitemap_request_loader.d.ts +197 -0
  77. package/internals/sitemap_request_loader.js +432 -0
  78. package/internals/throttling_request_manager.d.ts +230 -0
  79. package/internals/throttling_request_manager.js +843 -0
  80. package/package.json +19 -13
  81. package/index.d.ts.map +0 -1
  82. package/index.js.map +0 -1
  83. package/internals/basic-crawler.d.ts.map +0 -1
  84. package/internals/basic-crawler.js.map +0 -1
  85. package/internals/constants.d.ts +0 -7
  86. package/internals/constants.d.ts.map +0 -1
  87. package/internals/constants.js +0 -7
  88. package/internals/constants.js.map +0 -1
  89. package/internals/send-request.d.ts.map +0 -1
  90. package/internals/send-request.js.map +0 -1
  91. package/tsconfig.build.tsbuildinfo +0 -1
package/README.md CHANGED
@@ -1,19 +1,23 @@
1
1
  <h1 align="center">
2
2
  <a href="https://crawlee.dev">
3
3
  <picture>
4
- <source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/apify/crawlee/master/website/static/img/crawlee-dark.svg?sanitize=true">
5
- <img alt="Crawlee" src="https://raw.githubusercontent.com/apify/crawlee/master/website/static/img/crawlee-light.svg?sanitize=true" width="500">
4
+ <source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/apify/crawlee/master/website/static/img/crawlee-dark.svg?sanitize=true" />
5
+ <img alt="Crawlee" src="https://raw.githubusercontent.com/apify/crawlee/master/website/static/img/crawlee-light.svg?sanitize=true" width="500" />
6
6
  </picture>
7
7
  </a>
8
- <br>
8
+ <br />
9
9
  <small>A web scraping and browser automation library</small>
10
10
  </h1>
11
11
 
12
- <p align=center>
13
- <a href="https://www.npmjs.com/package/@crawlee/core" rel="nofollow"><img src="https://img.shields.io/npm/v/@crawlee/core.svg" alt="NPM latest version" data-canonical-src="https://img.shields.io/npm/v/@crawlee/core/next.svg" style="max-width: 100%;"></a>
14
- <a href="https://www.npmjs.com/package/@crawlee/core" rel="nofollow"><img src="https://img.shields.io/npm/dm/@crawlee/core.svg" alt="Downloads" data-canonical-src="https://img.shields.io/npm/dm/@crawlee/core.svg" style="max-width: 100%;"></a>
15
- <a href="https://discord.gg/jyEM2PRvMU" rel="nofollow"><img src="https://img.shields.io/discord/801163717915574323?label=discord" alt="Chat on discord" data-canonical-src="https://img.shields.io/discord/801163717915574323?label=discord" style="max-width: 100%;"></a>
16
- <a href="https://github.com/apify/crawlee/actions/workflows/test-ci.yml"><img src="https://github.com/apify/crawlee/actions/workflows/test-ci.yml/badge.svg?branch=master" alt="Build Status" style="max-width: 100%;"></a>
12
+ <p align="center">
13
+ <a href="https://trendshift.io/repositories/5179" target="_blank"><img src="https://trendshift.io/api/badge/repositories/5179" alt="apify%2Fcrawlee | Trendshift" width="250" height="55"/></a>
14
+ </p>
15
+
16
+ <p align="center">
17
+ <a href="https://www.npmjs.com/package/@crawlee/core" rel="nofollow"><img src="https://img.shields.io/npm/v/@crawlee/core.svg" alt="NPM latest version" data-canonical-src="https://img.shields.io/npm/v/@crawlee/core/next.svg" /></a>
18
+ <a href="https://www.npmjs.com/package/@crawlee/core" rel="nofollow"><img src="https://img.shields.io/npm/dm/@crawlee/core.svg" alt="Downloads" data-canonical-src="https://img.shields.io/npm/dm/@crawlee/core.svg" /></a>
19
+ <a href="https://discord.gg/jyEM2PRvMU" rel="nofollow"><img src="https://img.shields.io/discord/801163717915574323?label=discord" alt="Chat on discord" data-canonical-src="https://img.shields.io/discord/801163717915574323?label=discord" /></a>
20
+ <a href="https://github.com/apify/crawlee/actions/workflows/test-ci.yml"><img src="https://github.com/apify/crawlee/actions/workflows/test-ci.yml/badge.svg?branch=master" alt="Build Status" /></a>
17
21
  </p>
18
22
 
19
23
  Crawlee covers your crawling and scraping end-to-end and **helps you build reliable scrapers. Fast.**
@@ -24,7 +28,7 @@ Crawlee is available as the [`crawlee`](https://www.npmjs.com/package/crawlee) N
24
28
 
25
29
  > 👉 **View full documentation, guides and examples on the [Crawlee project website](https://crawlee.dev)** 👈
26
30
 
27
- > Crawlee for Python is open for early adopters. 🐍 [👉 Checkout the source code 👈](https://github.com/apify/crawlee-python).
31
+ > Do you prefer 🐍 Python instead of JavaScript? [👉 Checkout Crawlee for Python 👈](https://github.com/apify/crawlee-python).
28
32
 
29
33
  ## Installation
30
34
 
@@ -85,7 +89,7 @@ By default, Crawlee stores data to `./storage` in the current working directory.
85
89
  We provide automated beta builds for every merged code change in Crawlee. You can find them in the npm [list of releases](https://www.npmjs.com/package/crawlee?activeTab=versions). If you want to test new features or bug fixes before we release them, feel free to install a beta build like this:
86
90
 
87
91
  ```bash
88
- npm install crawlee@3.12.3-beta.13
92
+ npm install crawlee@next
89
93
  ```
90
94
 
91
95
  If you also use the [Apify SDK](https://github.com/apify/apify-sdk-js), you need to specify dependency overrides in your `package.json` file so that you don't end up with multiple versions of Crawlee installed:
@@ -94,9 +98,9 @@ If you also use the [Apify SDK](https://github.com/apify/apify-sdk-js), you need
94
98
  {
95
99
  "overrides": {
96
100
  "apify": {
97
- "@crawlee/core": "3.12.3-beta.13",
98
- "@crawlee/types": "3.12.3-beta.13",
99
- "@crawlee/utils": "3.12.3-beta.13"
101
+ "@crawlee/core": "$crawlee",
102
+ "@crawlee/types": "$crawlee",
103
+ "@crawlee/utils": "$crawlee"
100
104
  }
101
105
  }
102
106
  }
package/index.d.ts CHANGED
@@ -1,4 +1,13 @@
1
1
  export * from '@crawlee/core';
2
+ export * from './internals/autoscaling/index.js';
2
3
  export * from './internals/basic-crawler.js';
3
- export * from './internals/constants.js';
4
- //# sourceMappingURL=index.d.ts.map
4
+ export * from './internals/cookie_utils.js';
5
+ export * from './internals/crawlers/index.js';
6
+ export * from './internals/crawling_request.js';
7
+ export * from './internals/enqueue_links/index.js';
8
+ export * from './internals/errors.js';
9
+ export * from './internals/http.js';
10
+ export * from './internals/router.js';
11
+ export * from './internals/session_pool/index.js';
12
+ export * from './internals/sitemap_request_loader.js';
13
+ export * from './internals/throttling_request_manager.js';
package/index.js CHANGED
@@ -1,4 +1,13 @@
1
1
  export * from '@crawlee/core';
2
+ export * from './internals/autoscaling/index.js';
2
3
  export * from './internals/basic-crawler.js';
3
- export * from './internals/constants.js';
4
- //# sourceMappingURL=index.js.map
4
+ export * from './internals/cookie_utils.js';
5
+ export * from './internals/crawlers/index.js';
6
+ export * from './internals/crawling_request.js';
7
+ export * from './internals/enqueue_links/index.js';
8
+ export * from './internals/errors.js';
9
+ export * from './internals/http.js';
10
+ export * from './internals/router.js';
11
+ export * from './internals/session_pool/index.js';
12
+ export * from './internals/sitemap_request_loader.js';
13
+ export * from './internals/throttling_request_manager.js';
@@ -0,0 +1,198 @@
1
+ import type { CrawleeLogger } from '@crawlee/core';
2
+ import type { ConcurrencyConsumer, IConcurrencySystem } from './concurrency_system.js';
3
+ /**
4
+ * The two predicates that steer a task loop: *is there work ready?* and *are we done?* These are the parts of the loop
5
+ * a caller legitimately overrides, as opposed to the task itself (`runTaskFunction`), which the loop's driver owns.
6
+ */
7
+ export interface TaskLoopPredicates {
8
+ /**
9
+ * A function that indicates whether `runTaskFunction` should be called.
10
+ * This function is called every time there is free capacity for a new task and it should
11
+ * indicate whether it should start a new task or not by resolving to either `true` or `false`.
12
+ * Besides its obvious use, it is also useful for task throttling to save resources.
13
+ */
14
+ isTaskReadyFunction?: () => Promise<boolean>;
15
+ /**
16
+ * A function that is called only when there are no tasks to be processed.
17
+ * If it resolves to `true` then the run finishes. Being called only
18
+ * when there are no tasks being processed means that as long as `isTaskReadyFunction()`
19
+ * keeps resolving to `true`, `isFinishedFunction()` will never be called.
20
+ */
21
+ isFinishedFunction?: () => Promise<boolean>;
22
+ }
23
+ export interface TaskLoopOptions extends TaskLoopPredicates {
24
+ /**
25
+ * How often the pool should check if a new task is ready, in seconds.
26
+ * @default 0.5
27
+ */
28
+ maybeRunIntervalSecs?: number;
29
+ }
30
+ /** @internal */
31
+ export interface AutoscaledPoolOptions extends TaskLoopOptions {
32
+ /**
33
+ * The governor that decides whether there is free compute for one more task. Typically a
34
+ * {@link ConcurrencySystem}, but any {@link IConcurrencySystem} works. Share a single instance across
35
+ * multiple pools (and therefore multiple crawlers) to cap their *combined* concurrency against one budget.
36
+ *
37
+ * All concurrency/scaling/snapshotter configuration lives on the governor — the pool only owns the task loop and
38
+ * its cadence.
39
+ */
40
+ concurrencySystem: IConcurrencySystem;
41
+ /**
42
+ * Who this pool is, presented to the governor on every capacity query and booking so that a shared one can tell
43
+ * several pools apart. Worth naming meaningfully — a governor that allocates per consumer reports this `id`.
44
+ */
45
+ consumer: ConcurrencyConsumer;
46
+ /**
47
+ * A function that performs an asynchronous resource-intensive task.
48
+ * The function must either be labeled `async` or return a promise.
49
+ * @param taskId The id the task is {@link IConcurrencySystem.tryRegisterTaskStart|booked} under, so work done
50
+ * inside can be correlated with what the governor sees.
51
+ */
52
+ runTaskFunction?: (taskId: string) => Promise<unknown>;
53
+ /**
54
+ * Timeout in which the `runTaskFunction` needs to finish, given in seconds.
55
+ * @default 0
56
+ */
57
+ taskTimeoutSecs?: number;
58
+ log?: CrawleeLogger;
59
+ }
60
+ /**
61
+ * Manages a pool of asynchronous resource-intensive tasks that are executed in parallel.
62
+ * The pool only starts new tasks while its {@link IConcurrencySystem|concurrency system} reports free capacity —
63
+ * that governor is what monitors CPU, memory and event loop load and autoscales the concurrency budget.
64
+ *
65
+ * Before running the pool, you need to implement the following three functions:
66
+ * {@link AutoscaledPoolOptions.runTaskFunction|`runTaskFunction`},
67
+ * {@link TaskLoopPredicates.isTaskReadyFunction|`isTaskReadyFunction`} and
68
+ * {@link TaskLoopPredicates.isFinishedFunction|`isFinishedFunction`}.
69
+ *
70
+ * The auto-scaled pool is started by calling the {@link AutoscaledPool.run} function.
71
+ * The pool periodically queries `isTaskReadyFunction` for more tasks, managing optimal concurrency, until the function
72
+ * resolves to `false`. The pool then queries `isFinishedFunction`. If it resolves to `true`, the run finishes after all
73
+ * running tasks complete. If it resolves to `false`, it assumes there will be more tasks available later and keeps
74
+ * periodically querying for tasks.
75
+ * If any of the tasks throws then the {@link AutoscaledPool.run} function rejects the promise with an error.
76
+ *
77
+ * The pool evaluates whether it should start a new task every time one of the tasks finishes
78
+ * and also in the interval set by the `options.maybeRunIntervalSecs` parameter.
79
+ *
80
+ * **Example usage:**
81
+ *
82
+ * ```javascript
83
+ * const concurrencySystem = new ConcurrencySystem({ maxConcurrency: 50 });
84
+ * await concurrencySystem.start();
85
+ *
86
+ * const pool = new AutoscaledPool({
87
+ * concurrencySystem,
88
+ * consumer: { id: 'my-pool' },
89
+ * runTaskFunction: async () => {
90
+ * // Run some resource-intensive asynchronous operation here.
91
+ * },
92
+ * isTaskReadyFunction: async () => {
93
+ * // Tell the pool whether more tasks are ready to be processed.
94
+ * // Return true or false
95
+ * },
96
+ * isFinishedFunction: async () => {
97
+ * // Tell the pool whether it should finish
98
+ * // or wait for more tasks to become available.
99
+ * // Return true or false
100
+ * }
101
+ * });
102
+ *
103
+ * try {
104
+ * await pool.run();
105
+ * } finally {
106
+ * await concurrencySystem.stop();
107
+ * }
108
+ * ```
109
+ *
110
+ * @internal
111
+ */
112
+ export declare class AutoscaledPool {
113
+ #private;
114
+ constructor(options: AutoscaledPoolOptions);
115
+ /**
116
+ * The governor backing this pool, as supplied to the constructor — exposed as the read-only
117
+ * {@link IConcurrencySystem} contract.
118
+ *
119
+ * This and the two getters below are telemetry only: concurrency is configured and tuned on the concrete
120
+ * {@link ConcurrencySystem} its owner holds, never through the pool.
121
+ */
122
+ get system(): IConcurrencySystem;
123
+ /** The estimated number of parallel tasks the governor can currently support. */
124
+ get desiredConcurrency(): number;
125
+ /**
126
+ * The number of parallel tasks currently booked against the governor. When it is shared, this counts every
127
+ * borrowing pool's tasks, not just this one's.
128
+ */
129
+ get currentConcurrency(): number;
130
+ /**
131
+ * Runs the auto-scaled pool. Returns a promise that gets resolved or rejected once
132
+ * all the tasks are finished or one of them fails.
133
+ *
134
+ * Throws if the {@link IConcurrencySystem|concurrency system} it borrows was never started — the pool assumes
135
+ * a running governor and cannot start one it does not own.
136
+ */
137
+ run(): Promise<void>;
138
+ /**
139
+ * Aborts the run of the auto-scaled pool and destroys it. The promise returned from
140
+ * the {@link AutoscaledPool.run} function will immediately resolve, no more new tasks
141
+ * will be spawned and all running tasks will be left in their current state.
142
+ *
143
+ * Due to the nature of the tasks, auto-scaled pool cannot reliably guarantee abortion
144
+ * of all the running tasks, therefore, no abortion is attempted and some of the tasks
145
+ * may finish, while others may not. Essentially, auto-scaled pool doesn't care about
146
+ * their state after the invocation of `.abort()`, but that does not mean that some
147
+ * parts of their asynchronous chains of commands will not execute.
148
+ */
149
+ abort(): Promise<void>;
150
+ /**
151
+ * Prevents the auto-scaled pool from starting new tasks, but allows the running ones to finish
152
+ * (unlike abort, which terminates them). Used together with {@link AutoscaledPool.resume}
153
+ *
154
+ * The function's promise will resolve once all running tasks have completed and the pool
155
+ * is effectively idle. If the `timeoutSecs` argument is provided, the promise will reject
156
+ * with a timeout error after the `timeoutSecs` seconds.
157
+ *
158
+ * The promise returned from the {@link AutoscaledPool.run} function will not resolve
159
+ * when `.pause()` is invoked (unlike abort, which resolves it).
160
+ *
161
+ * > *NOTE:* Pausing the pool does not suspend the (possibly shared) {@link ConcurrencySystem} — its
162
+ * autoscaling and resource monitoring keep running, since other pools borrowing it may still be active. To silence
163
+ * it during a long pause, its owner can `stop()` and `start()` it again.
164
+ */
165
+ pause(timeoutSecs?: number): Promise<void>;
166
+ /**
167
+ * Resumes the operation of the autoscaled-pool by allowing more tasks to be run.
168
+ * Used together with {@link AutoscaledPool.pause}
169
+ *
170
+ * Tasks will automatically start running again in `options.maybeRunIntervalSecs`.
171
+ */
172
+ resume(): void;
173
+ /**
174
+ * Explicitly check the queue for new tasks. The AutoscaledPool checks the queue for new tasks periodically,
175
+ * every `maybeRunIntervalSecs` seconds. If you want to trigger the processing immediately, use this method.
176
+ */
177
+ notify(): Promise<void>;
178
+ /**
179
+ * Starts a new task
180
+ * if the number of running tasks (current concurrency) is lower than desired concurrency
181
+ * and the system is not currently overloaded
182
+ * and `isTaskReadyFunction()` returns true.
183
+ *
184
+ * It doesn't allow multiple concurrent runs of this method.
185
+ */
186
+ private maybeRunTask;
187
+ /**
188
+ * If there are no running tasks and `isFinishedFunction()` returns true then closes
189
+ * the pool and resolves the pool's promise returned by the run() method.
190
+ *
191
+ * It doesn't allow multiple concurrent runs of this method.
192
+ */
193
+ private maybeFinish;
194
+ /**
195
+ * Cleans up resources.
196
+ */
197
+ private destroy;
198
+ }