@crawlee/core 4.0.0-beta.17 → 4.0.0-beta.171

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 (270) hide show
  1. package/README.md +14 -14
  2. package/byte_utils.d.ts +17 -0
  3. package/byte_utils.js +42 -0
  4. package/configuration.d.ts +96 -223
  5. package/configuration.js +170 -222
  6. package/debug.d.ts +36 -0
  7. package/debug.js +70 -0
  8. package/errors.d.ts +40 -19
  9. package/errors.js +53 -28
  10. package/events/event_manager.d.ts +35 -9
  11. package/events/event_manager.js +12 -13
  12. package/events/index.d.ts +1 -1
  13. package/events/index.js +0 -1
  14. package/events/local_event_manager.d.ts +15 -3
  15. package/events/local_event_manager.js +39 -13
  16. package/events/system_info.d.ts +38 -0
  17. package/events/system_info.js +1 -0
  18. package/index.d.ts +7 -11
  19. package/index.js +8 -10
  20. package/internal.d.ts +8 -0
  21. package/internal.js +9 -0
  22. package/iterables.d.ts +79 -0
  23. package/iterables.js +134 -0
  24. package/log.d.ts +77 -1
  25. package/log.js +134 -1
  26. package/memory-storage/consts.d.ts +4 -0
  27. package/memory-storage/consts.js +4 -0
  28. package/memory-storage/index.d.ts +1 -0
  29. package/memory-storage/index.js +1 -0
  30. package/memory-storage/memory-storage.d.ts +44 -0
  31. package/memory-storage/memory-storage.js +160 -0
  32. package/memory-storage/resource-clients/common/base-client.d.ts +4 -0
  33. package/memory-storage/resource-clients/common/base-client.js +6 -0
  34. package/memory-storage/resource-clients/dataset.d.ts +40 -0
  35. package/memory-storage/resource-clients/dataset.js +106 -0
  36. package/memory-storage/resource-clients/key-value-store.d.ts +63 -0
  37. package/memory-storage/resource-clients/key-value-store.js +199 -0
  38. package/memory-storage/resource-clients/request-queue.d.ts +77 -0
  39. package/memory-storage/resource-clients/request-queue.js +414 -0
  40. package/memory-storage/utils.d.ts +16 -0
  41. package/memory-storage/utils.js +41 -0
  42. package/owned_or_injected.d.ts +58 -0
  43. package/owned_or_injected.js +98 -0
  44. package/package.json +18 -19
  45. package/proxy_configuration.d.ts +22 -128
  46. package/proxy_configuration.js +32 -144
  47. package/recoverable_state.d.ts +84 -51
  48. package/recoverable_state.js +175 -72
  49. package/request.d.ts +60 -17
  50. package/request.js +130 -69
  51. package/serialization.d.ts +0 -1
  52. package/serialization.js +15 -15
  53. package/service_locator.d.ts +165 -0
  54. package/service_locator.js +253 -0
  55. package/storages/batched_adds.d.ts +37 -0
  56. package/storages/batched_adds.js +73 -0
  57. package/storages/dataset.d.ts +114 -56
  58. package/storages/dataset.js +292 -149
  59. package/storages/index.d.ts +7 -9
  60. package/storages/index.js +5 -9
  61. package/storages/key_value_store.d.ts +186 -48
  62. package/storages/key_value_store.js +452 -170
  63. package/storages/key_value_store_codec.d.ts +32 -0
  64. package/storages/key_value_store_codec.js +113 -0
  65. package/storages/request_dedup_cache.d.ts +22 -0
  66. package/storages/request_dedup_cache.js +48 -0
  67. package/storages/request_list.d.ts +54 -129
  68. package/storages/request_list.js +272 -245
  69. package/storages/request_loader.d.ts +133 -0
  70. package/storages/request_loader.js +36 -0
  71. package/storages/request_manager.d.ts +109 -0
  72. package/storages/request_manager.js +1 -0
  73. package/storages/request_manager_tandem.d.ts +55 -23
  74. package/storages/request_manager_tandem.js +139 -57
  75. package/storages/request_queue.d.ts +286 -48
  76. package/storages/request_queue.js +757 -218
  77. package/storages/storage_instance_manager.d.ts +87 -0
  78. package/storages/storage_instance_manager.js +256 -0
  79. package/storages/storage_stats.d.ts +48 -0
  80. package/storages/storage_stats.js +29 -0
  81. package/storages/transaction.d.ts +260 -0
  82. package/storages/transaction.js +287 -0
  83. package/storages/utils.d.ts +59 -11
  84. package/storages/utils.js +75 -15
  85. package/system-info/cpu-info.d.ts +67 -0
  86. package/system-info/cpu-info.js +216 -0
  87. package/system-info/memory-info.d.ts +31 -0
  88. package/system-info/memory-info.js +115 -0
  89. package/system-info/ps-tree.d.ts +17 -0
  90. package/system-info/ps-tree.js +144 -0
  91. package/system-info/runtime.d.ts +14 -0
  92. package/system-info/runtime.js +80 -0
  93. package/typedefs.d.ts +0 -6
  94. package/typedefs.js +0 -1
  95. package/url.d.ts +9 -0
  96. package/url.js +11 -0
  97. package/validators.d.ts +23 -18
  98. package/validators.js +14 -18
  99. package/autoscaling/autoscaled_pool.d.ts +0 -300
  100. package/autoscaling/autoscaled_pool.d.ts.map +0 -1
  101. package/autoscaling/autoscaled_pool.js +0 -533
  102. package/autoscaling/autoscaled_pool.js.map +0 -1
  103. package/autoscaling/index.d.ts +0 -4
  104. package/autoscaling/index.d.ts.map +0 -1
  105. package/autoscaling/index.js +0 -4
  106. package/autoscaling/index.js.map +0 -1
  107. package/autoscaling/snapshotter.d.ts +0 -189
  108. package/autoscaling/snapshotter.d.ts.map +0 -1
  109. package/autoscaling/snapshotter.js +0 -285
  110. package/autoscaling/snapshotter.js.map +0 -1
  111. package/autoscaling/system_status.d.ts +0 -181
  112. package/autoscaling/system_status.d.ts.map +0 -1
  113. package/autoscaling/system_status.js +0 -169
  114. package/autoscaling/system_status.js.map +0 -1
  115. package/configuration.d.ts.map +0 -1
  116. package/configuration.js.map +0 -1
  117. package/cookie_utils.d.ts +0 -43
  118. package/cookie_utils.d.ts.map +0 -1
  119. package/cookie_utils.js +0 -111
  120. package/cookie_utils.js.map +0 -1
  121. package/crawlers/context_pipeline.d.ts +0 -61
  122. package/crawlers/context_pipeline.d.ts.map +0 -1
  123. package/crawlers/context_pipeline.js +0 -99
  124. package/crawlers/context_pipeline.js.map +0 -1
  125. package/crawlers/crawler_commons.d.ts +0 -195
  126. package/crawlers/crawler_commons.d.ts.map +0 -1
  127. package/crawlers/crawler_commons.js +0 -108
  128. package/crawlers/crawler_commons.js.map +0 -1
  129. package/crawlers/crawler_utils.d.ts +0 -10
  130. package/crawlers/crawler_utils.d.ts.map +0 -1
  131. package/crawlers/crawler_utils.js +0 -12
  132. package/crawlers/crawler_utils.js.map +0 -1
  133. package/crawlers/error_snapshotter.d.ts +0 -60
  134. package/crawlers/error_snapshotter.d.ts.map +0 -1
  135. package/crawlers/error_snapshotter.js +0 -118
  136. package/crawlers/error_snapshotter.js.map +0 -1
  137. package/crawlers/error_tracker.d.ts +0 -55
  138. package/crawlers/error_tracker.d.ts.map +0 -1
  139. package/crawlers/error_tracker.js +0 -309
  140. package/crawlers/error_tracker.js.map +0 -1
  141. package/crawlers/index.d.ts +0 -7
  142. package/crawlers/index.d.ts.map +0 -1
  143. package/crawlers/index.js +0 -7
  144. package/crawlers/index.js.map +0 -1
  145. package/crawlers/internals/types.d.ts +0 -8
  146. package/crawlers/internals/types.d.ts.map +0 -1
  147. package/crawlers/internals/types.js +0 -2
  148. package/crawlers/internals/types.js.map +0 -1
  149. package/crawlers/statistics.d.ts +0 -204
  150. package/crawlers/statistics.d.ts.map +0 -1
  151. package/crawlers/statistics.js +0 -346
  152. package/crawlers/statistics.js.map +0 -1
  153. package/enqueue_links/enqueue_links.d.ts +0 -249
  154. package/enqueue_links/enqueue_links.d.ts.map +0 -1
  155. package/enqueue_links/enqueue_links.js +0 -269
  156. package/enqueue_links/enqueue_links.js.map +0 -1
  157. package/enqueue_links/index.d.ts +0 -3
  158. package/enqueue_links/index.d.ts.map +0 -1
  159. package/enqueue_links/index.js +0 -3
  160. package/enqueue_links/index.js.map +0 -1
  161. package/enqueue_links/shared.d.ts +0 -73
  162. package/enqueue_links/shared.d.ts.map +0 -1
  163. package/enqueue_links/shared.js +0 -212
  164. package/enqueue_links/shared.js.map +0 -1
  165. package/errors.d.ts.map +0 -1
  166. package/errors.js.map +0 -1
  167. package/events/event_manager.d.ts.map +0 -1
  168. package/events/event_manager.js.map +0 -1
  169. package/events/index.d.ts.map +0 -1
  170. package/events/index.js.map +0 -1
  171. package/events/local_event_manager.d.ts.map +0 -1
  172. package/events/local_event_manager.js.map +0 -1
  173. package/http_clients/base-http-client.d.ts +0 -140
  174. package/http_clients/base-http-client.d.ts.map +0 -1
  175. package/http_clients/base-http-client.js +0 -40
  176. package/http_clients/base-http-client.js.map +0 -1
  177. package/http_clients/form-data-like.d.ts +0 -67
  178. package/http_clients/form-data-like.d.ts.map +0 -1
  179. package/http_clients/form-data-like.js +0 -5
  180. package/http_clients/form-data-like.js.map +0 -1
  181. package/http_clients/got-scraping-http-client.d.ts +0 -20
  182. package/http_clients/got-scraping-http-client.d.ts.map +0 -1
  183. package/http_clients/got-scraping-http-client.js +0 -85
  184. package/http_clients/got-scraping-http-client.js.map +0 -1
  185. package/http_clients/index.d.ts +0 -3
  186. package/http_clients/index.d.ts.map +0 -1
  187. package/http_clients/index.js +0 -3
  188. package/http_clients/index.js.map +0 -1
  189. package/index.d.ts.map +0 -1
  190. package/index.js.map +0 -1
  191. package/log.d.ts.map +0 -1
  192. package/log.js.map +0 -1
  193. package/proxy_configuration.d.ts.map +0 -1
  194. package/proxy_configuration.js.map +0 -1
  195. package/recoverable_state.d.ts.map +0 -1
  196. package/recoverable_state.js.map +0 -1
  197. package/request.d.ts.map +0 -1
  198. package/request.js.map +0 -1
  199. package/router.d.ts +0 -134
  200. package/router.d.ts.map +0 -1
  201. package/router.js +0 -164
  202. package/router.js.map +0 -1
  203. package/serialization.d.ts.map +0 -1
  204. package/serialization.js.map +0 -1
  205. package/session_pool/consts.d.ts +0 -4
  206. package/session_pool/consts.d.ts.map +0 -1
  207. package/session_pool/consts.js +0 -4
  208. package/session_pool/consts.js.map +0 -1
  209. package/session_pool/errors.d.ts +0 -8
  210. package/session_pool/errors.d.ts.map +0 -1
  211. package/session_pool/errors.js +0 -12
  212. package/session_pool/errors.js.map +0 -1
  213. package/session_pool/events.d.ts +0 -3
  214. package/session_pool/events.d.ts.map +0 -1
  215. package/session_pool/events.js +0 -3
  216. package/session_pool/events.js.map +0 -1
  217. package/session_pool/index.d.ts +0 -6
  218. package/session_pool/index.d.ts.map +0 -1
  219. package/session_pool/index.js +0 -6
  220. package/session_pool/index.js.map +0 -1
  221. package/session_pool/session.d.ts +0 -203
  222. package/session_pool/session.d.ts.map +0 -1
  223. package/session_pool/session.js +0 -278
  224. package/session_pool/session.js.map +0 -1
  225. package/session_pool/session_pool.d.ts +0 -258
  226. package/session_pool/session_pool.d.ts.map +0 -1
  227. package/session_pool/session_pool.js +0 -387
  228. package/session_pool/session_pool.js.map +0 -1
  229. package/storages/access_checking.d.ts +0 -13
  230. package/storages/access_checking.d.ts.map +0 -1
  231. package/storages/access_checking.js +0 -14
  232. package/storages/access_checking.js.map +0 -1
  233. package/storages/dataset.d.ts.map +0 -1
  234. package/storages/dataset.js.map +0 -1
  235. package/storages/index.d.ts.map +0 -1
  236. package/storages/index.js.map +0 -1
  237. package/storages/key_value_store.d.ts.map +0 -1
  238. package/storages/key_value_store.js.map +0 -1
  239. package/storages/request_list.d.ts.map +0 -1
  240. package/storages/request_list.js.map +0 -1
  241. package/storages/request_list_adapter.d.ts +0 -58
  242. package/storages/request_list_adapter.d.ts.map +0 -1
  243. package/storages/request_list_adapter.js +0 -81
  244. package/storages/request_list_adapter.js.map +0 -1
  245. package/storages/request_manager_tandem.d.ts.map +0 -1
  246. package/storages/request_manager_tandem.js.map +0 -1
  247. package/storages/request_provider.d.ts +0 -371
  248. package/storages/request_provider.d.ts.map +0 -1
  249. package/storages/request_provider.js +0 -585
  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 +0 -245
  258. package/storages/sitemap_request_list.d.ts.map +0 -1
  259. package/storages/sitemap_request_list.js +0 -430
  260. package/storages/sitemap_request_list.js.map +0 -1
  261. package/storages/storage_manager.d.ts +0 -58
  262. package/storages/storage_manager.d.ts.map +0 -1
  263. package/storages/storage_manager.js +0 -105
  264. package/storages/storage_manager.js.map +0 -1
  265. package/storages/utils.d.ts.map +0 -1
  266. package/storages/utils.js.map +0 -1
  267. package/typedefs.d.ts.map +0 -1
  268. package/typedefs.js.map +0 -1
  269. package/validators.d.ts.map +0 -1
  270. package/validators.js.map +0 -1
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Canonical write path for key-value store records.
3
+ *
4
+ * When a content type is provided, the value passes through unchanged — it is the caller's
5
+ * responsibility to supply a String/Buffer/Stream (the frontend validates this).
6
+ *
7
+ * When no content type is provided, it is inferred from the value's shape:
8
+ * - Buffer / typed array / ArrayBuffer / stream → `application/octet-stream` (passthrough)
9
+ * - `string` → `text/plain; charset=utf-8` (passthrough)
10
+ * - anything else → `application/json; charset=utf-8` (serialized via `jsonStringifyExtended`)
11
+ *
12
+ * Does NOT drain streams — that is storage mechanics and stays in the storage backend.
13
+ *
14
+ * Backend-independent.
15
+ */
16
+ export declare function serializeValue(value: unknown, contentType?: string): {
17
+ value: Buffer | ArrayBuffer | ArrayBufferView | string | NodeJS.ReadableStream | ReadableStream;
18
+ contentType: string;
19
+ };
20
+ /**
21
+ * Parses a Buffer or ArrayBuffer using the provided content type header.
22
+ *
23
+ * - application/json is returned as a parsed object.
24
+ * - application/*xml and text/* are returned as strings.
25
+ * - everything else is returned as original body.
26
+ *
27
+ * If the header includes a charset, the body will be stringified only
28
+ * if the charset represents a known encoding to Node.js or Browser.
29
+ *
30
+ * Backend-independent — this is the canonical read path for the {@link KeyValueStore} frontend.
31
+ */
32
+ export declare function parseValue(body: Buffer | ArrayBuffer | string, contentTypeHeader: string | null): string | Buffer | ArrayBuffer | Record<string, unknown>;
@@ -0,0 +1,113 @@
1
+ import contentTypeParser from 'content-type';
2
+ import JSON5 from 'json5';
3
+ import { jsonStringifyExtended } from '@apify/utilities';
4
+ import { isBuffer, isStream } from '../byte_utils.js';
5
+ const CONTENT_TYPE_JSON = 'application/json';
6
+ const STRINGIFIABLE_CONTENT_TYPE_RXS = [new RegExp(`^${CONTENT_TYPE_JSON}$`, 'i'), /^application\/.*xml$/i, /^text\//i];
7
+ /**
8
+ * Canonical write path for key-value store records.
9
+ *
10
+ * When a content type is provided, the value passes through unchanged — it is the caller's
11
+ * responsibility to supply a String/Buffer/Stream (the frontend validates this).
12
+ *
13
+ * When no content type is provided, it is inferred from the value's shape:
14
+ * - Buffer / typed array / ArrayBuffer / stream → `application/octet-stream` (passthrough)
15
+ * - `string` → `text/plain; charset=utf-8` (passthrough)
16
+ * - anything else → `application/json; charset=utf-8` (serialized via `jsonStringifyExtended`)
17
+ *
18
+ * Does NOT drain streams — that is storage mechanics and stays in the storage backend.
19
+ *
20
+ * Backend-independent.
21
+ */
22
+ export function serializeValue(value, contentType) {
23
+ if (contentType !== null && contentType !== undefined) {
24
+ return { value: value, contentType };
25
+ }
26
+ if (isStream(value) || isBuffer(value)) {
27
+ return {
28
+ value,
29
+ contentType: 'application/octet-stream',
30
+ };
31
+ }
32
+ if (typeof value === 'string') {
33
+ return { value, contentType: 'text/plain; charset=utf-8' };
34
+ }
35
+ let serialized;
36
+ try {
37
+ // Format JSON to simplify debugging, the overheads with compression is negligible
38
+ serialized = jsonStringifyExtended(value, null, 2);
39
+ }
40
+ catch (e) {
41
+ const error = e;
42
+ // Give more meaningful error message
43
+ if (error.message?.includes('Invalid string length')) {
44
+ error.message = 'Object is too large';
45
+ }
46
+ throw new Error(`The "value" parameter cannot be stringified to JSON: ${error.message}`);
47
+ }
48
+ if (serialized === undefined) {
49
+ throw new Error('The "value" parameter was stringified to JSON and returned undefined. ' +
50
+ "Make sure you're not trying to stringify an undefined value.");
51
+ }
52
+ return { value: serialized, contentType: 'application/json; charset=utf-8' };
53
+ }
54
+ /**
55
+ * Parses a Buffer or ArrayBuffer using the provided content type header.
56
+ *
57
+ * - application/json is returned as a parsed object.
58
+ * - application/*xml and text/* are returned as strings.
59
+ * - everything else is returned as original body.
60
+ *
61
+ * If the header includes a charset, the body will be stringified only
62
+ * if the charset represents a known encoding to Node.js or Browser.
63
+ *
64
+ * Backend-independent — this is the canonical read path for the {@link KeyValueStore} frontend.
65
+ */
66
+ export function parseValue(body, contentTypeHeader) {
67
+ // No content type at all → we have no basis for interpretation; hand back the raw value.
68
+ if (contentTypeHeader === null)
69
+ return body;
70
+ let contentType;
71
+ let charset;
72
+ try {
73
+ const result = contentTypeParser.parse(contentTypeHeader);
74
+ contentType = result.type;
75
+ charset = result.parameters.charset;
76
+ }
77
+ catch {
78
+ // Unparseable header → keep the original value rather than a mangled string.
79
+ return body;
80
+ }
81
+ // If we can't successfully interpret it, we return the original value rather than mangling it.
82
+ if (!areDataStringifiable(contentType, charset))
83
+ return body;
84
+ // Decode raw bytes using the resolved charset. An already-decoded string passes through (callers
85
+ // may hand us one directly), avoiding a needless re-encode round-trip.
86
+ const dataString = typeof body === 'string' ? body : isomorphicBufferToString(body, charset);
87
+ return contentType === CONTENT_TYPE_JSON ? JSON5.parse(dataString) : dataString;
88
+ }
89
+ function isomorphicBufferToString(buffer, encoding) {
90
+ if (buffer.constructor.name !== ArrayBuffer.name) {
91
+ return buffer.toString(encoding);
92
+ }
93
+ // In Node, wrap the ArrayBuffer in a Buffer so the resolved charset is honored (the caller already
94
+ // checked it via `Buffer.isEncoding`). Only the browser, which lacks Buffer, is limited to UTF-8.
95
+ if (typeof Buffer !== 'undefined') {
96
+ return Buffer.from(buffer).toString(encoding);
97
+ }
98
+ const decoder = new TextDecoder(encoding);
99
+ return decoder.decode(new Uint8Array(buffer));
100
+ }
101
+ function isCharsetStringifiable(charset) {
102
+ if (!charset)
103
+ return true; // hope that it's utf-8
104
+ return Buffer.isEncoding(charset);
105
+ }
106
+ function isContentTypeStringifiable(contentType) {
107
+ if (!contentType)
108
+ return false; // keep buffer
109
+ return STRINGIFIABLE_CONTENT_TYPE_RXS.some((rx) => rx.test(contentType));
110
+ }
111
+ function areDataStringifiable(contentType, charset) {
112
+ return isContentTypeStringifiable(contentType) && isCharsetStringifiable(charset);
113
+ }
@@ -0,0 +1,22 @@
1
+ /**
2
+ * A fixed-size, direct-mapped cache for `uniqueKey`-based request deduplication.
3
+ *
4
+ * `RequestProvider.requestCache` only remembers the first batch of requests, so repeated
5
+ * `addRequestsBatched()` calls with overlapping URLs re-submit already-enqueued requests
6
+ * (https://github.com/apify/crawlee/issues/3120). This is a separate, cheaper cache we can populate on
7
+ * every batch: a fixed number of slots indexed by a hash of the request's cache key, storing the
8
+ * server-assigned `requestId`. Memory is capped by the slot count regardless of the working set size;
9
+ * a hash collision just overwrites a slot, causing an occasional cache miss (a harmless re-submission)
10
+ * but never a false hit — so a genuinely new request is never dropped.
11
+ *
12
+ * @internal
13
+ */
14
+ export declare class RequestDeduplicationCache {
15
+ #private;
16
+ private readonly size;
17
+ constructor(size?: number);
18
+ get(cacheKey: string): string | null;
19
+ add(cacheKey: string, requestId: string): void;
20
+ clear(): void;
21
+ private indexOf;
22
+ }
@@ -0,0 +1,48 @@
1
+ /**
2
+ * A fixed-size, direct-mapped cache for `uniqueKey`-based request deduplication.
3
+ *
4
+ * `RequestProvider.requestCache` only remembers the first batch of requests, so repeated
5
+ * `addRequestsBatched()` calls with overlapping URLs re-submit already-enqueued requests
6
+ * (https://github.com/apify/crawlee/issues/3120). This is a separate, cheaper cache we can populate on
7
+ * every batch: a fixed number of slots indexed by a hash of the request's cache key, storing the
8
+ * server-assigned `requestId`. Memory is capped by the slot count regardless of the working set size;
9
+ * a hash collision just overwrites a slot, causing an occasional cache miss (a harmless re-submission)
10
+ * but never a false hit — so a genuinely new request is never dropped.
11
+ *
12
+ * @internal
13
+ */
14
+ export class RequestDeduplicationCache {
15
+ size;
16
+ #keys;
17
+ #ids;
18
+ // The slot count is the same for every queue, so it's a fixed default rather than a per-consumer option.
19
+ constructor(size = 1_000_000) {
20
+ this.size = size;
21
+ this.#keys = new Array(size);
22
+ this.#ids = new Array(size);
23
+ }
24
+ get(cacheKey) {
25
+ const index = this.indexOf(cacheKey);
26
+ return this.#keys[index] === cacheKey ? this.#ids[index] : null;
27
+ }
28
+ add(cacheKey, requestId) {
29
+ const index = this.indexOf(cacheKey);
30
+ this.#keys[index] = cacheKey;
31
+ this.#ids[index] = requestId;
32
+ }
33
+ clear() {
34
+ this.#keys = new Array(this.size);
35
+ this.#ids = new Array(this.size);
36
+ }
37
+ // A cheap FNV-1a hash of the cache key — avoids pulling in a dedicated hashing dependency.
38
+ indexOf(cacheKey) {
39
+ /* eslint-disable no-bitwise */
40
+ let hash = 0x811c9dc5;
41
+ for (let i = 0; i < cacheKey.length; i++) {
42
+ hash ^= cacheKey.charCodeAt(i);
43
+ hash = Math.imul(hash, 0x01000193);
44
+ }
45
+ return (hash >>> 0) % this.size;
46
+ /* eslint-enable no-bitwise */
47
+ }
48
+ }
@@ -1,69 +1,14 @@
1
+ import type { BaseHttpClient } from '@crawlee/http-client';
1
2
  import type { Dictionary } from '@crawlee/types';
2
- import { Configuration } from '../configuration.js';
3
- import type { ProxyConfiguration } from '../proxy_configuration.js';
4
- import { type InternalSource, Request, type RequestOptions, type Source } from '../request.js';
3
+ import type { Configuration } from '../configuration.js';
4
+ import type { IProxyConfiguration } from '../proxy_configuration.js';
5
+ import { Request, type RequestOptions, type Source } from '../request.js';
6
+ import type { IRequestLoader, RequestLoaderStatus } from './request_loader.js';
7
+ import type { IRequestManager } from './request_manager.js';
5
8
  /** @internal */
6
9
  export declare const STATE_PERSISTENCE_KEY = "REQUEST_LIST_STATE";
7
10
  /** @internal */
8
11
  export declare const REQUESTS_PERSISTENCE_KEY = "REQUEST_LIST_REQUESTS";
9
- /**
10
- * Represents a static list of URLs to crawl.
11
- */
12
- export interface IRequestList {
13
- /**
14
- * Returns the total number of unique requests present in the list.
15
- */
16
- length(): number;
17
- /**
18
- * Returns `true` if all requests were already handled and there are no more left.
19
- */
20
- isFinished(): Promise<boolean>;
21
- /**
22
- * Resolves to `true` if the next call to {@link IRequestList.fetchNextRequest} function
23
- * would return `null`, otherwise it resolves to `false`.
24
- * Note that even if the list is empty, there might be some pending requests currently being processed.
25
- */
26
- isEmpty(): Promise<boolean>;
27
- /**
28
- * Returns number of handled requests.
29
- */
30
- handledCount(): number;
31
- /**
32
- * Persists the current state of the `IRequestList` into the default {@link KeyValueStore}.
33
- * The state is persisted automatically in regular intervals, but calling this method manually
34
- * is useful in cases where you want to have the most current state available after you pause
35
- * or stop fetching its requests. For example after you pause or abort a crawl. Or just before
36
- * a server migration.
37
- */
38
- persistState(): Promise<void>;
39
- /**
40
- * Gets the next {@link Request} to process. First, the function gets a request previously reclaimed
41
- * using the {@link RequestList.reclaimRequest} function, if there is any.
42
- * Otherwise it gets the next request from sources.
43
- *
44
- * The function's `Promise` resolves to `null` if there are no more
45
- * requests to process.
46
- */
47
- fetchNextRequest(): Promise<Request | null>;
48
- /**
49
- * Can be used to iterate over the `RequestList` instance in a `for await .. of` loop.
50
- * Provides an alternative for the repeated use of `fetchNextRequest`.
51
- */
52
- [Symbol.asyncIterator](): AsyncGenerator<Request>;
53
- /**
54
- * Reclaims request to the list if its processing failed.
55
- * The request will become available in the next `this.fetchNextRequest()`.
56
- */
57
- reclaimRequest(request: Request): Promise<void>;
58
- /**
59
- * Marks request as handled after successful processing.
60
- */
61
- markRequestHandled(request: Request): Promise<void>;
62
- /**
63
- * @internal
64
- */
65
- inProgress: Set<string>;
66
- }
67
12
  export interface RequestListOptions {
68
13
  /**
69
14
  * An array of sources of URLs for the {@link RequestList}. It can be either an array of strings,
@@ -143,7 +88,7 @@ export interface RequestListOptions {
143
88
  * Takes advantage of the internal address rotation and authentication process.
144
89
  * If undefined, the `requestsFromUrl` requests will be made without proxy.
145
90
  */
146
- proxyConfiguration?: ProxyConfiguration;
91
+ proxyConfiguration?: IProxyConfiguration;
147
92
  /**
148
93
  * Identifies the key in the default key-value store under which `RequestList` periodically stores its
149
94
  * state (i.e. which URLs were crawled and which not).
@@ -182,7 +127,8 @@ export interface RequestListOptions {
182
127
  * ```
183
128
  *
184
129
  * Note that the preferred (and simpler) way to persist the state of crawling of the `RequestList`
185
- * is to use the `stateKeyPrefix` parameter instead.
130
+ * is to use the `stateKeyPrefix` parameter instead. When both are set, a record persisted under
131
+ * {@link RequestListOptions.persistStateKey} takes precedence over this option.
186
132
  */
187
133
  state?: RequestListState;
188
134
  /**
@@ -202,7 +148,13 @@ export interface RequestListOptions {
202
148
  */
203
149
  keepDuplicateUrls?: boolean;
204
150
  /** @internal */
205
- config?: Configuration;
151
+ configuration?: Configuration;
152
+ /**
153
+ * The HTTP client to be used to download `requestsFromUrl` URLs.
154
+ *
155
+ * If not specified the `RequestList` will use the default HTTP client.
156
+ */
157
+ httpClient?: BaseHttpClient;
206
158
  }
207
159
  /**
208
160
  * Represents a static list of URLs to crawl.
@@ -226,8 +178,8 @@ export interface RequestListOptions {
226
178
  * > In practical terms, such a combination can be useful when there is a large number of initial URLs,
227
179
  * > but more URLs would be added dynamically by the crawler.
228
180
  *
229
- * `RequestList` has an internal state where it stores information about which requests were already handled,
230
- * which are in progress and which were reclaimed. The state may be automatically persisted to the default
181
+ * `RequestList` has an internal state where it stores information about which requests were already handled
182
+ * and which are in progress. The state may be automatically persisted to the default
231
183
  * {@link KeyValueStore} by setting the `persistStateKey` option so that if the Node.js process is restarted,
232
184
  * the crawling can continue where it left off. The automated persisting is launched upon receiving the `persistState`
233
185
  * event that is periodically emitted by {@link EventManager}.
@@ -265,49 +217,24 @@ export interface RequestListOptions {
265
217
  * ```
266
218
  * @category Sources
267
219
  */
268
- export declare class RequestList implements IRequestList {
269
- private log;
220
+ export declare class RequestList implements IRequestLoader {
221
+ #private;
270
222
  /**
271
223
  * Array of all requests from all sources, in the order as they appeared in sources.
272
224
  * All requests in the array have distinct uniqueKey!
273
225
  * @internal
274
226
  */
275
- requests: (Request | RequestOptions)[];
276
- /** Index to the next item in requests array to fetch. All previous requests are either handled or in progress. */
277
- private nextIndex;
278
- /** Dictionary, key is Request.uniqueKey, value is corresponding index in the requests array. */
279
- private uniqueKeyToIndex;
227
+ readonly requests: (Request | RequestOptions)[];
280
228
  /**
281
229
  * Set of `uniqueKey`s of requests that were returned by fetchNextRequest().
282
230
  * @internal
283
231
  */
284
- inProgress: Set<string>;
285
- /**
286
- * Set of `uniqueKey`s of requests for which reclaimRequest() was called.
287
- * @internal
288
- */
289
- reclaimed: Set<string>;
290
- /**
291
- * Starts as true because until we handle the first request, the list is effectively persisted by doing nothing.
292
- * @internal
293
- */
294
- isStatePersisted: boolean;
232
+ get inProgress(): Set<string>;
295
233
  /**
296
234
  * Starts as false because we don't know yet and sources might change in the meantime (eg. download from live list).
297
235
  * @internal
298
236
  */
299
237
  areRequestsPersisted: boolean;
300
- private isLoading;
301
- private isInitialized;
302
- private persistStateKey?;
303
- private persistRequestsKey?;
304
- private initialState?;
305
- private store?;
306
- private keepDuplicateUrls;
307
- private sources;
308
- private sourcesFunction?;
309
- private proxyConfiguration?;
310
- private events;
311
238
  /**
312
239
  * To create new instance of `RequestList` we need to use `RequestList.open()` factory method.
313
240
  * @param options All `RequestList` configuration options
@@ -324,33 +251,30 @@ export declare class RequestList implements IRequestList {
324
251
  * This needs to be done in a memory efficient way. We should update the input
325
252
  * to a Stream once apify-client supports streams.
326
253
  */
327
- protected _addPersistedRequests(persistedRequests: Buffer): Promise<void>;
254
+ private addPersistedRequests;
328
255
  /**
329
256
  * Add Requests from both options.sources and options.sourcesFunction.
330
257
  * This function is called only when persisted sources were not loaded.
331
258
  * We need to avoid keeping both sources and requests in memory
332
259
  * to reduce memory footprint with very large sources.
333
260
  */
334
- protected _addRequestsFromSources(): Promise<void>;
261
+ private addRequestsFromSources;
335
262
  /**
336
263
  * @inheritDoc
337
264
  */
338
265
  persistState(): Promise<void>;
266
+ /**
267
+ * Removes the `PERSIST_STATE` event listener registered during initialization and persists
268
+ * the current state one last time. Call this when you are done with the `RequestList` to avoid
269
+ * leaking the listener (and the requests it retains) on the shared event manager.
270
+ */
271
+ teardown(): Promise<void>;
339
272
  /**
340
273
  * Unlike persistState(), this is used only internally, since the sources
341
274
  * are automatically persisted at RequestList initialization (if the persistRequestsKey is set),
342
275
  * but there's no reason to persist it again afterwards, because RequestList is immutable.
343
276
  */
344
- protected _persistRequests(): Promise<void>;
345
- /**
346
- * Restores RequestList state from a state object.
347
- */
348
- protected _restoreState(state?: RequestListState): void;
349
- /**
350
- * Attempts to load state and requests using the `RequestList` configuration
351
- * and returns a tuple of [state, requests] where each may be null if not loaded.
352
- */
353
- protected _loadStateAndPersistedRequests(): Promise<[RequestListState, Buffer]>;
277
+ private persistRequests;
354
278
  /**
355
279
  * Returns an object representing the internal state of the `RequestList` instance.
356
280
  * Note that the object's fields can change in future releases.
@@ -359,11 +283,7 @@ export declare class RequestList implements IRequestList {
359
283
  /**
360
284
  * @inheritDoc
361
285
  */
362
- isEmpty(): Promise<boolean>;
363
- /**
364
- * @inheritDoc
365
- */
366
- isFinished(): Promise<boolean>;
286
+ checkReadiness(): Promise<RequestLoaderStatus>;
367
287
  /**
368
288
  * @inheritDoc
369
289
  */
@@ -376,47 +296,53 @@ export declare class RequestList implements IRequestList {
376
296
  /**
377
297
  * @inheritDoc
378
298
  */
379
- markRequestHandled(request: Request): Promise<void>;
380
- /**
381
- * @inheritDoc
382
- */
383
- reclaimRequest(request: Request): Promise<void>;
299
+ markRequestAsHandled(request: Request): Promise<void>;
384
300
  /**
385
301
  * Adds all fetched requests from a URL from a remote resource.
386
302
  */
387
- protected _addFetchedRequests(source: InternalSource, fetchedRequests: RequestOptions[]): Promise<void>;
388
- protected _getPersistedState<T>(key: string): Promise<T>;
303
+ private addFetchedRequests;
304
+ private getPersistedState;
389
305
  /**
390
306
  * Fetches URLs from requestsFromUrl and returns them in format of list of requests
391
307
  */
392
- protected _fetchRequestsFromUrl(source: InternalSource): Promise<RequestOptions[]>;
308
+ private fetchRequestsFromUrl;
393
309
  /**
394
310
  * Adds given request.
395
311
  * If the `source` parameter is a string or plain object and not an instance
396
312
  * of a `Request`, then the function creates a `Request` instance.
397
313
  */
398
- protected _addRequest(source: RequestListSource): void;
314
+ private addRequest;
399
315
  /**
400
316
  * Helper function that validates unique key.
401
317
  * Throws an error if uniqueKey is not a non-empty string.
402
318
  */
403
- protected _ensureUniqueKeyValid(uniqueKey: string): void;
319
+ private ensureUniqueKeyValid;
404
320
  /**
405
- * Checks that request is not reclaimed and throws an error if so.
321
+ * Checks that a request is currently being processed and throws an error if not.
406
322
  */
407
- protected _ensureInProgressAndNotReclaimed(uniqueKey: string): void;
323
+ private ensureInProgress;
408
324
  /**
409
325
  * Throws an error if request list wasn't initialized.
410
326
  */
411
- protected _ensureIsInitialized(): void;
327
+ private ensureIsInitialized;
412
328
  /**
413
329
  * Returns the total number of unique requests present in the `RequestList`.
414
330
  */
415
- length(): number;
331
+ getTotalCount(): Promise<number>;
332
+ /**
333
+ * Returns the number of pending requests in the `RequestList`.
334
+ */
335
+ getPendingCount(): Promise<number>;
336
+ /**
337
+ * Combines this list with a request manager (a {@link RequestQueue} by default) into a
338
+ * {@link RequestManagerTandem}, allowing requests to be added and reclaimed while still
339
+ * being read from this list first.
340
+ */
341
+ toTandem(requestManager?: IRequestManager): Promise<IRequestManager>;
416
342
  /**
417
343
  * @inheritDoc
418
344
  */
419
- handledCount(): number;
345
+ getHandledCount(): Promise<number>;
420
346
  /**
421
347
  * Opens a request list and returns a promise resolving to an instance
422
348
  * of the {@link RequestList} class that is already initialized.
@@ -474,7 +400,7 @@ export declare class RequestList implements IRequestList {
474
400
  /**
475
401
  * @internal wraps public utility for mocking purposes
476
402
  */
477
- private _downloadListOfUrls;
403
+ private downloadListOfUrls;
478
404
  }
479
405
  /**
480
406
  * Represents state of a {@link RequestList}. It can be used to resume a {@link RequestList} which has been previously processed.
@@ -503,4 +429,3 @@ export interface RequestListState {
503
429
  type RequestListSource = string | Source;
504
430
  export type RequestListSourcesFunction = () => Promise<RequestListSource[]>;
505
431
  export {};
506
- //# sourceMappingURL=request_list.d.ts.map