@crawlee/core 4.0.0-beta.15 → 4.0.0-beta.150

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 (287) hide show
  1. package/README.md +14 -14
  2. package/autoscaling/autoscaled_pool.d.ts +73 -177
  3. package/autoscaling/autoscaled_pool.js +182 -329
  4. package/autoscaling/concurrency_system.d.ts +268 -0
  5. package/autoscaling/concurrency_system.js +364 -0
  6. package/autoscaling/cpu_load_signal.d.ts +43 -0
  7. package/autoscaling/cpu_load_signal.js +47 -0
  8. package/autoscaling/event_loop_load_signal.d.ts +51 -0
  9. package/autoscaling/event_loop_load_signal.js +60 -0
  10. package/autoscaling/index.d.ts +6 -1
  11. package/autoscaling/index.js +6 -1
  12. package/autoscaling/load_signal.d.ts +98 -0
  13. package/autoscaling/load_signal.js +103 -0
  14. package/autoscaling/memory_load_signal.d.ts +47 -0
  15. package/autoscaling/memory_load_signal.js +106 -0
  16. package/autoscaling/snapshotter.d.ts +58 -163
  17. package/autoscaling/snapshotter.js +45 -263
  18. package/autoscaling/storage_backend_load_signal.d.ts +56 -0
  19. package/autoscaling/storage_backend_load_signal.js +73 -0
  20. package/autoscaling/system_status.d.ts +67 -89
  21. package/autoscaling/system_status.js +92 -122
  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 -223
  27. package/configuration.js +170 -222
  28. package/cookie_utils.d.ts +3 -2
  29. package/cookie_utils.js +18 -7
  30. package/crawlers/context_pipeline.d.ts +10 -1
  31. package/crawlers/context_pipeline.js +31 -8
  32. package/crawlers/crawler_commons.d.ts +90 -126
  33. package/crawlers/crawler_commons.js +1 -108
  34. package/crawlers/error_snapshotter.d.ts +2 -5
  35. package/crawlers/error_snapshotter.js +7 -8
  36. package/crawlers/error_tracker.d.ts +0 -1
  37. package/crawlers/error_tracker.js +0 -1
  38. package/crawlers/index.d.ts +1 -3
  39. package/crawlers/index.js +0 -3
  40. package/crawlers/internals/types.d.ts +0 -1
  41. package/crawlers/internals/types.js +0 -1
  42. package/crawlers/statistics.d.ts +187 -64
  43. package/crawlers/statistics.js +354 -165
  44. package/debug.d.ts +36 -0
  45. package/debug.js +70 -0
  46. package/enqueue_links/enqueue_links.d.ts +61 -154
  47. package/enqueue_links/enqueue_links.js +40 -232
  48. package/enqueue_links/index.d.ts +0 -1
  49. package/enqueue_links/index.js +0 -1
  50. package/enqueue_links/shared.d.ts +55 -28
  51. package/enqueue_links/shared.js +116 -69
  52. package/errors.d.ts +72 -4
  53. package/errors.js +89 -5
  54. package/events/event_manager.d.ts +35 -9
  55. package/events/event_manager.js +12 -13
  56. package/events/index.d.ts +0 -1
  57. package/events/index.js +0 -1
  58. package/events/local_event_manager.d.ts +15 -3
  59. package/events/local_event_manager.js +39 -13
  60. package/http.d.ts +9 -0
  61. package/http.js +28 -0
  62. package/index.d.ts +7 -5
  63. package/index.js +8 -4
  64. package/iterables.d.ts +79 -0
  65. package/iterables.js +134 -0
  66. package/log.d.ts +77 -1
  67. package/log.js +104 -1
  68. package/memory-storage/consts.d.ts +4 -0
  69. package/memory-storage/consts.js +4 -0
  70. package/memory-storage/index.d.ts +1 -0
  71. package/memory-storage/index.js +1 -0
  72. package/memory-storage/memory-storage.d.ts +44 -0
  73. package/memory-storage/memory-storage.js +160 -0
  74. package/memory-storage/resource-clients/common/base-client.d.ts +4 -0
  75. package/memory-storage/resource-clients/common/base-client.js +6 -0
  76. package/memory-storage/resource-clients/dataset.d.ts +40 -0
  77. package/memory-storage/resource-clients/dataset.js +106 -0
  78. package/memory-storage/resource-clients/key-value-store.d.ts +63 -0
  79. package/memory-storage/resource-clients/key-value-store.js +199 -0
  80. package/memory-storage/resource-clients/request-queue.d.ts +77 -0
  81. package/memory-storage/resource-clients/request-queue.js +407 -0
  82. package/memory-storage/utils.d.ts +16 -0
  83. package/memory-storage/utils.js +41 -0
  84. package/owned_or_injected.d.ts +58 -0
  85. package/owned_or_injected.js +98 -0
  86. package/package.json +13 -12
  87. package/proxy_configuration.d.ts +22 -128
  88. package/proxy_configuration.js +32 -144
  89. package/recoverable_state.d.ts +83 -51
  90. package/recoverable_state.js +163 -72
  91. package/request.d.ts +57 -16
  92. package/request.js +130 -69
  93. package/router.d.ts +193 -21
  94. package/router.js +188 -43
  95. package/serialization.d.ts +0 -1
  96. package/serialization.js +15 -15
  97. package/service_locator.d.ts +165 -0
  98. package/service_locator.js +253 -0
  99. package/session_pool/consts.d.ts +1 -2
  100. package/session_pool/consts.js +1 -2
  101. package/session_pool/errors.d.ts +0 -1
  102. package/session_pool/errors.js +0 -1
  103. package/session_pool/fingerprint.d.ts +9 -0
  104. package/session_pool/fingerprint.js +30 -0
  105. package/session_pool/index.d.ts +0 -2
  106. package/session_pool/index.js +0 -2
  107. package/session_pool/session.d.ts +39 -89
  108. package/session_pool/session.js +102 -159
  109. package/session_pool/session_pool.d.ts +67 -91
  110. package/session_pool/session_pool.js +196 -187
  111. package/storages/batched_adds.d.ts +37 -0
  112. package/storages/batched_adds.js +73 -0
  113. package/storages/dataset.d.ts +109 -56
  114. package/storages/dataset.js +284 -149
  115. package/storages/index.d.ts +9 -9
  116. package/storages/index.js +7 -9
  117. package/storages/key_value_store.d.ts +183 -48
  118. package/storages/key_value_store.js +444 -171
  119. package/storages/key_value_store_codec.d.ts +32 -0
  120. package/storages/key_value_store_codec.js +113 -0
  121. package/storages/request_dedup_cache.d.ts +22 -0
  122. package/storages/request_dedup_cache.js +48 -0
  123. package/storages/request_list.d.ts +53 -115
  124. package/storages/request_list.js +194 -167
  125. package/storages/request_loader.d.ts +133 -0
  126. package/storages/request_loader.js +36 -0
  127. package/storages/request_manager.d.ts +109 -0
  128. package/storages/request_manager.js +1 -0
  129. package/storages/request_manager_tandem.d.ts +55 -23
  130. package/storages/request_manager_tandem.js +139 -57
  131. package/storages/request_queue.d.ts +286 -48
  132. package/storages/request_queue.js +757 -218
  133. package/storages/{sitemap_request_list.d.ts → sitemap_request_loader.d.ts} +43 -91
  134. package/storages/sitemap_request_loader.js +439 -0
  135. package/storages/storage_instance_manager.d.ts +87 -0
  136. package/storages/storage_instance_manager.js +256 -0
  137. package/storages/storage_stats.d.ts +48 -0
  138. package/storages/storage_stats.js +29 -0
  139. package/storages/throttling_request_manager.d.ts +222 -0
  140. package/storages/throttling_request_manager.js +780 -0
  141. package/storages/transaction.d.ts +252 -0
  142. package/storages/transaction.js +251 -0
  143. package/storages/utils.d.ts +59 -11
  144. package/storages/utils.js +75 -15
  145. package/system-info/cpu-info.d.ts +67 -0
  146. package/system-info/cpu-info.js +216 -0
  147. package/system-info/memory-info.d.ts +31 -0
  148. package/system-info/memory-info.js +115 -0
  149. package/system-info/ps-tree.d.ts +17 -0
  150. package/system-info/ps-tree.js +144 -0
  151. package/system-info/runtime.d.ts +14 -0
  152. package/system-info/runtime.js +80 -0
  153. package/typedefs.d.ts +0 -6
  154. package/typedefs.js +0 -1
  155. package/url.d.ts +9 -0
  156. package/url.js +11 -0
  157. package/validators.d.ts +22 -18
  158. package/validators.js +13 -18
  159. package/autoscaling/autoscaled_pool.d.ts.map +0 -1
  160. package/autoscaling/autoscaled_pool.js.map +0 -1
  161. package/autoscaling/index.d.ts.map +0 -1
  162. package/autoscaling/index.js.map +0 -1
  163. package/autoscaling/snapshotter.d.ts.map +0 -1
  164. package/autoscaling/snapshotter.js.map +0 -1
  165. package/autoscaling/system_status.d.ts.map +0 -1
  166. package/autoscaling/system_status.js.map +0 -1
  167. package/configuration.d.ts.map +0 -1
  168. package/configuration.js.map +0 -1
  169. package/cookie_utils.d.ts.map +0 -1
  170. package/cookie_utils.js.map +0 -1
  171. package/crawlers/context_pipeline.d.ts.map +0 -1
  172. package/crawlers/context_pipeline.js.map +0 -1
  173. package/crawlers/crawler_commons.d.ts.map +0 -1
  174. package/crawlers/crawler_commons.js.map +0 -1
  175. package/crawlers/crawler_utils.d.ts +0 -10
  176. package/crawlers/crawler_utils.d.ts.map +0 -1
  177. package/crawlers/crawler_utils.js +0 -12
  178. package/crawlers/crawler_utils.js.map +0 -1
  179. package/crawlers/error_snapshotter.d.ts.map +0 -1
  180. package/crawlers/error_snapshotter.js.map +0 -1
  181. package/crawlers/error_tracker.d.ts.map +0 -1
  182. package/crawlers/error_tracker.js.map +0 -1
  183. package/crawlers/index.d.ts.map +0 -1
  184. package/crawlers/index.js.map +0 -1
  185. package/crawlers/internals/types.d.ts.map +0 -1
  186. package/crawlers/internals/types.js.map +0 -1
  187. package/crawlers/statistics.d.ts.map +0 -1
  188. package/crawlers/statistics.js.map +0 -1
  189. package/enqueue_links/enqueue_links.d.ts.map +0 -1
  190. package/enqueue_links/enqueue_links.js.map +0 -1
  191. package/enqueue_links/index.d.ts.map +0 -1
  192. package/enqueue_links/index.js.map +0 -1
  193. package/enqueue_links/shared.d.ts.map +0 -1
  194. package/enqueue_links/shared.js.map +0 -1
  195. package/errors.d.ts.map +0 -1
  196. package/errors.js.map +0 -1
  197. package/events/event_manager.d.ts.map +0 -1
  198. package/events/event_manager.js.map +0 -1
  199. package/events/index.d.ts.map +0 -1
  200. package/events/index.js.map +0 -1
  201. package/events/local_event_manager.d.ts.map +0 -1
  202. package/events/local_event_manager.js.map +0 -1
  203. package/http_clients/base-http-client.d.ts +0 -140
  204. package/http_clients/base-http-client.d.ts.map +0 -1
  205. package/http_clients/base-http-client.js +0 -40
  206. package/http_clients/base-http-client.js.map +0 -1
  207. package/http_clients/form-data-like.d.ts +0 -67
  208. package/http_clients/form-data-like.d.ts.map +0 -1
  209. package/http_clients/form-data-like.js +0 -5
  210. package/http_clients/form-data-like.js.map +0 -1
  211. package/http_clients/got-scraping-http-client.d.ts +0 -20
  212. package/http_clients/got-scraping-http-client.d.ts.map +0 -1
  213. package/http_clients/got-scraping-http-client.js +0 -85
  214. package/http_clients/got-scraping-http-client.js.map +0 -1
  215. package/http_clients/index.d.ts +0 -3
  216. package/http_clients/index.d.ts.map +0 -1
  217. package/http_clients/index.js +0 -3
  218. package/http_clients/index.js.map +0 -1
  219. package/index.d.ts.map +0 -1
  220. package/index.js.map +0 -1
  221. package/log.d.ts.map +0 -1
  222. package/log.js.map +0 -1
  223. package/proxy_configuration.d.ts.map +0 -1
  224. package/proxy_configuration.js.map +0 -1
  225. package/recoverable_state.d.ts.map +0 -1
  226. package/recoverable_state.js.map +0 -1
  227. package/request.d.ts.map +0 -1
  228. package/request.js.map +0 -1
  229. package/router.d.ts.map +0 -1
  230. package/router.js.map +0 -1
  231. package/serialization.d.ts.map +0 -1
  232. package/serialization.js.map +0 -1
  233. package/session_pool/consts.d.ts.map +0 -1
  234. package/session_pool/consts.js.map +0 -1
  235. package/session_pool/errors.d.ts.map +0 -1
  236. package/session_pool/errors.js.map +0 -1
  237. package/session_pool/events.d.ts +0 -3
  238. package/session_pool/events.d.ts.map +0 -1
  239. package/session_pool/events.js +0 -3
  240. package/session_pool/events.js.map +0 -1
  241. package/session_pool/index.d.ts.map +0 -1
  242. package/session_pool/index.js.map +0 -1
  243. package/session_pool/session.d.ts.map +0 -1
  244. package/session_pool/session.js.map +0 -1
  245. package/session_pool/session_pool.d.ts.map +0 -1
  246. package/session_pool/session_pool.js.map +0 -1
  247. package/storages/access_checking.d.ts +0 -13
  248. package/storages/access_checking.d.ts.map +0 -1
  249. package/storages/access_checking.js +0 -14
  250. package/storages/access_checking.js.map +0 -1
  251. package/storages/dataset.d.ts.map +0 -1
  252. package/storages/dataset.js.map +0 -1
  253. package/storages/index.d.ts.map +0 -1
  254. package/storages/index.js.map +0 -1
  255. package/storages/key_value_store.d.ts.map +0 -1
  256. package/storages/key_value_store.js.map +0 -1
  257. package/storages/request_list.d.ts.map +0 -1
  258. package/storages/request_list.js.map +0 -1
  259. package/storages/request_list_adapter.d.ts +0 -58
  260. package/storages/request_list_adapter.d.ts.map +0 -1
  261. package/storages/request_list_adapter.js +0 -81
  262. package/storages/request_list_adapter.js.map +0 -1
  263. package/storages/request_manager_tandem.d.ts.map +0 -1
  264. package/storages/request_manager_tandem.js.map +0 -1
  265. package/storages/request_provider.d.ts +0 -371
  266. package/storages/request_provider.d.ts.map +0 -1
  267. package/storages/request_provider.js +0 -585
  268. package/storages/request_provider.js.map +0 -1
  269. package/storages/request_queue.d.ts.map +0 -1
  270. package/storages/request_queue.js.map +0 -1
  271. package/storages/request_queue_v2.d.ts +0 -87
  272. package/storages/request_queue_v2.d.ts.map +0 -1
  273. package/storages/request_queue_v2.js +0 -438
  274. package/storages/request_queue_v2.js.map +0 -1
  275. package/storages/sitemap_request_list.d.ts.map +0 -1
  276. package/storages/sitemap_request_list.js +0 -430
  277. package/storages/sitemap_request_list.js.map +0 -1
  278. package/storages/storage_manager.d.ts +0 -58
  279. package/storages/storage_manager.d.ts.map +0 -1
  280. package/storages/storage_manager.js +0 -105
  281. package/storages/storage_manager.js.map +0 -1
  282. package/storages/utils.d.ts.map +0 -1
  283. package/storages/utils.js.map +0 -1
  284. package/typedefs.d.ts.map +0 -1
  285. package/typedefs.js.map +0 -1
  286. package/validators.d.ts.map +0 -1
  287. package/validators.js.map +0 -1
