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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (259) hide show
  1. package/README.md +17 -13
  2. package/byte_utils.d.ts +17 -0
  3. package/byte_utils.js +42 -0
  4. package/configuration.d.ts +88 -234
  5. package/configuration.js +162 -230
  6. package/debug.d.ts +36 -0
  7. package/debug.js +70 -0
  8. package/errors.d.ts +43 -10
  9. package/errors.js +57 -12
  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 -5
  15. package/events/local_event_manager.js +39 -42
  16. package/events/system_info.d.ts +38 -0
  17. package/events/system_info.js +1 -0
  18. package/index.d.ts +8 -11
  19. package/index.js +9 -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 +81 -3
  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 +43 -0
  31. package/memory-storage/memory-storage.js +158 -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 +56 -0
  37. package/memory-storage/resource-clients/key-value-store.js +180 -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 +19 -20
  45. package/proxy_configuration.d.ts +29 -155
  46. package/proxy_configuration.js +38 -183
  47. package/recoverable_state.d.ts +177 -0
  48. package/recoverable_state.js +268 -0
  49. package/request.d.ts +62 -81
  50. package/request.js +125 -220
  51. package/serialization.d.ts +0 -1
  52. package/serialization.js +18 -18
  53. package/service_locator.d.ts +168 -0
  54. package/service_locator.js +255 -0
  55. package/storages/batched_adds.d.ts +37 -0
  56. package/storages/batched_adds.js +73 -0
  57. package/storages/dataset.d.ts +120 -56
  58. package/storages/dataset.js +299 -148
  59. package/storages/index.d.ts +9 -8
  60. package/storages/index.js +5 -8
  61. package/storages/key_value_store.d.ts +192 -65
  62. package/storages/key_value_store.js +453 -193
  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 +55 -137
  68. package/storages/request_list.js +272 -245
  69. package/storages/request_loader.d.ts +127 -0
  70. package/storages/request_loader.js +36 -0
  71. package/storages/request_manager.d.ts +119 -0
  72. package/storages/request_manager.js +1 -0
  73. package/storages/request_manager_tandem.d.ts +94 -0
  74. package/storages/request_manager_tandem.js +200 -0
  75. package/storages/request_queue.d.ts +293 -48
  76. package/storages/request_queue.js +766 -216
  77. package/storages/storage_instance_manager.d.ts +86 -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 +271 -0
  82. package/storages/transaction.js +296 -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 -292
  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 -113
  120. package/cookie_utils.js.map +0 -1
  121. package/crawlers/crawler_commons.d.ts +0 -199
  122. package/crawlers/crawler_commons.d.ts.map +0 -1
  123. package/crawlers/crawler_commons.js +0 -116
  124. package/crawlers/crawler_commons.js.map +0 -1
  125. package/crawlers/crawler_extension.d.ts +0 -12
  126. package/crawlers/crawler_extension.d.ts.map +0 -1
  127. package/crawlers/crawler_extension.js +0 -14
  128. package/crawlers/crawler_extension.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 -59
  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 -54
  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/statistics.d.ts +0 -204
  146. package/crawlers/statistics.d.ts.map +0 -1
  147. package/crawlers/statistics.js +0 -346
  148. package/crawlers/statistics.js.map +0 -1
  149. package/enqueue_links/enqueue_links.d.ts +0 -242
  150. package/enqueue_links/enqueue_links.d.ts.map +0 -1
  151. package/enqueue_links/enqueue_links.js +0 -250
  152. package/enqueue_links/enqueue_links.js.map +0 -1
  153. package/enqueue_links/index.d.ts +0 -3
  154. package/enqueue_links/index.d.ts.map +0 -1
  155. package/enqueue_links/index.js +0 -3
  156. package/enqueue_links/index.js.map +0 -1
  157. package/enqueue_links/shared.d.ts +0 -67
  158. package/enqueue_links/shared.d.ts.map +0 -1
  159. package/enqueue_links/shared.js +0 -190
  160. package/enqueue_links/shared.js.map +0 -1
  161. package/errors.d.ts.map +0 -1
  162. package/errors.js.map +0 -1
  163. package/events/event_manager.d.ts.map +0 -1
  164. package/events/event_manager.js.map +0 -1
  165. package/events/index.d.ts.map +0 -1
  166. package/events/index.js.map +0 -1
  167. package/events/local_event_manager.d.ts.map +0 -1
  168. package/events/local_event_manager.js.map +0 -1
  169. package/http_clients/base-http-client.d.ts +0 -134
  170. package/http_clients/base-http-client.d.ts.map +0 -1
  171. package/http_clients/base-http-client.js +0 -33
  172. package/http_clients/base-http-client.js.map +0 -1
  173. package/http_clients/form-data-like.d.ts +0 -67
  174. package/http_clients/form-data-like.d.ts.map +0 -1
  175. package/http_clients/form-data-like.js +0 -5
  176. package/http_clients/form-data-like.js.map +0 -1
  177. package/http_clients/got-scraping-http-client.d.ts +0 -15
  178. package/http_clients/got-scraping-http-client.d.ts.map +0 -1
  179. package/http_clients/got-scraping-http-client.js +0 -69
  180. package/http_clients/got-scraping-http-client.js.map +0 -1
  181. package/http_clients/index.d.ts +0 -3
  182. package/http_clients/index.d.ts.map +0 -1
  183. package/http_clients/index.js +0 -3
  184. package/http_clients/index.js.map +0 -1
  185. package/index.d.ts.map +0 -1
  186. package/index.js.map +0 -1
  187. package/log.d.ts.map +0 -1
  188. package/log.js.map +0 -1
  189. package/proxy_configuration.d.ts.map +0 -1
  190. package/proxy_configuration.js.map +0 -1
  191. package/request.d.ts.map +0 -1
  192. package/request.js.map +0 -1
  193. package/router.d.ts +0 -134
  194. package/router.d.ts.map +0 -1
  195. package/router.js +0 -164
  196. package/router.js.map +0 -1
  197. package/serialization.d.ts.map +0 -1
  198. package/serialization.js.map +0 -1
  199. package/session_pool/consts.d.ts +0 -4
  200. package/session_pool/consts.d.ts.map +0 -1
  201. package/session_pool/consts.js +0 -4
  202. package/session_pool/consts.js.map +0 -1
  203. package/session_pool/errors.d.ts +0 -8
  204. package/session_pool/errors.d.ts.map +0 -1
  205. package/session_pool/errors.js +0 -12
  206. package/session_pool/errors.js.map +0 -1
  207. package/session_pool/events.d.ts +0 -3
  208. package/session_pool/events.d.ts.map +0 -1
  209. package/session_pool/events.js +0 -3
  210. package/session_pool/events.js.map +0 -1
  211. package/session_pool/index.d.ts +0 -6
  212. package/session_pool/index.d.ts.map +0 -1
  213. package/session_pool/index.js +0 -6
  214. package/session_pool/index.js.map +0 -1
  215. package/session_pool/session.d.ts +0 -199
  216. package/session_pool/session.d.ts.map +0 -1
  217. package/session_pool/session.js +0 -271
  218. package/session_pool/session.js.map +0 -1
  219. package/session_pool/session_pool.d.ts +0 -251
  220. package/session_pool/session_pool.d.ts.map +0 -1
  221. package/session_pool/session_pool.js +0 -375
  222. package/session_pool/session_pool.js.map +0 -1
  223. package/storages/access_checking.d.ts +0 -13
  224. package/storages/access_checking.d.ts.map +0 -1
  225. package/storages/access_checking.js +0 -14
  226. package/storages/access_checking.js.map +0 -1
  227. package/storages/dataset.d.ts.map +0 -1
  228. package/storages/dataset.js.map +0 -1
  229. package/storages/index.d.ts.map +0 -1
  230. package/storages/index.js.map +0 -1
  231. package/storages/key_value_store.d.ts.map +0 -1
  232. package/storages/key_value_store.js.map +0 -1
  233. package/storages/request_list.d.ts.map +0 -1
  234. package/storages/request_list.js.map +0 -1
  235. package/storages/request_provider.d.ts +0 -307
  236. package/storages/request_provider.d.ts.map +0 -1
  237. package/storages/request_provider.js +0 -555
  238. package/storages/request_provider.js.map +0 -1
  239. package/storages/request_queue.d.ts.map +0 -1
  240. package/storages/request_queue.js.map +0 -1
  241. package/storages/request_queue_v2.d.ts +0 -87
  242. package/storages/request_queue_v2.d.ts.map +0 -1
  243. package/storages/request_queue_v2.js +0 -438
  244. package/storages/request_queue_v2.js.map +0 -1
  245. package/storages/sitemap_request_list.d.ts +0 -245
  246. package/storages/sitemap_request_list.d.ts.map +0 -1
  247. package/storages/sitemap_request_list.js +0 -430
  248. package/storages/sitemap_request_list.js.map +0 -1
  249. package/storages/storage_manager.d.ts +0 -58
  250. package/storages/storage_manager.d.ts.map +0 -1
  251. package/storages/storage_manager.js +0 -105
  252. package/storages/storage_manager.js.map +0 -1
  253. package/storages/utils.d.ts.map +0 -1
  254. package/storages/utils.js.map +0 -1
  255. package/tsconfig.build.tsbuildinfo +0 -1
  256. package/typedefs.d.ts.map +0 -1
  257. package/typedefs.js.map +0 -1
  258. package/validators.d.ts.map +0 -1
  259. package/validators.js.map +0 -1
