@crawlee/core 4.0.0-beta.1 → 4.0.0-beta.100

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 (269) hide show
  1. package/README.md +17 -13
  2. package/autoscaling/autoscaled_pool.d.ts +69 -156
  3. package/autoscaling/autoscaled_pool.js +97 -252
  4. package/autoscaling/client_load_signal.d.ts +59 -0
  5. package/autoscaling/client_load_signal.js +73 -0
  6. package/autoscaling/concurrency_system.d.ts +283 -0
  7. package/autoscaling/concurrency_system.js +350 -0
  8. package/autoscaling/cpu_load_signal.d.ts +44 -0
  9. package/autoscaling/cpu_load_signal.js +46 -0
  10. package/autoscaling/event_loop_load_signal.d.ts +54 -0
  11. package/autoscaling/event_loop_load_signal.js +60 -0
  12. package/autoscaling/index.d.ts +6 -1
  13. package/autoscaling/index.js +6 -1
  14. package/autoscaling/load_signal.d.ts +99 -0
  15. package/autoscaling/load_signal.js +103 -0
  16. package/autoscaling/memory_load_signal.d.ts +56 -0
  17. package/autoscaling/memory_load_signal.js +106 -0
  18. package/autoscaling/snapshotter.d.ts +61 -163
  19. package/autoscaling/snapshotter.js +45 -270
  20. package/autoscaling/system_status.d.ts +63 -83
  21. package/autoscaling/system_status.js +90 -120
  22. package/autoscaling/weighted_avg.d.ts +5 -0
  23. package/autoscaling/weighted_avg.js +14 -0
  24. package/byte_utils.d.ts +17 -0
  25. package/byte_utils.js +42 -0
  26. package/configuration.d.ts +96 -230
  27. package/configuration.js +170 -226
  28. package/cookie_utils.d.ts +4 -3
  29. package/cookie_utils.js +22 -13
  30. package/crawlers/context_pipeline.d.ts +70 -0
  31. package/crawlers/context_pipeline.js +122 -0
  32. package/crawlers/crawler_commons.d.ts +96 -40
  33. package/crawlers/crawler_commons.js +15 -24
  34. package/crawlers/error_snapshotter.d.ts +3 -3
  35. package/crawlers/error_snapshotter.js +2 -3
  36. package/crawlers/error_tracker.d.ts +2 -2
  37. package/crawlers/error_tracker.js +0 -1
  38. package/crawlers/index.d.ts +1 -3
  39. package/crawlers/index.js +1 -3
  40. package/crawlers/internals/types.d.ts +7 -0
  41. package/crawlers/internals/types.js +1 -0
  42. package/crawlers/statistics.d.ts +28 -23
  43. package/crawlers/statistics.js +38 -34
  44. package/debug.d.ts +36 -0
  45. package/debug.js +70 -0
  46. package/enqueue_links/enqueue_links.d.ts +59 -68
  47. package/enqueue_links/enqueue_links.js +57 -62
  48. package/enqueue_links/index.d.ts +0 -1
  49. package/enqueue_links/index.js +0 -1
  50. package/enqueue_links/shared.d.ts +39 -26
  51. package/enqueue_links/shared.js +89 -67
  52. package/errors.d.ts +53 -4
  53. package/errors.js +70 -5
  54. package/events/event_manager.d.ts +34 -8
  55. package/events/event_manager.js +8 -10
  56. package/events/index.d.ts +0 -1
  57. package/events/index.js +0 -1
  58. package/events/local_event_manager.d.ts +15 -5
  59. package/events/local_event_manager.js +37 -40
  60. package/index.d.ts +6 -4
  61. package/index.js +5 -3
  62. package/iterables.d.ts +79 -0
  63. package/iterables.js +134 -0
  64. package/log.d.ts +82 -3
  65. package/log.js +102 -1
  66. package/memory-storage/consts.d.ts +4 -0
  67. package/memory-storage/consts.js +4 -0
  68. package/memory-storage/index.d.ts +1 -0
  69. package/memory-storage/index.js +1 -0
  70. package/memory-storage/memory-storage.d.ts +46 -0
  71. package/memory-storage/memory-storage.js +136 -0
  72. package/memory-storage/resource-clients/common/base-client.d.ts +4 -0
  73. package/memory-storage/resource-clients/common/base-client.js +6 -0
  74. package/memory-storage/resource-clients/dataset.d.ts +40 -0
  75. package/memory-storage/resource-clients/dataset.js +113 -0
  76. package/memory-storage/resource-clients/key-value-store.d.ts +63 -0
  77. package/memory-storage/resource-clients/key-value-store.js +203 -0
  78. package/memory-storage/resource-clients/request-queue.d.ts +96 -0
  79. package/memory-storage/resource-clients/request-queue.js +421 -0
  80. package/memory-storage/utils.d.ts +16 -0
  81. package/memory-storage/utils.js +41 -0
  82. package/owned_or_injected.d.ts +60 -0
  83. package/owned_or_injected.js +98 -0
  84. package/package.json +13 -12
  85. package/proxy_configuration.d.ts +29 -152
  86. package/proxy_configuration.js +21 -173
  87. package/recoverable_state.d.ts +120 -0
  88. package/recoverable_state.js +143 -0
  89. package/request.d.ts +85 -17
  90. package/request.js +107 -36
  91. package/router.d.ts +194 -19
  92. package/router.js +177 -32
  93. package/serialization.d.ts +0 -1
  94. package/serialization.js +1 -2
  95. package/service_locator.d.ts +156 -0
  96. package/service_locator.js +244 -0
  97. package/session_pool/consts.d.ts +1 -2
  98. package/session_pool/consts.js +1 -2
  99. package/session_pool/errors.d.ts +0 -1
  100. package/session_pool/errors.js +0 -1
  101. package/session_pool/fingerprint.d.ts +9 -0
  102. package/session_pool/fingerprint.js +30 -0
  103. package/session_pool/index.d.ts +0 -2
  104. package/session_pool/index.js +0 -2
  105. package/session_pool/session.d.ts +37 -75
  106. package/session_pool/session.js +49 -102
  107. package/session_pool/session_pool.d.ts +85 -90
  108. package/session_pool/session_pool.js +131 -120
  109. package/storages/access_checking.d.ts +1 -2
  110. package/storages/access_checking.js +5 -2
  111. package/storages/dataset.d.ts +103 -54
  112. package/storages/dataset.js +174 -132
  113. package/storages/index.d.ts +8 -7
  114. package/storages/index.js +6 -7
  115. package/storages/key_value_store.d.ts +167 -39
  116. package/storages/key_value_store.js +274 -127
  117. package/storages/key_value_store_codec.d.ts +32 -0
  118. package/storages/key_value_store_codec.js +113 -0
  119. package/storages/request_dedup_cache.d.ts +23 -0
  120. package/storages/request_dedup_cache.js +48 -0
  121. package/storages/request_list.d.ts +54 -98
  122. package/storages/request_list.js +99 -75
  123. package/storages/request_loader.d.ts +96 -0
  124. package/storages/request_loader.js +1 -0
  125. package/storages/request_manager.d.ts +33 -0
  126. package/storages/request_manager.js +1 -0
  127. package/storages/request_manager_tandem.d.ts +106 -0
  128. package/storages/request_manager_tandem.js +197 -0
  129. package/storages/request_queue.d.ts +287 -47
  130. package/storages/request_queue.js +620 -215
  131. package/storages/{sitemap_request_list.d.ts → sitemap_request_loader.d.ts} +38 -46
  132. package/storages/{sitemap_request_list.js → sitemap_request_loader.js} +58 -65
  133. package/storages/storage_instance_manager.d.ts +88 -0
  134. package/storages/storage_instance_manager.js +256 -0
  135. package/storages/storage_stats.d.ts +48 -0
  136. package/storages/storage_stats.js +29 -0
  137. package/storages/utils.d.ts +54 -9
  138. package/storages/utils.js +64 -13
  139. package/system-info/cpu-info.d.ts +67 -0
  140. package/system-info/cpu-info.js +216 -0
  141. package/system-info/memory-info.d.ts +31 -0
  142. package/system-info/memory-info.js +115 -0
  143. package/system-info/ps-tree.d.ts +17 -0
  144. package/system-info/ps-tree.js +144 -0
  145. package/system-info/runtime.d.ts +14 -0
  146. package/system-info/runtime.js +80 -0
  147. package/typedefs.d.ts +0 -6
  148. package/typedefs.js +0 -1
  149. package/validators.d.ts +8 -1
  150. package/validators.js +10 -3
  151. package/autoscaling/autoscaled_pool.d.ts.map +0 -1
  152. package/autoscaling/autoscaled_pool.js.map +0 -1
  153. package/autoscaling/index.d.ts.map +0 -1
  154. package/autoscaling/index.js.map +0 -1
  155. package/autoscaling/snapshotter.d.ts.map +0 -1
  156. package/autoscaling/snapshotter.js.map +0 -1
  157. package/autoscaling/system_status.d.ts.map +0 -1
  158. package/autoscaling/system_status.js.map +0 -1
  159. package/configuration.d.ts.map +0 -1
  160. package/configuration.js.map +0 -1
  161. package/cookie_utils.d.ts.map +0 -1
  162. package/cookie_utils.js.map +0 -1
  163. package/crawlers/crawler_commons.d.ts.map +0 -1
  164. package/crawlers/crawler_commons.js.map +0 -1
  165. package/crawlers/crawler_extension.d.ts +0 -12
  166. package/crawlers/crawler_extension.d.ts.map +0 -1
  167. package/crawlers/crawler_extension.js +0 -14
  168. package/crawlers/crawler_extension.js.map +0 -1
  169. package/crawlers/crawler_utils.d.ts +0 -10
  170. package/crawlers/crawler_utils.d.ts.map +0 -1
  171. package/crawlers/crawler_utils.js +0 -12
  172. package/crawlers/crawler_utils.js.map +0 -1
  173. package/crawlers/error_snapshotter.d.ts.map +0 -1
  174. package/crawlers/error_snapshotter.js.map +0 -1
  175. package/crawlers/error_tracker.d.ts.map +0 -1
  176. package/crawlers/error_tracker.js.map +0 -1
  177. package/crawlers/index.d.ts.map +0 -1
  178. package/crawlers/index.js.map +0 -1
  179. package/crawlers/statistics.d.ts.map +0 -1
  180. package/crawlers/statistics.js.map +0 -1
  181. package/enqueue_links/enqueue_links.d.ts.map +0 -1
  182. package/enqueue_links/enqueue_links.js.map +0 -1
  183. package/enqueue_links/index.d.ts.map +0 -1
  184. package/enqueue_links/index.js.map +0 -1
  185. package/enqueue_links/shared.d.ts.map +0 -1
  186. package/enqueue_links/shared.js.map +0 -1
  187. package/errors.d.ts.map +0 -1
  188. package/errors.js.map +0 -1
  189. package/events/event_manager.d.ts.map +0 -1
  190. package/events/event_manager.js.map +0 -1
  191. package/events/index.d.ts.map +0 -1
  192. package/events/index.js.map +0 -1
  193. package/events/local_event_manager.d.ts.map +0 -1
  194. package/events/local_event_manager.js.map +0 -1
  195. package/http_clients/base-http-client.d.ts +0 -134
  196. package/http_clients/base-http-client.d.ts.map +0 -1
  197. package/http_clients/base-http-client.js +0 -33
  198. package/http_clients/base-http-client.js.map +0 -1
  199. package/http_clients/form-data-like.d.ts +0 -67
  200. package/http_clients/form-data-like.d.ts.map +0 -1
  201. package/http_clients/form-data-like.js +0 -5
  202. package/http_clients/form-data-like.js.map +0 -1
  203. package/http_clients/got-scraping-http-client.d.ts +0 -15
  204. package/http_clients/got-scraping-http-client.d.ts.map +0 -1
  205. package/http_clients/got-scraping-http-client.js +0 -69
  206. package/http_clients/got-scraping-http-client.js.map +0 -1
  207. package/http_clients/index.d.ts +0 -3
  208. package/http_clients/index.d.ts.map +0 -1
  209. package/http_clients/index.js +0 -3
  210. package/http_clients/index.js.map +0 -1
  211. package/index.d.ts.map +0 -1
  212. package/index.js.map +0 -1
  213. package/log.d.ts.map +0 -1
  214. package/log.js.map +0 -1
  215. package/proxy_configuration.d.ts.map +0 -1
  216. package/proxy_configuration.js.map +0 -1
  217. package/request.d.ts.map +0 -1
  218. package/request.js.map +0 -1
  219. package/router.d.ts.map +0 -1
  220. package/router.js.map +0 -1
  221. package/serialization.d.ts.map +0 -1
  222. package/serialization.js.map +0 -1
  223. package/session_pool/consts.d.ts.map +0 -1
  224. package/session_pool/consts.js.map +0 -1
  225. package/session_pool/errors.d.ts.map +0 -1
  226. package/session_pool/errors.js.map +0 -1
  227. package/session_pool/events.d.ts +0 -3
  228. package/session_pool/events.d.ts.map +0 -1
  229. package/session_pool/events.js +0 -3
  230. package/session_pool/events.js.map +0 -1
  231. package/session_pool/index.d.ts.map +0 -1
  232. package/session_pool/index.js.map +0 -1
  233. package/session_pool/session.d.ts.map +0 -1
  234. package/session_pool/session.js.map +0 -1
  235. package/session_pool/session_pool.d.ts.map +0 -1
  236. package/session_pool/session_pool.js.map +0 -1
  237. package/storages/access_checking.d.ts.map +0 -1
  238. package/storages/access_checking.js.map +0 -1
  239. package/storages/dataset.d.ts.map +0 -1
  240. package/storages/dataset.js.map +0 -1
  241. package/storages/index.d.ts.map +0 -1
  242. package/storages/index.js.map +0 -1
  243. package/storages/key_value_store.d.ts.map +0 -1
  244. package/storages/key_value_store.js.map +0 -1
  245. package/storages/request_list.d.ts.map +0 -1
  246. package/storages/request_list.js.map +0 -1
  247. package/storages/request_provider.d.ts +0 -307
  248. package/storages/request_provider.d.ts.map +0 -1
  249. package/storages/request_provider.js +0 -555
  250. package/storages/request_provider.js.map +0 -1
  251. package/storages/request_queue.d.ts.map +0 -1
  252. package/storages/request_queue.js.map +0 -1
  253. package/storages/request_queue_v2.d.ts +0 -87
  254. package/storages/request_queue_v2.d.ts.map +0 -1
  255. package/storages/request_queue_v2.js +0 -438
  256. package/storages/request_queue_v2.js.map +0 -1
  257. package/storages/sitemap_request_list.d.ts.map +0 -1
  258. package/storages/sitemap_request_list.js.map +0 -1
  259. package/storages/storage_manager.d.ts +0 -58
  260. package/storages/storage_manager.d.ts.map +0 -1
  261. package/storages/storage_manager.js +0 -105
  262. package/storages/storage_manager.js.map +0 -1
  263. package/storages/utils.d.ts.map +0 -1
  264. package/storages/utils.js.map +0 -1
  265. package/tsconfig.build.tsbuildinfo +0 -1
  266. package/typedefs.d.ts.map +0 -1
  267. package/typedefs.js.map +0 -1
  268. package/validators.d.ts.map +0 -1
  269. package/validators.js.map +0 -1