@@ -1,10 +1,25 @@
1
- import { getCurrentCpuTicksV2, getMemoryInfo, isContainerized } from '@crawlee/utils';
2
- import log from '@apify/log';
3
1
  import { betterClearInterval, betterSetInterval } from '@apify/utilities';
4
- import { EventManager } from './event_manager.js';
2
+ import { serviceLocator } from '../service_locator.js';
3
+ import { EventManager, EventType } from './event_manager.js';
5
4
  export class LocalEventManager extends EventManager {
5
+ #systemInfoIntervalMillis;
6
+ constructor(options) {
7
+ super(options);
8
+ this.#systemInfoIntervalMillis = options.systemInfoIntervalMillis;
9
+ }
10
+ /**
11
+ * Creates a new `LocalEventManager` based on the provided `Configuration`.
12
+ * Uses the global configuration from the service locator if none is provided.
13
+ */
14
+ static fromConfiguration(configuration) {
15
+ const resolvedConfiguration = configuration ?? serviceLocator.getConfiguration();
16
+ return new LocalEventManager({
17
+ persistStateIntervalMillis: resolvedConfiguration.persistStateIntervalMillis,
18
+ systemInfoIntervalMillis: resolvedConfiguration.systemInfoIntervalMillis,
19
+ });
20
+ }
6
21
  /**
7
- * Initializes the EventManager and sets up periodic `systemInfo` and `persistState` events.
22
+ * Initializes the EventManager and sets up periodic `systemInfo` events.
8
23
  * This is automatically called at the beginning of `crawler.run()`.
9
24
  */
10
25
  async init() {
@@ -12,9 +27,8 @@ export class LocalEventManager extends EventManager {
12
27
  return;
13
28
  }
14
29
  await super.init();
15
- const systemInfoIntervalMillis = this.config.get('systemInfoIntervalMillis');
16
30
  this.emitSystemInfoEvent = this.emitSystemInfoEvent.bind(this);
17
- this.intervals.systemInfo = betterSetInterval(this.emitSystemInfoEvent.bind(this), systemInfoIntervalMillis);
31
+ this.intervals.systemInfo = betterSetInterval(this.emitSystemInfoEvent.bind(this), this.#systemInfoIntervalMillis);
18
32
  }
19
33
  /**
20
34
  * @inheritDoc
@@ -31,16 +45,17 @@ export class LocalEventManager extends EventManager {
31
45
  */
32
46
  async emitSystemInfoEvent(intervalCallback) {
33
47
  const info = await this.createSystemInfo({
34
- maxUsedCpuRatio: this.config.get('maxUsedCpuRatio'),
48
+ maxUsedCpuRatio: serviceLocator.getConfiguration().maxUsedCpuRatio,
35
49
  });
36
- this.events.emit("systemInfo" /* EventType.SYSTEM_INFO */, info);
50
+ this.events.emit(EventType.SYSTEM_INFO, info);
37
51
  intervalCallback();
38
52
  }
39
53
  /**
40
54
  * @internal
41
55
  */
42
56
  async isContainerizedWrapper() {
43
- return this.config.get('containerized', await isContainerized());
57
+ const { isContainerized } = await import('../system-info/runtime.js');
58
+ return serviceLocator.getConfiguration().containerized ?? (await isContainerized());
44
59
  }
45
60
  /**
46
61
  * Creates a SystemInfo object based on local metrics.
@@ -53,7 +68,11 @@ export class LocalEventManager extends EventManager {
53
68
  };
54
69
  }
55
70
  async createCpuInfo(options) {
56
- const usedCpuRatio = await getCurrentCpuTicksV2(await this.isContainerizedWrapper());
71
+ const { getCurrentCpuTicksV2 } = await import('../system-info/cpu-info.js');
72
+ const usedCpuRatio = await getCurrentCpuTicksV2({
73
+ containerized: await this.isContainerizedWrapper(),
74
+ logger: serviceLocator.getLogger(),
75
+ });
57
76
  return {
58
77
  cpuCurrentUsage: usedCpuRatio * 100,
59
78
  isCpuOverloaded: usedCpuRatio > options.maxUsedCpuRatio,
@@ -61,15 +80,22 @@ export class LocalEventManager extends EventManager {
61
80
  }
62
81
  async createMemoryInfo() {
63
82
  try {
64
- const memInfo = await getMemoryInfo(await this.isContainerizedWrapper());
83
+ const memInfo = await this.getMemoryInfo();
65
84
  return {
85
+ memTotalBytes: memInfo.totalBytes,
66
86
  memCurrentBytes: memInfo.mainProcessBytes + memInfo.childProcessesBytes,
67
87
  };
68
88
  }
69
89
  catch (err) {
70
- log.exception(err, 'Memory snapshot failed.');
90
+ this.log.exception(err, 'Memory snapshot failed.');
71
91
  return {};
72
92
  }
73
93
  }
94
+ async getMemoryInfo() {
95
+ const { getMemoryInfo } = await import('../system-info/memory-info.js');
96
+ return getMemoryInfo({
97
+ containerized: await this.isContainerizedWrapper(),
98
+ logger: serviceLocator.getLogger(),
99
+ });
100
+ }
74
101
  }
75
- //# sourceMappingURL=local_event_manager.js.map
package/http.d.ts ADDED
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Parses a `Retry-After` response header into a delay in milliseconds.
3
+ *
4
+ * The header holds either a non-negative number of seconds or an HTTP-date.
5
+ * See [MDN](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Retry-After).
6
+ *
7
+ * @returns The delay in milliseconds, or `null` if the header is absent, unparseable, or already elapsed.
8
+ */
9
+ export declare function parseRetryAfterHeader(value?: string | null): number | null;
package/http.js ADDED
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Parses a `Retry-After` response header into a delay in milliseconds.
3
+ *
4
+ * The header holds either a non-negative number of seconds or an HTTP-date.
5
+ * See [MDN](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Retry-After).
6
+ *
7
+ * @returns The delay in milliseconds, or `null` if the header is absent, unparseable, or already elapsed.
8
+ */
9
+ export function parseRetryAfterHeader(value) {
10
+ if (!value) {
11
+ return null;
12
+ }
13
+ const trimmed = value.trim();
14
+ // Per the spec this is a `delay-seconds`: digits only, so a negative or fractional value is not one.
15
+ if (/^\d+$/.test(trimmed)) {
16
+ // `Retry-After: 0` names no future deadline, same as an HTTP-date that has already passed. Reporting it
17
+ // as a zero delay would leave the domain unthrottled while still counting as a rate-limit event, so the
18
+ // caller would defer the request for free and re-send it immediately.
19
+ const delayMs = Number(trimmed) * 1000;
20
+ return delayMs > 0 ? delayMs : null;
21
+ }
22
+ const date = Date.parse(trimmed);
23
+ if (!Number.isNaN(date)) {
24
+ const delayMs = date - Date.now();
25
+ return delayMs > 0 ? delayMs : null;
26
+ }
27
+ return null;
28
+ }
package/index.d.ts CHANGED
@@ -1,20 +1,22 @@
1
+ export * from './debug.js';
1
2
  export * from './errors.js';
2
3
  export * from './autoscaling/index.js';
3
4
  export * from './configuration.js';
5
+ export * from './service_locator.js';
4
6
  export * from './crawlers/index.js';
5
7
  export * from './enqueue_links/index.js';
6
8
  export * from './events/index.js';
7
- export * from './http_clients/index.js';
8
9
  export * from './log.js';
10
+ export * from './owned_or_injected.js';
9
11
  export * from './proxy_configuration.js';
10
12
  export * from './request.js';
11
13
  export * from './router.js';
12
14
  export * from './serialization.js';
13
15
  export * from './session_pool/index.js';
14
16
  export * from './storages/index.js';
15
- export * from './validators.js';
17
+ export * from './memory-storage/index.js';
18
+ export { ArgumentValidationError, validators } from './validators.js';
16
19
  export * from './cookie_utils.js';
20
+ export * from './http.js';
17
21
  export * from './recoverable_state.js';
18
- export { PseudoUrl } from '@apify/pseudo_url';
19
- export { Dictionary, Awaitable, Constructor, StorageClient, Cookie, QueueOperationInfo } from '@crawlee/types';
20
- //# sourceMappingURL=index.d.ts.map
22
+ export type { StorageBackend } from '@crawlee/types';
package/index.js CHANGED
@@ -1,19 +1,23 @@
1
+ export * from './debug.js';
1
2
  export * from './errors.js';
2
3
  export * from './autoscaling/index.js';
3
4
  export * from './configuration.js';
5
+ export * from './service_locator.js';
4
6
  export * from './crawlers/index.js';
5
7
  export * from './enqueue_links/index.js';
6
8
  export * from './events/index.js';
7
- export * from './http_clients/index.js';
8
9
  export * from './log.js';
10
+ export * from './owned_or_injected.js';
9
11
  export * from './proxy_configuration.js';
10
12
  export * from './request.js';
11
13
  export * from './router.js';
12
14
  export * from './serialization.js';
13
15
  export * from './session_pool/index.js';
14
16
  export * from './storages/index.js';
15
- export * from './validators.js';
17
+ export * from './memory-storage/index.js';
18
+ // Not `export *`: the rest of the module re-exports `@crawlee/utils/internal` symbols, which carry no
19
+ // semver guarantees and must not reach the public surface. Internal consumers import them directly.
20
+ export { ArgumentValidationError, validators } from './validators.js';
16
21
  export * from './cookie_utils.js';
22
+ export * from './http.js';
17
23
  export * from './recoverable_state.js';
18
- export { PseudoUrl } from '@apify/pseudo_url';
19
- //# sourceMappingURL=index.js.map
package/iterables.d.ts ADDED
@@ -0,0 +1,79 @@
1
+ /**
2
+ * Converts any iterable or async iterable to an async iterable.
3
+ * @internal
4
+ *
5
+ * @yields Each item from the input iterable
6
+ *
7
+ * **Example usage:**
8
+ * ```ts
9
+ * const syncArray = [1, 2, 3];
10
+ * for await (const item of asyncifyIterable(syncArray)) {
11
+ * console.log(item); // 1, 2, 3
12
+ * }
13
+ * ```
14
+ */
15
+ export declare function asyncifyIterable<T>(iterable: Iterable<T> | AsyncIterable<T>): AsyncIterable<T>;
16
+ /**
17
+ * Lazily splits the input async iterable into chunks of specified size.
18
+ * The last chunk may contain fewer items if the total number of items
19
+ * is not evenly divisible by the chunk size.
20
+ * @internal
21
+ *
22
+ * @yields Arrays of items, each containing up to chunkSize items
23
+ *
24
+ * **Example usage:**
25
+ * ```ts
26
+ * const numbers = async function* () {
27
+ * for (let i = 1; i <= 10; i++) yield i;
28
+ * };
29
+ *
30
+ * for await (const chunk of chunkedAsyncIterable(numbers(), 3)) {
31
+ * console.log(chunk); // [1, 2, 3], [4, 5, 6], [7, 8, 9], [10]
32
+ * }
33
+ * ```
34
+ */
35
+ export declare function chunkedAsyncIterable<T>(iterable: AsyncIterable<T> | Iterable<T>, chunkSize: number | (() => number)): AsyncIterable<T[]>;
36
+ /**
37
+ * An async iterator that also supports peeking at the next value without consuming it.
38
+ * Extends both AsyncIterator and AsyncIterable interfaces.
39
+ * @internal
40
+ */
41
+ export interface PeekableAsyncIterator<T> extends AsyncIterator<T>, AsyncIterable<T> {
42
+ /**
43
+ * Peeks at the next value without consuming it from the iterator.
44
+ * Subsequent calls to peek() will return the same value until next() is called.
45
+ *
46
+ * @returns Promise that resolves to the next value, or undefined if the iterator is exhausted
47
+ */
48
+ peek(): Promise<T | undefined>;
49
+ }
50
+ /**
51
+ * An async iterable that yields peekable async iterators.
52
+ * @internal
53
+ */
54
+ export interface PeekableAsyncIterable<T> extends AsyncIterable<T> {
55
+ [Symbol.asyncIterator](): PeekableAsyncIterator<T>;
56
+ }
57
+ /**
58
+ * Wraps an async iterable to provide peek functionality, allowing you to look at
59
+ * the next value without consuming it from the iterator.
60
+ * @internal
61
+ *
62
+ * @param iterable - The async iterable to make peekable
63
+ *
64
+ * **Example usage:**
65
+ * ```ts
66
+ * const numbers = async function* () {
67
+ * yield 1; yield 2; yield 3;
68
+ * };
69
+ *
70
+ * const peekable = peekableAsyncIterable(numbers());
71
+ * const iterator = peekable[Symbol.asyncIterator]();
72
+ *
73
+ * console.log(await iterator.peek()); // 1 (doesn't consume)
74
+ * console.log(await iterator.peek()); // 1 (still doesn't consume)
75
+ * console.log(await iterator.next()); // { value: 1, done: false } (now consumed)
76
+ * console.log(await iterator.peek()); // 2 (next value)
77
+ * ```
78
+ */
79
+ export declare function peekableAsyncIterable<T>(iterable: AsyncIterable<T> | Iterable<T>): PeekableAsyncIterable<T>;
package/iterables.js ADDED
@@ -0,0 +1,134 @@
1
+ import { inspect } from 'node:util';
2
+ /**
3
+ * Converts any iterable or async iterable to an async iterable.
4
+ * @internal
5
+ *
6
+ * @yields Each item from the input iterable
7
+ *
8
+ * **Example usage:**
9
+ * ```ts
10
+ * const syncArray = [1, 2, 3];
11
+ * for await (const item of asyncifyIterable(syncArray)) {
12
+ * console.log(item); // 1, 2, 3
13
+ * }
14
+ * ```
15
+ */
16
+ export async function* asyncifyIterable(iterable) {
17
+ yield* iterable;
18
+ }
19
+ /**
20
+ * Lazily splits the input async iterable into chunks of specified size.
21
+ * The last chunk may contain fewer items if the total number of items
22
+ * is not evenly divisible by the chunk size.
23
+ * @internal
24
+ *
25
+ * @yields Arrays of items, each containing up to chunkSize items
26
+ *
27
+ * **Example usage:**
28
+ * ```ts
29
+ * const numbers = async function* () {
30
+ * for (let i = 1; i <= 10; i++) yield i;
31
+ * };
32
+ *
33
+ * for await (const chunk of chunkedAsyncIterable(numbers(), 3)) {
34
+ * console.log(chunk); // [1, 2, 3], [4, 5, 6], [7, 8, 9], [10]
35
+ * }
36
+ * ```
37
+ */
38
+ export async function* chunkedAsyncIterable(iterable, chunkSize) {
39
+ const getChunkSize = typeof chunkSize === 'function' ? chunkSize : () => chunkSize;
40
+ if (typeof chunkSize === 'number' && chunkSize < 1) {
41
+ throw new Error(`Chunk size must be a positive number (${inspect(chunkSize)}) received`);
42
+ }
43
+ const iterator = Symbol.asyncIterator in iterable
44
+ ? iterable[Symbol.asyncIterator]()
45
+ : iterable[Symbol.iterator]();
46
+ while (true) {
47
+ const currentSize = getChunkSize();
48
+ if (currentSize < 1)
49
+ break;
50
+ const chunk = [];
51
+ for (let i = 0; i < currentSize; i++) {
52
+ const next = await iterator.next();
53
+ if (next.done) {
54
+ break;
55
+ }
56
+ chunk.push(next.value);
57
+ }
58
+ if (chunk.length === 0)
59
+ break;
60
+ yield chunk;
61
+ }
62
+ }
63
+ /**
64
+ * Wraps an async iterable to provide peek functionality, allowing you to look at
65
+ * the next value without consuming it from the iterator.
66
+ * @internal
67
+ *
68
+ * @param iterable - The async iterable to make peekable
69
+ *
70
+ * **Example usage:**
71
+ * ```ts
72
+ * const numbers = async function* () {
73
+ * yield 1; yield 2; yield 3;
74
+ * };
75
+ *
76
+ * const peekable = peekableAsyncIterable(numbers());
77
+ * const iterator = peekable[Symbol.asyncIterator]();
78
+ *
79
+ * console.log(await iterator.peek()); // 1 (doesn't consume)
80
+ * console.log(await iterator.peek()); // 1 (still doesn't consume)
81
+ * console.log(await iterator.next()); // { value: 1, done: false } (now consumed)
82
+ * console.log(await iterator.peek()); // 2 (next value)
83
+ * ```
84
+ */
85
+ export function peekableAsyncIterable(iterable) {
86
+ const iterator = asyncifyIterable(iterable)[Symbol.asyncIterator]();
87
+ let peekedValue;
88
+ let isExhausted = false;
89
+ const peekableIterator = {
90
+ async next() {
91
+ // If we have peeked a value, return it and clear the peek
92
+ if (peekedValue !== undefined) {
93
+ const result = peekedValue;
94
+ peekedValue = undefined;
95
+ if (result.done) {
96
+ isExhausted = true;
97
+ return { done: true, value: undefined };
98
+ }
99
+ return { done: false, value: result.value };
100
+ }
101
+ if (isExhausted) {
102
+ return { done: true, value: undefined };
103
+ }
104
+ const result = await iterator.next();
105
+ if (result.done) {
106
+ isExhausted = true;
107
+ }
108
+ return result;
109
+ },
110
+ async peek() {
111
+ if (peekedValue !== undefined) {
112
+ return peekedValue.done ? undefined : peekedValue.value;
113
+ }
114
+ if (isExhausted) {
115
+ return undefined;
116
+ }
117
+ const result = await iterator.next();
118
+ peekedValue = { done: result.done ?? false, value: result.value };
119
+ if (result.done) {
120
+ isExhausted = true;
121
+ return undefined;
122
+ }
123
+ return result.value;
124
+ },
125
+ [Symbol.asyncIterator]() {
126
+ return this;
127
+ },
128
+ };
129
+ return {
130
+ [Symbol.asyncIterator]() {
131
+ return peekableIterator;
132
+ },
133
+ };
134
+ }
package/log.d.ts CHANGED
@@ -1,5 +1,81 @@
1
+ import type { CrawleeLogger, CrawleeLoggerOptions } from '@crawlee/types';
1
2
  import type { LoggerOptions } from '@apify/log';
2
3
  import log, { Log, Logger, LoggerJson, LoggerText, LogLevel } from '@apify/log';
4
+ export type { CrawleeLogger, CrawleeLoggerOptions };
5
+ /**
6
+ * Abstract base class for custom Crawlee logger implementations.
7
+ *
8
+ * Subclasses must implement two methods:
9
+ * - {@link BaseCrawleeLogger.logWithLevel} — the core logging dispatch
10
+ * - {@link BaseCrawleeLogger.createChild} — how to create a child logger instance
11
+ *
12
+ * All other `CrawleeLogger` methods (`error`, `warning`, `info`, `debug`, etc.)
13
+ * are derived automatically. Level filtering is entirely the responsibility of the
14
+ * underlying library — `logWithLevel()` is called for every message.
15
+ *
16
+ * **Example — Winston adapter:**
17
+ * ```typescript
18
+ * const CRAWLEE_TO_WINSTON = { 1: 'error', 2: 'warn', 3: 'warn', 4: 'info', 5: 'debug', 6: 'debug' };
19
+ *
20
+ * class WinstonAdapter extends BaseCrawleeLogger {
21
+ * constructor(private logger: winston.Logger, options?: Partial<CrawleeLoggerOptions>) {
22
+ * super(options);
23
+ * }
24
+ *
25
+ * logWithLevel(level: number, message: string, data?: Record<string, unknown>): void {
26
+ * this.logger.log(CRAWLEE_TO_WINSTON[level] ?? 'info', message, data);
27
+ * }
28
+ *
29
+ * protected createChild(options: Partial<CrawleeLoggerOptions>): CrawleeLogger {
30
+ * return new WinstonAdapter(this.logger.child({ prefix: options.prefix }), { ...this.getOptions(), ...options });
31
+ * }
32
+ * }
33
+ * ```
34
+ */
35
+ export declare abstract class BaseCrawleeLogger implements CrawleeLogger {
36
+ #private;
37
+ constructor(options?: Partial<CrawleeLoggerOptions>);
38
+ /**
39
+ * Core logging method. Subclasses must implement this to dispatch log messages
40
+ * to the underlying logger (Winston, Pino, console, etc.).
41
+ *
42
+ * Level filtering is the responsibility of the underlying library — this method
43
+ * is called for every message regardless of the current level.
44
+ *
45
+ * @param level Crawlee log level (use {@link LogLevel} constants)
46
+ * @param message The log message
47
+ * @param data Optional structured data to attach to the log entry
48
+ */
49
+ abstract logWithLevel(level: number, message: string, data?: Record<string, unknown>): void;
50
+ /**
51
+ * Creates a child logger instance. Subclasses must implement this to define
52
+ * how child loggers are created for the underlying logger.
53
+ */
54
+ protected abstract createChild(options: Partial<CrawleeLoggerOptions>): CrawleeLogger;
55
+ getOptions(): CrawleeLoggerOptions;
56
+ setOptions(options: Partial<CrawleeLoggerOptions>): void;
57
+ child(options: Partial<CrawleeLoggerOptions>): CrawleeLogger;
58
+ error(message: string, data?: Record<string, unknown>): void;
59
+ exception(exception: Error, message: string, data?: Record<string, unknown>): void;
60
+ softFail(message: string, data?: Record<string, unknown>): void;
61
+ warning(message: string, data?: Record<string, unknown>): void;
62
+ warningOnce(message: string): void;
63
+ info(message: string, data?: Record<string, unknown>): void;
64
+ debug(message: string, data?: Record<string, unknown>): void;
65
+ perf(message: string, data?: Record<string, unknown>): void;
66
+ deprecated(message: string): void;
67
+ }
68
+ /**
69
+ * Adapter that wraps `@apify/log`'s {@link Log} instance to implement the {@link CrawleeLogger} interface.
70
+ *
71
+ * This is the default logger used by Crawlee when no custom logger is configured.
72
+ * Users who want to use a different logging library should implement {@link BaseCrawleeLogger} directly.
73
+ */
74
+ export declare class ApifyLogAdapter extends BaseCrawleeLogger {
75
+ #private;
76
+ constructor(apifyLog: Log, options?: Partial<CrawleeLoggerOptions>);
77
+ logWithLevel(level: number, message: string, data?: Record<string, unknown>): void;
78
+ protected createChild(options: Partial<CrawleeLoggerOptions>): CrawleeLogger;
79
+ }
3
80
  export { log, Log, LogLevel, Logger, LoggerJson, LoggerText };
4
81
  export type { LoggerOptions };
5
- //# sourceMappingURL=log.d.ts.map
package/log.js CHANGED
@@ -1,3 +1,106 @@
1
1
  import log, { Log, Logger, LoggerJson, LoggerText, LogLevel } from '@apify/log';
2
+ /**
3
+ * Abstract base class for custom Crawlee logger implementations.
4
+ *
5
+ * Subclasses must implement two methods:
6
+ * - {@link BaseCrawleeLogger.logWithLevel} — the core logging dispatch
7
+ * - {@link BaseCrawleeLogger.createChild} — how to create a child logger instance
8
+ *
9
+ * All other `CrawleeLogger` methods (`error`, `warning`, `info`, `debug`, etc.)
10
+ * are derived automatically. Level filtering is entirely the responsibility of the
11
+ * underlying library — `logWithLevel()` is called for every message.
12
+ *
13
+ * **Example — Winston adapter:**
14
+ * ```typescript
15
+ * const CRAWLEE_TO_WINSTON = { 1: 'error', 2: 'warn', 3: 'warn', 4: 'info', 5: 'debug', 6: 'debug' };
16
+ *
17
+ * class WinstonAdapter extends BaseCrawleeLogger {
18
+ * constructor(private logger: winston.Logger, options?: Partial<CrawleeLoggerOptions>) {
19
+ * super(options);
20
+ * }
21
+ *
22
+ * logWithLevel(level: number, message: string, data?: Record<string, unknown>): void {
23
+ * this.logger.log(CRAWLEE_TO_WINSTON[level] ?? 'info', message, data);
24
+ * }
25
+ *
26
+ * protected createChild(options: Partial<CrawleeLoggerOptions>): CrawleeLogger {
27
+ * return new WinstonAdapter(this.logger.child({ prefix: options.prefix }), { ...this.getOptions(), ...options });
28
+ * }
29
+ * }
30
+ * ```
31
+ */
32
+ export class BaseCrawleeLogger {
33
+ // Note: If wrapping logger in a Proxy, unbound methods calling #-fields throw TypeError
34
+ // unless bound to the target (see createLogProxy in adaptive-playwright-crawler.ts).
35
+ #options;
36
+ #warningsLogged = new Set();
37
+ constructor(options = {}) {
38
+ this.#options = options;
39
+ }
40
+ getOptions() {
41
+ return this.#options;
42
+ }
43
+ setOptions(options) {
44
+ this.#options = { ...this.#options, ...options };
45
+ }
46
+ child(options) {
47
+ return this.createChild(options);
48
+ }
49
+ error(message, data) {
50
+ this.logWithLevel(LogLevel.ERROR, message, data);
51
+ }
52
+ exception(exception, message, data) {
53
+ this.logWithLevel(LogLevel.ERROR, `${message}: ${exception.message}`, {
54
+ ...data,
55
+ stack: exception.stack,
56
+ exception,
57
+ });
58
+ }
59
+ softFail(message, data) {
60
+ this.logWithLevel(LogLevel.SOFT_FAIL, message, data);
61
+ }
62
+ warning(message, data) {
63
+ this.logWithLevel(LogLevel.WARNING, message, data);
64
+ }
65
+ warningOnce(message) {
66
+ if (!this.#warningsLogged.has(message)) {
67
+ this.#warningsLogged.add(message);
68
+ this.warning(message);
69
+ }
70
+ }
71
+ info(message, data) {
72
+ this.logWithLevel(LogLevel.INFO, message, data);
73
+ }
74
+ debug(message, data) {
75
+ this.logWithLevel(LogLevel.DEBUG, message, data);
76
+ }
77
+ perf(message, data) {
78
+ this.logWithLevel(LogLevel.PERF, `[PERF] ${message}`, data);
79
+ }
80
+ deprecated(message) {
81
+ this.warningOnce(`[DEPRECATED] ${message}`);
82
+ }
83
+ }
84
+ /**
85
+ * Adapter that wraps `@apify/log`'s {@link Log} instance to implement the {@link CrawleeLogger} interface.
86
+ *
87
+ * This is the default logger used by Crawlee when no custom logger is configured.
88
+ * Users who want to use a different logging library should implement {@link BaseCrawleeLogger} directly.
89
+ */
90
+ export class ApifyLogAdapter extends BaseCrawleeLogger {
91
+ #apifyLog;
92
+ constructor(apifyLog, options) {
93
+ super(options ?? {});
94
+ this.#apifyLog = apifyLog;
95
+ }
96
+ logWithLevel(level, message, data) {
97
+ this.#apifyLog.internal(level, message, data);
98
+ }
99
+ createChild(options) {
100
+ return new ApifyLogAdapter(this.#apifyLog.child({ prefix: options.prefix ?? null }), {
101
+ ...this.getOptions(),
102
+ ...options,
103
+ });
104
+ }
105
+ }
2
106
  export { log, Log, LogLevel, Logger, LoggerJson, LoggerText };
3
- //# sourceMappingURL=log.js.map
@@ -0,0 +1,4 @@
1
+ /**
2
+ * Length of id property of a Request instance in characters.
3
+ */
4
+ export declare const REQUEST_ID_LENGTH = 15;
@@ -0,0 +1,4 @@
1
+ /**
2
+ * Length of id property of a Request instance in characters.
3
+ */
4
+ export const REQUEST_ID_LENGTH = 15;
@@ -0,0 +1 @@
1
+ export * from './memory-storage.js';
@@ -0,0 +1 @@
1
+ export * from './memory-storage.js';
@@ -0,0 +1,44 @@
1
+ import type * as storage from '@crawlee/types';
2
+ import type { CrawleeLogger } from '@crawlee/types';
3
+ import { RequestQueueBackend } from './resource-clients/request-queue.js';
4
+ export interface MemoryStorageOptions {
5
+ /**
6
+ * Optional logger for MemoryStorageBackend warnings.
7
+ */
8
+ logger?: CrawleeLogger;
9
+ }
10
+ export declare class MemoryStorageBackend implements storage.StorageBackend {
11
+ #private;
12
+ readonly logger?: CrawleeLogger;
13
+ constructor(options?: MemoryStorageOptions);
14
+ /**
15
+ * Return a per-instance unique cache key so that distinct `MemoryStorageBackend` instances get separate
16
+ * cache partitions in the storage backend cache.
17
+ */
18
+ getStorageBackendCacheKey(): string;
19
+ /**
20
+ * Evict a cached backend so that a dropped storage is no longer resolved by `createXBackend`,
21
+ * reported by `storageExists` or visited by `purge`. Returns whether the backend was cached, which
22
+ * tells the caller whether it still owns in-memory state worth clearing.
23
+ *
24
+ * The resource clients own their own entry's lifetime but must not reach into the caches directly.
25
+ * Because a client is only ever constructed by `createXBackend`, which caches it immediately, the
26
+ * entry matching `id` is always the caller itself.
27
+ * @internal
28
+ */
29
+ evictBackend(type: 'Dataset' | 'KeyValueStore' | 'RequestQueue', id: string): boolean;
30
+ createDatasetBackend(options?: storage.StorageIdentifier): Promise<storage.DatasetBackend>;
31
+ createKeyValueStoreBackend(options?: storage.StorageIdentifier): Promise<storage.KeyValueStoreBackend>;
32
+ createRequestQueueBackend(options?: storage.StorageIdentifier): Promise<RequestQueueBackend>;
33
+ storageExists(id: string, type: 'Dataset' | 'KeyValueStore' | 'RequestQueue'): Promise<boolean>;
34
+ /**
35
+ * Cleans up the run-scoped storages before the run starts. For the in-memory storage this simply
36
+ * resets the in-memory state of the cached backends.
37
+ */
38
+ purge(): Promise<void>;
39
+ /**
40
+ * This method should be called at the end of the process. The in-memory storage holds no resources
41
+ * that outlive the process (no file handles, no cross-process locks), so there is nothing to do.
42
+ */
43
+ teardown(): Promise<void>;
44
+ }