package/errors.js CHANGED
@@ -1,3 +1,4 @@
1
+ import { inspectValue } from './debug.js';
1
2
  /**
2
3
  * Errors of `NonRetryableError` type will never be retried by the crawler.
3
4
  */
@@ -9,29 +10,73 @@ export class NonRetryableError extends Error {
9
10
  */
10
11
  export class CriticalError extends NonRetryableError {
11
12
  }
13
+ function formatIssues(issues) {
14
+ return issues
15
+ .map((issue) => {
16
+ const path = (issue.path ?? [])
17
+ .map((segment) => (typeof segment === 'object' ? segment.key : segment))
18
+ .join('.');
19
+ return `- ${path ? `${path}: ` : ''}${issue.message}`;
20
+ })
21
+ .join('\n');
22
+ }
12
23
  /**
13
- * @ignore
24
+ * Thrown when a request's `userData` does not match the {@link RouteSchemas|Standard Schema} registered for its label.
25
+ *
26
+ * As the `userData` does not change between attempts, this error is non-retryable.
14
27
  */
15
- export class MissingRouteError extends CriticalError {
28
+ export class RequestValidationError extends NonRetryableError {
29
+ label;
30
+ issues;
31
+ constructor(label, issues) {
32
+ super(`Request userData for label '${String(label)}' failed schema validation:\n${formatIssues(issues)}`);
33
+ this.label = label;
34
+ this.issues = issues;
35
+ }
16
36
  }
17
37
  /**
18
- * Errors of `RetryRequestError` type will always be retried by the crawler.
38
+ * Thrown by {@link RecoverableState} when a persisted state record does not match its `stateSchema`.
19
39
  *
20
- * *This error overrides the `maxRequestRetries` option, i.e. the request can be retried indefinitely until it succeeds.*
40
+ * Whether a corrupt record should abort the run or be discarded in favour of the defaults depends on what the
41
+ * state is for, so {@link RecoverableState.initialize} always throws and leaves the choice to the caller.
21
42
  */
22
- export class RetryRequestError extends Error {
23
- constructor(message) {
24
- super(message ?? "Request is being retried at the user's request");
43
+ export class StateValidationError extends Error {
44
+ persistStateKey;
45
+ issues;
46
+ constructor(persistStateKey, issues) {
47
+ super(`State persisted under key '${persistStateKey}' failed schema validation:\n${formatIssues(issues)}`);
48
+ this.persistStateKey = persistStateKey;
49
+ this.issues = issues;
25
50
  }
26
51
  }
27
52
  /**
28
- * Errors of `SessionError` type will trigger a session rotation.
53
+ * Errors of `SessionError` type retire the session associated with the request and trigger a regular retry.
29
54
  *
30
- * This error doesn't respect the `maxRequestRetries` option and has a separate limit of `maxSessionRotations`.
55
+ * The retry counts towards the `maxRequestRetries` limit, just like any other error.
31
56
  */
32
- export class SessionError extends RetryRequestError {
57
+ export class SessionError extends Error {
33
58
  constructor(message) {
34
- super(`Detected a session error, rotating session... ${message ? `\n${message}` : ''}`);
59
+ super(`Detected a session error, retiring session... ${message ? `\n${message}` : ''}`);
60
+ }
61
+ }
62
+ /**
63
+ * Wraps the failure of a callback registered with {@link StorageTransaction.afterCommit|`afterCommit`}
64
+ * that ran after the request's writes had already been committed.
65
+ *
66
+ * Non-retryable by nature: the writes are durable, so re-running the request handler would duplicate
67
+ * them. A callback that throws a `NonRetryableError` of its own is left alone.
68
+ */
69
+ export class AfterCommitError extends NonRetryableError {
70
+ constructor(cause) {
71
+ super(cause instanceof Error ? cause.message : String(cause), { cause });
72
+ }
73
+ }
74
+ /**
75
+ * Thrown when attempting to set a different service instance after one has already been retrieved.
76
+ */
77
+ export class ServiceConflictError extends Error {
78
+ constructor(serviceName, newValue, existingValue) {
79
+ super(`Service ${serviceName} is already in use. ` +
80
+ `Existing value: ${inspectValue(existingValue)}, attempted new value: ${inspectValue(newValue)}.`);
35
81
  }
36
82
  }
37
- //# sourceMappingURL=errors.js.map
@@ -1,28 +1,55 @@
1
1
  import { AsyncEventEmitter } from '@vladfrangu/async_event_emitter';
2
2
  import type { BetterIntervalID } from '@apify/utilities';
3
- import { Configuration } from '../configuration.js';
4
- export declare const enum EventType {
3
+ export interface EventManagerOptions {
4
+ /** Interval between emitted `persistState` events in milliseconds. */
5
+ persistStateIntervalMillis: number;
6
+ }
7
+ export declare enum EventType {
5
8
  PERSIST_STATE = "persistState",
6
9
  SYSTEM_INFO = "systemInfo",
7
10
  MIGRATING = "migrating",
8
11
  ABORTING = "aborting",
9
- EXIT = "exit"
12
+ EXIT = "exit",
13
+ STATUS_MESSAGE = "statusMessage"
14
+ }
15
+ export type EventTypeName = EventType | 'systemInfo' | 'persistState' | 'migrating' | 'aborting' | 'exit' | 'statusMessage';
16
+ /**
17
+ * Payload emitted with the {@link EventType.STATUS_MESSAGE|`statusMessage`} event.
18
+ *
19
+ * The crawler broadcasts these whenever it wants to report its progress (e.g. periodically, or on
20
+ * start/finish). Consumers such as the Apify SDK can listen for the event and propagate the message
21
+ * to the platform. This keeps the crawler decoupled from any specific status-reporting backend.
22
+ */
23
+ export interface EventStatusMessageData {
24
+ /**
25
+ * Identifies the crawler that emitted the message.
26
+ *
27
+ * Either the user-provided `id` from the crawler options, or a randomly generated one.
28
+ * Since a single event manager may be shared by multiple crawlers, consumers can use this
29
+ * to attribute the message to a specific crawler instance.
30
+ */
31
+ crawlerId: string;
32
+ /** The human-readable status message. */
33
+ message: string;
34
+ /** Whether this is the final status message of the run. */
35
+ isStatusMessageTerminal?: boolean;
36
+ /** The log level the message was logged with. */
37
+ level?: 'DEBUG' | 'INFO' | 'WARNING' | 'ERROR';
10
38
  }
11
- export type EventTypeName = EventType | 'systemInfo' | 'persistState' | 'migrating' | 'aborting' | 'exit';
12
39
  interface Intervals {
13
40
  persistState?: BetterIntervalID;
14
41
  systemInfo?: BetterIntervalID;
15
42
  }
16
43
  export declare abstract class EventManager {
17
- readonly config: Configuration;
44
+ #private;
18
45
  protected events: AsyncEventEmitter<{}>;
19
46
  protected initialized: boolean;
20
47
  protected intervals: Intervals;
21
48
  // @ts-ignore optional peer dependency or compatibility with es2022
22
- protected log: import("@apify/log").Log;
23
- constructor(config?: Configuration);
49
+ protected log: import("@crawlee/types").CrawleeLogger;
50
+ constructor(options: EventManagerOptions);
24
51
  /**
25
- * Initializes the event manager by creating the `persistState` event interval.
52
+ * Initializes the event manager by starting the `persistState` event interval.
26
53
  * This is automatically called at the beginning of `crawler.run()`.
27
54
  */
28
55
  init(): Promise<void>;
@@ -49,4 +76,3 @@ export declare abstract class EventManager {
49
76
  waitForAllListenersToComplete(): Promise<boolean>;
50
77
  }
51
78
  export {};
52
- //# sourceMappingURL=event_manager.d.ts.map
@@ -1,7 +1,6 @@
1
1
  import { AsyncEventEmitter } from '@vladfrangu/async_event_emitter';
2
- import log from '@apify/log';
3
2
  import { betterClearInterval, betterSetInterval } from '@apify/utilities';
4
- import { Configuration } from '../configuration.js';
3
+ import { serviceLocator } from '../service_locator.js';
5
4
  export var EventType;
6
5
  (function (EventType) {
7
6
  EventType["PERSIST_STATE"] = "persistState";
@@ -9,30 +8,31 @@ export var EventType;
9
8
  EventType["MIGRATING"] = "migrating";
10
9
  EventType["ABORTING"] = "aborting";
11
10
  EventType["EXIT"] = "exit";
11
+ EventType["STATUS_MESSAGE"] = "statusMessage";
12
12
  })(EventType || (EventType = {}));
13
13
  export class EventManager {
14
- config;
15
14
  events = new AsyncEventEmitter();
16
15
  initialized = false;
17
16
  intervals = {};
18
- log = log.child({ prefix: 'Events' });
19
- constructor(config = Configuration.getGlobalConfig()) {
20
- this.config = config;
21
- this.events.setMaxListeners(50);
17
+ log = serviceLocator.getLogger().child({ prefix: 'Events' });
18
+ #persistStateIntervalMillis;
19
+ constructor(options) {
20
+ this.#persistStateIntervalMillis = options.persistStateIntervalMillis;
21
+ // One MIGRATING listener per RequestQueue, and ThrottlingRequestManager opens one per domain.
22
+ this.events.setMaxListeners(150);
22
23
  }
23
24
  /**
24
- * Initializes the event manager by creating the `persistState` event interval.
25
+ * Initializes the event manager by starting the `persistState` event interval.
25
26
  * This is automatically called at the beginning of `crawler.run()`.
26
27
  */
27
28
  async init() {
28
29
  if (this.initialized) {
29
30
  return;
30
31
  }
31
- const persistStateIntervalMillis = this.config.get('persistStateIntervalMillis');
32
32
  this.intervals.persistState = betterSetInterval((intervalCallback) => {
33
- this.emit("persistState" /* EventType.PERSIST_STATE */, { isMigrating: false });
33
+ this.emit(EventType.PERSIST_STATE, { isMigrating: false });
34
34
  intervalCallback();
35
- }, persistStateIntervalMillis);
35
+ }, this.#persistStateIntervalMillis);
36
36
  this.initialized = true;
37
37
  }
38
38
  /**
@@ -46,7 +46,7 @@ export class EventManager {
46
46
  betterClearInterval(this.intervals.persistState);
47
47
  this.initialized = false;
48
48
  // Emit final PERSIST_STATE event
49
- this.emit("persistState" /* EventType.PERSIST_STATE */, { isMigrating: false });
49
+ this.emit(EventType.PERSIST_STATE, { isMigrating: false });
50
50
  // Wait for PERSIST_STATE to process
51
51
  await this.waitForAllListenersToComplete();
52
52
  }
@@ -86,4 +86,3 @@ export class EventManager {
86
86
  return this.events.waitForAllListenersToComplete();
87
87
  }
88
88
  }
89
- //# sourceMappingURL=event_manager.js.map
package/events/index.d.ts CHANGED
@@ -1,3 +1,3 @@
1
1
  export * from './event_manager.js';
2
2
  export * from './local_event_manager.js';
3
- //# sourceMappingURL=index.d.ts.map
3
+ export type * from './system_info.js';
package/events/index.js CHANGED
@@ -1,3 +1,2 @@
1
1
  export * from './event_manager.js';
2
2
  export * from './local_event_manager.js';
3
- //# sourceMappingURL=index.js.map
@@ -1,8 +1,19 @@
1
- import { EventManager } from './event_manager.js';
1
+ import type { Configuration } from '../configuration.js';
2
+ import { EventManager, type EventManagerOptions } from './event_manager.js';
3
+ export interface LocalEventManagerOptions extends EventManagerOptions {
4
+ /** Interval between emitted `systemInfo` events in milliseconds. */
5
+ systemInfoIntervalMillis: number;
6
+ }
2
7
  export declare class LocalEventManager extends EventManager {
3
- private previousTicks;
8
+ #private;
9
+ constructor(options: LocalEventManagerOptions);
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?: Configuration): LocalEventManager;
4
15
  /**
5
- * Initializes the EventManager and sets up periodic `systemInfo` and `persistState` events.
16
+ * Initializes the EventManager and sets up periodic `systemInfo` events.
6
17
  * This is automatically called at the beginning of `crawler.run()`.
7
18
  */
8
19
  init(): Promise<void>;
@@ -18,12 +29,11 @@ export declare class LocalEventManager extends EventManager {
18
29
  * @internal
19
30
  */
20
31
  isContainerizedWrapper(): Promise<boolean>;
21
- private getCurrentCpuTicks;
22
32
  /**
23
33
  * Creates a SystemInfo object based on local metrics.
24
34
  */
25
35
  private createSystemInfo;
26
36
  private createCpuInfo;
27
37
  private createMemoryInfo;
38
+ private getMemoryInfo;
28
39
  }
29
- //# sourceMappingURL=local_event_manager.d.ts.map
@@ -1,12 +1,25 @@
1
- import os from 'node:os';
2
- import { getCurrentCpuTicksV2, getMemoryInfo, getMemoryInfoV2, isContainerized } from '@crawlee/utils';
3
- import log from '@apify/log';
4
1
  import { betterClearInterval, betterSetInterval } from '@apify/utilities';
5
- import { EventManager } from './event_manager.js';
2
+ import { serviceLocator } from '../service_locator.js';
3
+ import { EventManager, EventType } from './event_manager.js';
6
4
  export class LocalEventManager extends EventManager {
7
- previousTicks = { idle: 0, total: 0 };
5
+ #systemInfoIntervalMillis;
6
+ constructor(options) {
7
+ super(options);
8
+ this.#systemInfoIntervalMillis = options.systemInfoIntervalMillis;
9
+ }
8
10
  /**
9
- * Initializes the EventManager and sets up periodic `systemInfo` and `persistState` events.
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
+ }
21
+ /**
22
+ * Initializes the EventManager and sets up periodic `systemInfo` events.
10
23
  * This is automatically called at the beginning of `crawler.run()`.
11
24
  */
12
25
  async init() {
@@ -14,9 +27,8 @@ export class LocalEventManager extends EventManager {
14
27
  return;
15
28
  }
16
29
  await super.init();
17
- const systemInfoIntervalMillis = this.config.get('systemInfoIntervalMillis');
18
30
  this.emitSystemInfoEvent = this.emitSystemInfoEvent.bind(this);
19
- this.intervals.systemInfo = betterSetInterval(this.emitSystemInfoEvent.bind(this), systemInfoIntervalMillis);
31
+ this.intervals.systemInfo = betterSetInterval(this.emitSystemInfoEvent.bind(this), this.#systemInfoIntervalMillis);
20
32
  }
21
33
  /**
22
34
  * @inheritDoc
@@ -33,26 +45,17 @@ export class LocalEventManager extends EventManager {
33
45
  */
34
46
  async emitSystemInfoEvent(intervalCallback) {
35
47
  const info = await this.createSystemInfo({
36
- maxUsedCpuRatio: this.config.get('maxUsedCpuRatio'),
48
+ maxUsedCpuRatio: serviceLocator.getConfiguration().maxUsedCpuRatio,
37
49
  });
38
- this.events.emit("systemInfo" /* EventType.SYSTEM_INFO */, info);
50
+ this.events.emit(EventType.SYSTEM_INFO, info);
39
51
  intervalCallback();
40
52
  }
41
53
  /**
42
54
  * @internal
43
55
  */
44
56
  async isContainerizedWrapper() {
45
- return this.config.get('containerized', await isContainerized());
46
- }
47
- getCurrentCpuTicks() {
48
- const cpus = os.cpus();
49
- return cpus.reduce((acc, cpu) => {
50
- const cpuTimes = Object.values(cpu.times);
51
- return {
52
- idle: acc.idle + cpu.times.idle,
53
- total: acc.total + cpuTimes.reduce((sum, num) => sum + num),
54
- };
55
- }, { idle: 0, total: 0 });
57
+ const { isContainerized } = await import('../system-info/runtime.js');
58
+ return serviceLocator.getConfiguration().containerized ?? (await isContainerized());
56
59
  }
57
60
  /**
58
61
  * Creates a SystemInfo object based on local metrics.
@@ -65,18 +68,11 @@ export class LocalEventManager extends EventManager {
65
68
  };
66
69
  }
67
70
  async createCpuInfo(options) {
68
- if (this.config.get('systemInfoV2')) {
69
- const usedCpuRatio = await getCurrentCpuTicksV2(await this.isContainerizedWrapper());
70
- return {
71
- cpuCurrentUsage: usedCpuRatio * 100,
72
- isCpuOverloaded: usedCpuRatio > options.maxUsedCpuRatio,
73
- };
74
- }
75
- const ticks = this.getCurrentCpuTicks();
76
- const idleTicksDelta = ticks.idle - this.previousTicks.idle;
77
- const totalTicksDelta = ticks.total - this.previousTicks.total;
78
- const usedCpuRatio = totalTicksDelta ? 1 - idleTicksDelta / totalTicksDelta : 0;
79
- Object.assign(this.previousTicks, ticks);
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
+ });
80
76
  return {
81
77
  cpuCurrentUsage: usedCpuRatio * 100,
82
78
  isCpuOverloaded: usedCpuRatio > options.maxUsedCpuRatio,
@@ -84,21 +80,22 @@ export class LocalEventManager extends EventManager {
84
80
  }
85
81
  async createMemoryInfo() {
86
82
  try {
87
- if (this.config.get('systemInfoV2')) {
88
- const memInfo = await getMemoryInfoV2(await this.isContainerizedWrapper());
89
- return {
90
- memCurrentBytes: memInfo.mainProcessBytes + memInfo.childProcessesBytes,
91
- };
92
- }
93
- const memInfo = await getMemoryInfo();
83
+ const memInfo = await this.getMemoryInfo();
94
84
  return {
85
+ memTotalBytes: memInfo.totalBytes,
95
86
  memCurrentBytes: memInfo.mainProcessBytes + memInfo.childProcessesBytes,
96
87
  };
97
88
  }
98
89
  catch (err) {
99
- log.exception(err, 'Memory snapshot failed.');
90
+ this.log.exception(err, 'Memory snapshot failed.');
100
91
  return {};
101
92
  }
102
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
+ }
103
101
  }
104
- //# sourceMappingURL=local_event_manager.js.map
@@ -0,0 +1,38 @@
1
+ /**
2
+ * Represents the current status of the system.
3
+ */
4
+ export interface SystemInfo {
5
+ /** If false, system is being overloaded. */
6
+ isSystemIdle: boolean;
7
+ memInfo: LoadSignalInfo;
8
+ eventLoopInfo: LoadSignalInfo;
9
+ cpuInfo: LoadSignalInfo;
10
+ storageBackendInfo: LoadSignalInfo;
11
+ memTotalBytes?: number;
12
+ memCurrentBytes?: number;
13
+ /**
14
+ * Platform only property
15
+ * @internal
16
+ */
17
+ cpuCurrentUsage?: number;
18
+ /**
19
+ * Platform only property
20
+ * @internal
21
+ */
22
+ isCpuOverloaded?: boolean;
23
+ /**
24
+ * Platform only property
25
+ * @internal
26
+ */
27
+ createdAt?: Date;
28
+ /**
29
+ * Status of additional load signals beyond the built-in four.
30
+ * Keys are `LoadSignal.name` values, values are overload info.
31
+ */
32
+ loadSignalInfo?: Record<string, LoadSignalInfo>;
33
+ }
34
+ export interface LoadSignalInfo {
35
+ isOverloaded: boolean;
36
+ limitRatio: number;
37
+ actualRatio: number;
38
+ }
@@ -0,0 +1 @@
1
+ export {};
package/index.d.ts CHANGED
@@ -1,19 +1,16 @@
1
+ export * from './debug.js';
1
2
  export * from './errors.js';
2
- export * from './autoscaling/index.js';
3
3
  export * from './configuration.js';
4
- export * from './crawlers/index.js';
5
- export * from './enqueue_links/index.js';
4
+ export * from './service_locator.js';
6
5
  export * from './events/index.js';
7
- export * from './http_clients/index.js';
8
6
  export * from './log.js';
7
+ export * from './owned_or_injected.js';
9
8
  export * from './proxy_configuration.js';
10
9
  export * from './request.js';
11
- export * from './router.js';
12
10
  export * from './serialization.js';
13
- export * from './session_pool/index.js';
14
11
  export * from './storages/index.js';
15
- export * from './validators.js';
16
- export * from './cookie_utils.js';
17
- export { PseudoUrl } from '@apify/pseudo_url';
18
- export { Dictionary, Awaitable, Constructor, StorageClient, Cookie, QueueOperationInfo } from '@crawlee/types';
19
- //# sourceMappingURL=index.d.ts.map
12
+ export * from './memory-storage/index.js';
13
+ export { ArgumentValidationError, validators } from './validators.js';
14
+ export * from './recoverable_state.js';
15
+ export type { StorageBackend } from '@crawlee/types';
16
+ export { EnqueueStrategy } from '@crawlee/utils';
package/index.js CHANGED
@@ -1,18 +1,17 @@
1
+ export * from './debug.js';
1
2
  export * from './errors.js';
2
- export * from './autoscaling/index.js';
3
3
  export * from './configuration.js';
4
- export * from './crawlers/index.js';
5
- export * from './enqueue_links/index.js';
4
+ export * from './service_locator.js';
6
5
  export * from './events/index.js';
7
- export * from './http_clients/index.js';
8
6
  export * from './log.js';
7
+ export * from './owned_or_injected.js';
9
8
  export * from './proxy_configuration.js';
10
9
  export * from './request.js';
11
- export * from './router.js';
12
10
  export * from './serialization.js';
13
- export * from './session_pool/index.js';
14
11
  export * from './storages/index.js';
15
- export * from './validators.js';
16
- export * from './cookie_utils.js';
17
- export { PseudoUrl } from '@apify/pseudo_url';
18
- //# sourceMappingURL=index.js.map
12
+ export * from './memory-storage/index.js';
13
+ // Not `export *`: the rest of the module re-exports `@crawlee/utils/internal` symbols, which carry no
14
+ // semver guarantees and must not reach the public surface. Internal consumers import them directly.
15
+ export { ArgumentValidationError, validators } from './validators.js';
16
+ export * from './recoverable_state.js';
17
+ export { EnqueueStrategy } from '@crawlee/utils';
package/internal.d.ts ADDED
@@ -0,0 +1,8 @@
1
+ export * from './iterables.js';
2
+ export * from './storages/batched_adds.js';
3
+ export { joinRequestSourceStatuses } from './storages/request_loader.js';
4
+ export * from './system-info/cpu-info.js';
5
+ export * from './system-info/memory-info.js';
6
+ export * from './system-info/ps-tree.js';
7
+ export * from './system-info/runtime.js';
8
+ export * from './url.js';
package/internal.js ADDED
@@ -0,0 +1,9 @@
1
+ // Not part of the public API: internals that other Crawlee packages need but that carry no semver guarantees.
2
+ export * from './iterables.js';
3
+ export * from './storages/batched_adds.js';
4
+ export { joinRequestSourceStatuses } from './storages/request_loader.js';
5
+ export * from './system-info/cpu-info.js';
6
+ export * from './system-info/memory-info.js';
7
+ export * from './system-info/ps-tree.js';
8
+ export * from './system-info/runtime.js';
9
+ export * from './url.js';
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>;