@@ -1,44 +1,33 @@
1
+ import type { BaseHttpClient } from '@crawlee/types';
1
2
  import { type ParseSitemapOptions } from '@crawlee/utils';
2
- import { Configuration } from '../configuration.js';
3
- import type { GlobInput, RegExpInput } from '../enqueue_links/shared.js';
3
+ import type { UrlPatternInput } from '../enqueue_links/shared.js';
4
4
  import { Request } from '../request.js';
5
- import type { IRequestList } from './request_list.js';
5
+ import type { IRequestLoader } from './request_loader.js';
6
+ import type { IRequestManager } from './request_manager.js';
6
7
  interface UrlConstraints {
7
8
  /**
8
- * An array of glob pattern strings or plain objects
9
- * containing glob pattern strings matching the URLs to be enqueued.
9
+ * An array of URL patterns that URLs must match to be included.
10
10
  *
11
- * The plain objects must include at least the `glob` property, which holds the glob pattern string.
11
+ * Accepts glob pattern strings, `{ glob: string }` objects, `RegExp` instances, or `{ regexp: RegExp }` objects.
12
12
  *
13
- * The matching is always case-insensitive.
14
- * If you need case-sensitive matching, use `regexps` property directly.
13
+ * Glob matching is always case-insensitive.
14
+ * If you need case-sensitive matching, use a `RegExp`.
15
15
  *
16
- * If `globs` is an empty array or `undefined`, and `regexps` are also not defined, then the `SitemapRequestList`
16
+ * If `include` is an empty array or `undefined`, then the `SitemapRequestLoader`
17
17
  * includes all the URLs from the sitemap.
18
18
  */
19
- globs?: readonly GlobInput[];
19
+ include?: readonly UrlPatternInput[];
20
20
  /**
21
- * An array of glob pattern strings, regexp patterns or plain objects
22
- * containing patterns matching URLs that will **never** be included.
21
+ * An array of URL patterns. Matching URLs will **not** be included.
23
22
  *
24
- * The plain objects must include either the `glob` property or the `regexp` property.
23
+ * Accepts glob pattern strings, `{ glob: string }` objects, `RegExp` instances, or `{ regexp: RegExp }` objects.
25
24
  *
26
25
  * Glob matching is always case-insensitive.
27
- * If you need case-sensitive matching, provide a regexp.
26
+ * If you need case-sensitive matching, use a `RegExp`.
28
27
  */
29
- exclude?: readonly (GlobInput | RegExp)[];
30
- /**
31
- * An array of regular expressions or plain objects
32
- * containing regular expressions matching the URLs to be enqueued.
33
- *
34
- * The plain objects must include at least the `regexp` property, which holds the regular expression.
35
- *
36
- * If `regexps` is an empty array or `undefined`, and `globs` are also not defined, then the `SitemapRequestList`
37
- * includes all the URLs from the sitemap.
38
- */
39
- regexps?: readonly RegExpInput[];
28
+ exclude?: readonly UrlPatternInput[];
40
29
  }
41
- export interface SitemapRequestListOptions extends UrlConstraints {
30
+ export interface SitemapRequestLoaderOptions extends UrlConstraints {
42
31
  /**
43
32
  * List of sitemap URLs to parse.
44
33
  */
@@ -81,27 +70,25 @@ export interface SitemapRequestListOptions extends UrlConstraints {
81
70
  */
82
71
  parseSitemapOptions?: Omit<ParseSitemapOptions, 'emitNestedSitemaps' | 'maxDepth'>;
83
72
  /**
84
- * Crawlee configuration
73
+ * Custom HTTP client to be used for sitemap loading.
85
74
  */
86
- config?: Configuration;
75
+ httpClient?: BaseHttpClient;
87
76
  }
88
77
  /**
89
78
  * A list of URLs to crawl parsed from a sitemap.
90
79
  *
91
80
  * The loading of the sitemap is performed in the background so that crawling can start before the sitemap is fully loaded.
92
81
  */
93
- export declare class SitemapRequestList implements IRequestList {
82
+ export declare class SitemapRequestLoader implements IRequestLoader {
94
83
  /**
95
84
  * Set of URLs that were returned by `fetchNextRequest()` and not marked as handled yet.
96
85
  * @internal
97
86
  */
98
87
  inProgress: Set<string>;
99
- /** Set of URLs for which `reclaimRequest()` was called. */
100
- private reclaimed;
101
88
  /**
102
89
  * Map of returned Request objects that have not been marked as handled yet.
103
90
  *
104
- * We use this to persist custom user fields on the in-progress (or reclaimed) requests.
91
+ * We use this to persist custom user fields on the in-progress requests.
105
92
  */
106
93
  private requestData;
107
94
  /**
@@ -132,7 +119,7 @@ export declare class SitemapRequestList implements IRequestList {
132
119
  /**
133
120
  * Proxy URL to be used for sitemap loading.
134
121
  */
135
- private proxyUrl;
122
+ private proxyUrl?;
136
123
  /**
137
124
  * Logger instance.
138
125
  */
@@ -157,7 +144,7 @@ export declare class SitemapRequestList implements IRequestList {
157
144
  */
158
145
  private matchesUrl;
159
146
  /**
160
- * Checks whether the URL matches the `globs` / `regexps` / `exclude` provided in the `options`.
147
+ * Checks whether the URL matches the `include` / `exclude` patterns provided in the `options`.
161
148
  * @param url URL to be checked.
162
149
  * @returns `true` if the URL matches the patterns, `false` otherwise.
163
150
  */
@@ -190,15 +177,25 @@ export declare class SitemapRequestList implements IRequestList {
190
177
  /**
191
178
  * Open a sitemap and start processing it.
192
179
  *
193
- * Resolves to a new instance of `SitemapRequestList`, which **might not be fully loaded yet** - i.e. the sitemap might still be loading in the background.
180
+ * Resolves to a new instance of `SitemapRequestLoader`, which **might not be fully loaded yet** - i.e. the sitemap might still be loading in the background.
194
181
  *
195
182
  * Track the loading progress using the `isSitemapFullyLoaded` property.
196
183
  */
197
- static open(options: SitemapRequestListOptions): Promise<SitemapRequestList>;
184
+ static open(options: SitemapRequestLoaderOptions): Promise<SitemapRequestLoader>;
185
+ /**
186
+ * @inheritDoc
187
+ */
188
+ getTotalCount(): Promise<number>;
198
189
  /**
199
190
  * @inheritDoc
200
191
  */
201
- length(): number;
192
+ getPendingCount(): Promise<number>;
193
+ /**
194
+ * Combines this list with a request manager (a {@link RequestQueue} by default) into a
195
+ * {@link RequestManagerTandem}, allowing requests to be added and reclaimed while still
196
+ * being read from this list first.
197
+ */
198
+ toTandem(requestManager?: IRequestManager): Promise<IRequestManager>;
202
199
  /**
203
200
  * @inheritDoc
204
201
  */
@@ -210,7 +207,7 @@ export declare class SitemapRequestList implements IRequestList {
210
207
  /**
211
208
  * @inheritDoc
212
209
  */
213
- handledCount(): number;
210
+ getHandledCount(): Promise<number>;
214
211
  /**
215
212
  * @inheritDoc
216
213
  */
@@ -224,11 +221,7 @@ export declare class SitemapRequestList implements IRequestList {
224
221
  * @inheritDoc
225
222
  */
226
223
  // @ts-ignore optional peer dependency or compatibility with es2022
227
- [Symbol.asyncIterator](): AsyncGenerator<Request<import("@crawlee/utils").Dictionary>, void, unknown>;
228
- /**
229
- * @inheritDoc
230
- */
231
- reclaimRequest(request: Request): Promise<void>;
224
+ [Symbol.asyncIterator](): AsyncGenerator<Request<import("@crawlee/types").Dictionary>, void, unknown>;
232
225
  /**
233
226
  * Aborts the internal sitemap loading, stops the processing of the sitemap contents and drops all the pending URLs.
234
227
  *
@@ -238,8 +231,7 @@ export declare class SitemapRequestList implements IRequestList {
238
231
  /**
239
232
  * @inheritDoc
240
233
  */
241
- markRequestHandled(request: Request): Promise<void>;
242
- private ensureInProgressAndNotReclaimed;
234
+ markRequestAsHandled(request: Request): Promise<void>;
235
+ private ensureInProgress;
243
236
  }
244
237
  export {};
245
- //# sourceMappingURL=sitemap_request_list.d.ts.map
@@ -2,31 +2,28 @@ import { Transform } from 'node:stream';
2
2
  import { parseSitemap } from '@crawlee/utils';
3
3
  import { minimatch } from 'minimatch';
4
4
  import ow from 'ow';
5
- import defaultLog from '@apify/log';
6
- import { Configuration } from '../configuration.js';
7
- import { constructGlobObjectsFromGlobs, constructRegExpObjectsFromRegExps } from '../enqueue_links/shared.js';
5
+ import { constructUrlPatternObjects } from '../enqueue_links/shared.js';
8
6
  import { Request } from '../request.js';
7
+ import { serviceLocator } from '../service_locator.js';
9
8
  import { KeyValueStore } from './key_value_store.js';
10
9
  import { purgeDefaultStorages } from './utils.js';
11
10
  /** @internal */
12
- const STATE_PERSISTENCE_KEY = 'SITEMAP_REQUEST_LIST_STATE';
11
+ const STATE_PERSISTENCE_KEY = 'SITEMAP_REQUEST_LOADER_STATE';
13
12
  /**
14
13
  * A list of URLs to crawl parsed from a sitemap.
15
14
  *
16
15
  * The loading of the sitemap is performed in the background so that crawling can start before the sitemap is fully loaded.
17
16
  */
18
- export class SitemapRequestList {
17
+ export class SitemapRequestLoader {
19
18
  /**
20
19
  * Set of URLs that were returned by `fetchNextRequest()` and not marked as handled yet.
21
20
  * @internal
22
21
  */
23
22
  inProgress = new Set();
24
- /** Set of URLs for which `reclaimRequest()` was called. */
25
- reclaimed = new Set();
26
23
  /**
27
24
  * Map of returned Request objects that have not been marked as handled yet.
28
25
  *
29
- * We use this to persist custom user fields on the in-progress (or reclaimed) requests.
26
+ * We use this to persist custom user fields on the in-progress requests.
30
27
  */
31
28
  requestData = new Map();
32
29
  /**
@@ -74,7 +71,7 @@ export class SitemapRequestList {
74
71
  /**
75
72
  * Logger instance.
76
73
  */
77
- log = defaultLog.child({ prefix: 'SitemapRequestList' });
74
+ log;
78
75
  urlExcludePatternObjects = [];
79
76
  urlPatternObjects = [];
80
77
  /** EventManager used to handle persistence */
@@ -82,6 +79,7 @@ export class SitemapRequestList {
82
79
  persistenceOptions;
83
80
  /** @internal */
84
81
  constructor(options) {
82
+ const urlPatternValidator = ow.any(ow.string, ow.regExp, ow.object.hasKeys('glob'), ow.object.hasKeys('regexp'));
85
83
  ow(options, ow.object.exactShape({
86
84
  sitemapUrls: ow.array.ofType(ow.string),
87
85
  proxyUrl: ow.optional.string,
@@ -90,35 +88,25 @@ export class SitemapRequestList {
90
88
  timeoutMillis: ow.optional.number,
91
89
  maxBufferSize: ow.optional.number,
92
90
  parseSitemapOptions: ow.optional.object,
93
- globs: ow.optional.array.ofType(ow.any(ow.string, ow.object.hasKeys('glob'))),
94
- exclude: ow.optional.array.ofType(ow.any(ow.string, ow.regExp, ow.object.hasKeys('glob'), ow.object.hasKeys('regexp'))),
95
- regexps: ow.optional.array.ofType(ow.any(ow.regExp, ow.object.hasKeys('regexp'))),
96
- config: ow.optional.object,
91
+ include: ow.optional.array.ofType(urlPatternValidator),
92
+ exclude: ow.optional.array.ofType(urlPatternValidator),
97
93
  persistenceOptions: ow.optional.object,
94
+ httpClient: ow.optional.object,
98
95
  }));
99
- const { globs, exclude, regexps, config = Configuration.getGlobalConfig() } = options;
96
+ const { include, exclude } = options;
97
+ this.log = serviceLocator.getLogger().child({ prefix: 'SitemapRequestLoader' });
100
98
  if (exclude?.length) {
101
- for (const excl of exclude) {
102
- if (typeof excl === 'string' || 'glob' in excl) {
103
- this.urlExcludePatternObjects.push(...constructGlobObjectsFromGlobs([excl]));
104
- }
105
- else if (excl instanceof RegExp || 'regexp' in excl) {
106
- this.urlExcludePatternObjects.push(...constructRegExpObjectsFromRegExps([excl]));
107
- }
108
- }
99
+ this.urlExcludePatternObjects.push(...constructUrlPatternObjects(exclude));
109
100
  }
110
- if (globs?.length) {
111
- this.urlPatternObjects.push(...constructGlobObjectsFromGlobs(globs));
112
- }
113
- if (regexps?.length) {
114
- this.urlPatternObjects.push(...constructRegExpObjectsFromRegExps(regexps));
101
+ if (include?.length) {
102
+ this.urlPatternObjects.push(...constructUrlPatternObjects(include));
115
103
  }
116
104
  this.persistStateKey = options.persistStateKey;
117
105
  this.persistenceOptions = { enable: true, ...options.persistenceOptions };
118
106
  this.proxyUrl = options.proxyUrl;
119
107
  this.urlQueueStream = this.createNewStream(options.maxBufferSize ?? 200);
120
108
  this.sitemapParsingProgress.pendingSitemapUrls = new Set(options.sitemapUrls);
121
- this.events = config.getEventManager();
109
+ this.events = serviceLocator.getEventManager();
122
110
  this.persistState = this.persistState.bind(this);
123
111
  }
124
112
  /**
@@ -146,7 +134,7 @@ export class SitemapRequestList {
146
134
  };
147
135
  }
148
136
  /**
149
- * Checks whether the URL matches the `globs` / `regexps` / `exclude` provided in the `options`.
137
+ * Checks whether the URL matches the `include` / `exclude` patterns provided in the `options`.
150
138
  * @param url URL to be checked.
151
139
  * @returns `true` if the URL matches the patterns, `false` otherwise.
152
140
  */
@@ -248,17 +236,20 @@ export class SitemapRequestList {
248
236
  /**
249
237
  * Open a sitemap and start processing it.
250
238
  *
251
- * Resolves to a new instance of `SitemapRequestList`, which **might not be fully loaded yet** - i.e. the sitemap might still be loading in the background.
239
+ * Resolves to a new instance of `SitemapRequestLoader`, which **might not be fully loaded yet** - i.e. the sitemap might still be loading in the background.
252
240
  *
253
241
  * Track the loading progress using the `isSitemapFullyLoaded` property.
254
242
  */
255
243
  static async open(options) {
256
- const requestList = new SitemapRequestList({
257
- ...options,
244
+ const { httpClient, ...restOptions } = options;
245
+ const requestList = new SitemapRequestLoader({
246
+ ...restOptions,
258
247
  persistStateKey: options.persistStateKey ?? STATE_PERSISTENCE_KEY,
259
248
  });
260
249
  await requestList.restoreState();
261
- void requestList.load({ parseSitemapOptions: options.parseSitemapOptions });
250
+ void requestList.load({
251
+ parseSitemapOptions: { logger: serviceLocator.getLogger(), ...options.parseSitemapOptions, httpClient },
252
+ });
262
253
  if (requestList.persistenceOptions.enable) {
263
254
  requestList.events.on("persistState" /* EventType.PERSIST_STATE */, requestList.persistState);
264
255
  }
@@ -275,8 +266,28 @@ export class SitemapRequestList {
275
266
  /**
276
267
  * @inheritDoc
277
268
  */
278
- length() {
279
- return this.urlQueueStream.readableLength + this.handledUrlCount - this.inProgress.size - this.reclaimed.size;
269
+ async getTotalCount() {
270
+ // Total known so far = not-yet-fetched (still buffered in the stream) + in-progress (fetched but not
271
+ // yet handled) + already handled.
272
+ return this.urlQueueStream.readableLength + this.inProgress.size + this.handledUrlCount;
273
+ }
274
+ /**
275
+ * @inheritDoc
276
+ */
277
+ async getPendingCount() {
278
+ // Pending = everything not yet handled = not-yet-fetched + in-progress.
279
+ return this.urlQueueStream.readableLength + this.inProgress.size;
280
+ }
281
+ /**
282
+ * Combines this list with a request manager (a {@link RequestQueue} by default) into a
283
+ * {@link RequestManagerTandem}, allowing requests to be added and reclaimed while still
284
+ * being read from this list first.
285
+ */
286
+ async toTandem(requestManager) {
287
+ // Import here to avoid circular imports.
288
+ const { RequestManagerTandem } = await import('./request_manager_tandem.js');
289
+ const { RequestQueue } = await import('./request_queue.js');
290
+ return new RequestManagerTandem(this, requestManager ?? (await RequestQueue.open()));
280
291
  }
281
292
  /**
282
293
  * @inheritDoc
@@ -288,12 +299,12 @@ export class SitemapRequestList {
288
299
  * @inheritDoc
289
300
  */
290
301
  async isEmpty() {
291
- return this.reclaimed.size === 0 && this.urlQueueStream.readableLength === 0;
302
+ return this.urlQueueStream.readableLength === 0;
292
303
  }
293
304
  /**
294
305
  * @inheritDoc
295
306
  */
296
- handledCount() {
307
+ async getHandledCount() {
297
308
  return this.handledUrlCount;
298
309
  }
299
310
  /**
@@ -328,8 +339,8 @@ export class SitemapRequestList {
328
339
  inProgressSitemapUrl: this.sitemapParsingProgress.inProgressSitemapUrl,
329
340
  inProgressEntries: Array.from(this.sitemapParsingProgress.inProgressEntries),
330
341
  },
331
- urlQueue,
332
- reclaimed: [...this.inProgress, ...this.reclaimed], // In-progress and reclaimed requests will be both retried if state is restored
342
+ // Re-queue in-progress requests to the front so they are retried if the state is restored.
343
+ urlQueue: [...this.inProgress, ...urlQueue],
333
344
  requestData: Array.from(this.requestData.entries()),
334
345
  abortLoading: this.abortLoading,
335
346
  closed: this.closed,
@@ -345,7 +356,6 @@ export class SitemapRequestList {
345
356
  if (state === null) {
346
357
  return;
347
358
  }
348
- this.reclaimed = new Set(state.reclaimed);
349
359
  this.sitemapParsingProgress = {
350
360
  pendingSitemapUrls: new Set(state.sitemapParsingProgress.pendingSitemapUrls),
351
361
  inProgressSitemapUrl: state.sitemapParsingProgress.inProgressSitemapUrl,
@@ -362,17 +372,12 @@ export class SitemapRequestList {
362
372
  * @inheritDoc
363
373
  */
364
374
  async fetchNextRequest() {
365
- // Try to return a reclaimed request first
366
- let nextUrl = this.reclaimed.values().next().value;
367
- if (nextUrl) {
368
- this.reclaimed.delete(nextUrl);
375
+ const nextUrl = await this.readNextUrl();
376
+ if (!nextUrl) {
377
+ return null;
369
378
  }
370
- else {
371
- // Otherwise read next url from the stream
372
- nextUrl = await this.readNextUrl();
373
- if (!nextUrl) {
374
- return null;
375
- }
379
+ // A restored in-progress request already has its Request data; don't overwrite it.
380
+ if (!this.requestData.has(nextUrl)) {
376
381
  this.requestData.set(nextUrl, new Request({ url: nextUrl }));
377
382
  }
378
383
  this.inProgress.add(nextUrl);
@@ -389,14 +394,6 @@ export class SitemapRequestList {
389
394
  yield request;
390
395
  }
391
396
  }
392
- /**
393
- * @inheritDoc
394
- */
395
- async reclaimRequest(request) {
396
- this.ensureInProgressAndNotReclaimed(request.url);
397
- this.reclaimed.add(request.url);
398
- this.inProgress.delete(request.url);
399
- }
400
397
  /**
401
398
  * Aborts the internal sitemap loading, stops the processing of the sitemap contents and drops all the pending URLs.
402
399
  *
@@ -412,19 +409,15 @@ export class SitemapRequestList {
412
409
  /**
413
410
  * @inheritDoc
414
411
  */
415
- async markRequestHandled(request) {
412
+ async markRequestAsHandled(request) {
416
413
  this.handledUrlCount += 1;
417
- this.ensureInProgressAndNotReclaimed(request.url);
414
+ this.ensureInProgress(request.url);
418
415
  this.inProgress.delete(request.url);
419
416
  this.requestData.delete(request.url);
420
417
  }
421
- ensureInProgressAndNotReclaimed(url) {
418
+ ensureInProgress(url) {
422
419
  if (!this.inProgress.has(url)) {
423
420
  throw new Error(`The request is not being processed (url: ${url})`);
424
421
  }
425
- if (this.reclaimed.has(url)) {
426
- throw new Error(`The request was already reclaimed (url: ${url})`);
427
- }
428
422
  }
429
423
  }
430
- //# sourceMappingURL=sitemap_request_list.js.map
@@ -0,0 +1,88 @@
1
+ import type { Constructor, DatasetBackend, KeyValueStoreBackend, RequestQueueBackend, StorageBackend, StorageIdentifier } from '@crawlee/types';
2
+ export type { StorageIdentifier } from '@crawlee/types';
3
+ /**
4
+ * Matches an `IStorage` – a storage "frontend" (Dataset, KeyValueStore, RequestQueue).
5
+ */
6
+ export interface IStorage {
7
+ id: string;
8
+ name?: string;
9
+ }
10
+ type Hashable = string;
11
+ /**
12
+ * Unified manager for opening and caching storage instances (Dataset, KeyValueStore, RequestQueue).
13
+ *
14
+ * A single instance manages all storage types. Instances are cached by
15
+ * `(storageClass, id/name/alias, backendCacheKey)` so the same storage is never opened twice.
16
+ *
17
+ * The manager itself does not resolve identifiers — callers pass explicit `id`, `name`, or `alias` (at most one),
18
+ * and a pre-bound `backendOpener` promise. When none of `id`, `name`, `alias` are provided, the manager automatically
19
+ * assigns a reserved default alias.
20
+ */
21
+ export declare class StorageInstanceManager {
22
+ private readonly cache;
23
+ private readonly openerLocks;
24
+ /**
25
+ * Open (or retrieve from cache) a storage instance.
26
+ *
27
+ * @param cls The storage class constructor (e.g. `Dataset`, `KeyValueStore`, `RequestQueue`).
28
+ * @param id Storage ID (mutually exclusive with `name` and `alias`).
29
+ * @param name Storage name (mutually exclusive with `id` and `alias`).
30
+ * @param alias Run-scoped alias (mutually exclusive with `id` and `name`).
31
+ * Automatically assigned when no identifier is provided.
32
+ * @param backendOpener A **lazy** factory that creates the sub-backend.
33
+ * Only called on a cache miss.
34
+ * @param backendCacheKey Opaque key identifying the storage backend, so that the same logical
35
+ * storage opened through different clients is cached separately.
36
+ */
37
+ openStorage<TStorage extends IStorage>(cls: Constructor<TStorage>, { id, name, alias, backendOpener, backendCacheKey, }: (ExplicitStorageIdentifier | DefaultStorageIdentifier) & {
38
+ backendOpener: () => Promise<DatasetBackend | KeyValueStoreBackend | RequestQueueBackend>;
39
+ backendCacheKey: Hashable;
40
+ }): Promise<TStorage>;
41
+ /**
42
+ * Remove a storage instance from the cache (called from `storage.drop()`).
43
+ */
44
+ removeFromCache(instance: IStorage): void;
45
+ /**
46
+ * Clear the entire cache. Also calls `clearCache()` on any cached KeyValueStore
47
+ * instances (duck-typed to avoid importing KeyValueStore and circular dependencies).
48
+ * Called during service locator reset.
49
+ */
50
+ clearCache(): void;
51
+ }
52
+ /**
53
+ * A storage identifier where exactly one of `id`, `name`, or `alias` is specified.
54
+ * Produced by {@link resolveStorageIdentifier} from ambiguous user input.
55
+ */
56
+ export type ExplicitStorageIdentifier = {
57
+ id: string;
58
+ name?: never;
59
+ alias?: never;
60
+ } | {
61
+ id?: never;
62
+ name: string;
63
+ alias?: never;
64
+ } | {
65
+ id?: never;
66
+ name?: never;
67
+ alias: string;
68
+ };
69
+ /**
70
+ * Represents the case where no identifier was provided — the caller wants the default storage.
71
+ */
72
+ export interface DefaultStorageIdentifier {
73
+ id?: never;
74
+ name?: never;
75
+ alias?: never;
76
+ }
77
+ /**
78
+ * Decompose a user-provided `identifier` (the `Dataset.open()` / `KeyValueStore.open()` /
79
+ * `RequestQueue.open()` argument) into separate `id`, `name`, and `alias` fields that
80
+ * the `StorageInstanceManager` and `StorageBackend.create*Client` expect.
81
+ *
82
+ * - `null` / `undefined` / `{}` → default storage alias
83
+ * - `string` → resolved via `storageExists` (ID-first, then name)
84
+ * - `{ id }` → `{ id }`
85
+ * - `{ name }` → `{ name }`
86
+ * - `{ alias }` → `{ alias }`
87
+ */
88
+ export declare function resolveStorageIdentifier(identifier: string | StorageIdentifier | null | undefined, storageBackend: StorageBackend, storageType: 'Dataset' | 'KeyValueStore' | 'RequestQueue'): Promise<ExplicitStorageIdentifier>;