@crawlee/core 4.0.0-beta.14 → 4.0.0-beta.141

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 +67 -172
  3. package/autoscaling/autoscaled_pool.js +182 -329
  4. package/autoscaling/concurrency_system.d.ts +269 -0
  5. package/autoscaling/concurrency_system.js +365 -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 +100 -0
  13. package/autoscaling/load_signal.js +105 -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 -63
  43. package/crawlers/statistics.js +354 -164
  44. package/debug.d.ts +36 -0
  45. package/debug.js +70 -0
  46. package/enqueue_links/enqueue_links.d.ts +60 -153
  47. package/enqueue_links/enqueue_links.js +38 -229
  48. package/enqueue_links/index.d.ts +0 -1
  49. package/enqueue_links/index.js +0 -1
  50. package/enqueue_links/shared.d.ts +49 -30
  51. package/enqueue_links/shared.js +94 -68
  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 +78 -1
  67. package/log.js +106 -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 +35 -88
  108. package/session_pool/session.js +101 -159
  109. package/session_pool/session_pool.d.ts +74 -91
  110. package/session_pool/session_pool.js +175 -165
  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 +283 -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 +445 -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 +52 -109
  124. package/storages/request_list.js +183 -152
  125. package/storages/request_loader.d.ts +101 -0
  126. package/storages/request_loader.js +1 -0
  127. package/storages/request_manager.d.ts +33 -0
  128. package/storages/request_manager.js +1 -0
  129. package/storages/request_manager_tandem.d.ts +48 -19
  130. package/storages/request_manager_tandem.js +118 -45
  131. package/storages/request_queue.d.ts +290 -47
  132. package/storages/request_queue.js +762 -216
  133. package/storages/{sitemap_request_list.d.ts → sitemap_request_loader.d.ts} +45 -89
  134. package/storages/sitemap_request_loader.js +438 -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 +239 -0
  140. package/storages/throttling_request_manager.js +646 -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
@@ -0,0 +1,253 @@
1
+ import { AsyncLocalStorage } from 'node:async_hooks';
2
+ import { FileSystemStorageBackend } from '@crawlee/fs-storage';
3
+ import log from '@apify/log';
4
+ import { Configuration } from './configuration.js';
5
+ import { ServiceConflictError } from './errors.js';
6
+ import { LocalEventManager } from './events/local_event_manager.js';
7
+ import { ApifyLogAdapter } from './log.js';
8
+ import { MemoryStorageBackend } from './memory-storage/index.js';
9
+ import { StorageInstanceManager } from './storages/storage_instance_manager.js';
10
+ /**
11
+ * Service locator for managing the services used by Crawlee.
12
+ *
13
+ * All services are initialized to their default value lazily.
14
+ *
15
+ * There are two primary usage patterns:
16
+ *
17
+ * **1. Global service locator (for default services):**
18
+ * ```typescript
19
+ * import { serviceLocator, BasicCrawler } from 'crawlee';
20
+ *
21
+ * // Optionally configure global services before creating crawlers
22
+ * serviceLocator.setStorageBackend(myCustomClient);
23
+ *
24
+ * // Crawler uses global services
25
+ * const crawler = new BasicCrawler({ ... });
26
+ * ```
27
+ *
28
+ * **2. Per-crawler services (recommended for isolation):**
29
+ * ```typescript
30
+ * import { BasicCrawler, Configuration, LocalEventManager, MemoryStorageBackend } from 'crawlee';
31
+ *
32
+ * const crawler = new BasicCrawler({
33
+ * requestHandler: async ({ request }) => { ... },
34
+ * configuration: new Configuration({ ... }), // custom configuration
35
+ * storageBackend: new MemoryStorageBackend(), // custom storage
36
+ * eventManager: LocalEventManager.fromConfiguration(), // custom events
37
+ * });
38
+ * // Crawler has its own isolated ServiceLocator instance
39
+ * ```
40
+ */
41
+ export class ServiceLocator {
42
+ #configuration;
43
+ #eventManager;
44
+ #storageBackend;
45
+ #logger;
46
+ /**
47
+ * Unified storage instance manager for Dataset, KeyValueStore, and RequestQueue.
48
+ * Shared across all ServiceLocator instances (global singleton), matching crawlee-python.
49
+ * Per-crawler isolation is achieved via `clientCacheKey`, not separate manager instances.
50
+ */
51
+ static #storageInstanceManager;
52
+ /**
53
+ * Creates a new ServiceLocator instance.
54
+ *
55
+ * @param configuration Optional configuration instance to use
56
+ * @param eventManager Optional event manager instance to use
57
+ * @param storageBackend Optional storage backend instance to use
58
+ * @param logger Optional logger instance to use
59
+ */
60
+ constructor(configuration, eventManager, storageBackend, logger) {
61
+ this.#configuration = configuration;
62
+ this.#eventManager = eventManager;
63
+ this.#storageBackend = storageBackend;
64
+ this.#logger = logger;
65
+ }
66
+ /** @internal */
67
+ getServicesIfSet() {
68
+ return {
69
+ configuration: this.#configuration,
70
+ eventManager: this.#eventManager,
71
+ storageBackend: this.#storageBackend,
72
+ logger: this.#logger,
73
+ };
74
+ }
75
+ getConfiguration() {
76
+ if (!this.#configuration) {
77
+ this.getLogger().debug('No configuration set, implicitly creating and using default Configuration.');
78
+ this.#configuration = new Configuration();
79
+ }
80
+ return this.#configuration;
81
+ }
82
+ setConfiguration(configuration) {
83
+ // Same instance, no need to do anything
84
+ if (this.#configuration === configuration) {
85
+ return;
86
+ }
87
+ // Already have a different configuration that was retrieved
88
+ if (this.#configuration) {
89
+ throw new ServiceConflictError('Configuration', configuration, this.#configuration);
90
+ }
91
+ this.#configuration = configuration;
92
+ }
93
+ getEventManager() {
94
+ if (!this.#eventManager) {
95
+ this.getLogger().debug('No event manager set, implicitly creating and using default LocalEventManager.');
96
+ if (!this.#configuration) {
97
+ this.getLogger().warning('Implicit creation of event manager will implicitly set configuration as side effect. ' +
98
+ 'It is advised to explicitly first set the configuration instead.');
99
+ }
100
+ this.#eventManager = LocalEventManager.fromConfiguration(this.getConfiguration());
101
+ }
102
+ return this.#eventManager;
103
+ }
104
+ setEventManager(eventManager) {
105
+ // Same instance, no need to do anything
106
+ if (this.#eventManager === eventManager) {
107
+ return;
108
+ }
109
+ // Already have a different event manager that was retrieved
110
+ if (this.#eventManager) {
111
+ throw new ServiceConflictError('EventManager', eventManager, this.#eventManager);
112
+ }
113
+ this.#eventManager = eventManager;
114
+ }
115
+ getStorageBackend() {
116
+ if (!this.#storageBackend) {
117
+ this.getLogger().debug('No storage backend set, implicitly creating and using the default storage backend ' +
118
+ '(FileSystemStorageBackend when persistStorage is enabled, MemoryStorageBackend otherwise).');
119
+ if (!this.#configuration) {
120
+ this.getLogger().warning('Implicit creation of storage backend will implicitly set configuration as side effect. ' +
121
+ 'It is advised to explicitly first set the configuration instead.');
122
+ }
123
+ const configuration = this.getConfiguration();
124
+ this.#storageBackend = configuration.persistStorage
125
+ ? new FileSystemStorageBackend({
126
+ localDataDirectory: configuration.storageDir,
127
+ logger: this.getLogger().child({ prefix: 'FileSystemStorageBackend' }),
128
+ })
129
+ : new MemoryStorageBackend({
130
+ logger: this.getLogger().child({ prefix: 'MemoryStorageBackend' }),
131
+ });
132
+ }
133
+ return this.#storageBackend;
134
+ }
135
+ setStorageBackend(storageBackend) {
136
+ // Same instance, no need to do anything
137
+ if (this.#storageBackend === storageBackend) {
138
+ return;
139
+ }
140
+ // Already have a different storage backend that was retrieved
141
+ if (this.#storageBackend) {
142
+ throw new ServiceConflictError('StorageBackend', storageBackend, this.#storageBackend);
143
+ }
144
+ this.#storageBackend = storageBackend;
145
+ }
146
+ getLogger() {
147
+ if (!this.#logger) {
148
+ this.#logger = new ApifyLogAdapter(log);
149
+ }
150
+ return this.#logger;
151
+ }
152
+ setLogger(logger) {
153
+ if (this.#logger === logger) {
154
+ return;
155
+ }
156
+ if (this.#logger) {
157
+ throw new ServiceConflictError('Logger', logger, this.#logger);
158
+ }
159
+ this.#logger = logger;
160
+ }
161
+ getChildLog(prefix) {
162
+ return this.getLogger().child({ prefix });
163
+ }
164
+ getStorageInstanceManager() {
165
+ if (!ServiceLocator.#storageInstanceManager) {
166
+ ServiceLocator.#storageInstanceManager = new StorageInstanceManager();
167
+ }
168
+ return ServiceLocator.#storageInstanceManager;
169
+ }
170
+ reset() {
171
+ this.#configuration = undefined;
172
+ this.#eventManager = undefined;
173
+ this.#storageBackend = undefined;
174
+ this.#logger = undefined;
175
+ ServiceLocator.#storageInstanceManager?.clearCache();
176
+ ServiceLocator.#storageInstanceManager = undefined;
177
+ }
178
+ }
179
+ /**
180
+ * Used as the default service provider when crawlers don't specify custom services.
181
+ */
182
+ const globalServiceLocator = new ServiceLocator();
183
+ const serviceLocatorStorage = new AsyncLocalStorage();
184
+ /**
185
+ * Wraps all methods on `target` so that any code they invoke will see the given
186
+ * `serviceLocator` via `AsyncLocalStorage`, rather than the global one.
187
+ *
188
+ * Walks the prototype chain and replaces each method on the *instance* (not the prototype)
189
+ * with a wrapper that calls `serviceLocatorStorage.run(serviceLocator, originalMethod)`.
190
+ *
191
+ * The `AsyncLocalStorage` context propagates through the entire sync/async call tree of each
192
+ * wrapped method — including `super` calls, since the prototype methods execute within the
193
+ * context established by the instance-level wrapper.
194
+ *
195
+ * @internal
196
+ * @returns Scope control functions: `run` executes a callback within the scoped context,
197
+ * `enterScope`/`exitScope` allow entering/leaving the scope imperatively (e.g., for constructor bodies).
198
+ */
199
+ export function bindMethodsToServiceLocator(serviceLocator, target) {
200
+ let proto = Object.getPrototypeOf(target);
201
+ const seenKeys = new Set();
202
+ while (proto !== null && proto !== Object.prototype) {
203
+ const propertyKeys = [...Object.getOwnPropertyNames(proto), ...Object.getOwnPropertySymbols(proto)];
204
+ for (const propertyKey of propertyKeys) {
205
+ // The chain is walked derived-first, so the first occurrence of a key is the one dynamic
206
+ // dispatch would pick — a subclass override must not be clobbered by its base version.
207
+ if (seenKeys.has(propertyKey))
208
+ continue;
209
+ seenKeys.add(propertyKey);
210
+ const descriptor = Object.getOwnPropertyDescriptor(proto, propertyKey);
211
+ // We use property descriptors rather than accessing target[propertyKey] directly,
212
+ // because that would trigger getters and cause unwanted side effects.
213
+ // Skip getters, setters, and constructors — only wrap regular methods.
214
+ if (propertyKey === 'constructor' ||
215
+ !descriptor ||
216
+ descriptor.get ||
217
+ descriptor.set ||
218
+ typeof descriptor.value !== 'function')
219
+ continue;
220
+ const original = descriptor.value;
221
+ target[propertyKey] = (...args) => {
222
+ return serviceLocatorStorage.run(serviceLocator, () => {
223
+ return original.apply(target, args);
224
+ });
225
+ };
226
+ }
227
+ proto = Object.getPrototypeOf(proto);
228
+ }
229
+ let previousStore;
230
+ return {
231
+ run: (fn) => serviceLocatorStorage.run(serviceLocator, fn),
232
+ enterScope: () => {
233
+ previousStore = serviceLocatorStorage.getStore();
234
+ serviceLocatorStorage.enterWith(serviceLocator);
235
+ },
236
+ exitScope: () => {
237
+ serviceLocatorStorage.enterWith(previousStore); // casting to any so that `undefined` is accepted - this "unsets" the AsyncLocalStorage
238
+ },
239
+ };
240
+ }
241
+ export const serviceLocator = new Proxy({}, {
242
+ get(_target, prop) {
243
+ const active = serviceLocatorStorage.getStore() ?? globalServiceLocator;
244
+ const value = Reflect.get(active, prop, active);
245
+ if (typeof value === 'function') {
246
+ return value.bind(active);
247
+ }
248
+ return value;
249
+ },
250
+ set(_target, prop) {
251
+ throw new TypeError(`Cannot set property '${String(prop)}' on serviceLocator directly. Use the setter methods (e.g. setConfiguration(), setStorageBackend()) instead.`);
252
+ },
253
+ });
@@ -1,4 +1,3 @@
1
1
  export declare const BLOCKED_STATUS_CODES: number[];
2
- export declare const PERSIST_STATE_KEY = "SDK_SESSION_POOL_STATE";
2
+ export declare const PERSIST_STATE_KEY = "CRAWLEE_SESSION_POOL_STATE";
3
3
  export declare const MAX_POOL_SIZE = 1000;
4
- //# sourceMappingURL=consts.d.ts.map
@@ -1,4 +1,3 @@
1
1
  export const BLOCKED_STATUS_CODES = [401, 403, 429];
2
- export const PERSIST_STATE_KEY = 'SDK_SESSION_POOL_STATE';
2
+ export const PERSIST_STATE_KEY = 'CRAWLEE_SESSION_POOL_STATE';
3
3
  export const MAX_POOL_SIZE = 1000;
4
- //# sourceMappingURL=consts.js.map
@@ -5,4 +5,3 @@ export declare class CookieParseError extends Error {
5
5
  readonly cookieHeaderString: unknown;
6
6
  constructor(cookieHeaderString: unknown);
7
7
  }
8
- //# sourceMappingURL=errors.d.ts.map
@@ -9,4 +9,3 @@ export class CookieParseError extends Error {
9
9
  Error.captureStackTrace(this, CookieParseError);
10
10
  }
11
11
  }
12
- //# sourceMappingURL=errors.js.map
@@ -0,0 +1,9 @@
1
+ import type { SessionFingerprint } from '@crawlee/types';
2
+ /**
3
+ * Build a {@link SessionFingerprint} whose `platform` matches the host OS
4
+ * and whose `browser`/`device` are randomized within the realistic profiles for
5
+ * that platform. Used by {@link SessionPool} as the default fingerprint for
6
+ * freshly created sessions; callers can override by passing their own
7
+ * `fingerprint` in `sessionOptions`.
8
+ */
9
+ export declare function createDefaultSessionFingerprint(): SessionFingerprint;
@@ -0,0 +1,30 @@
1
+ /**
2
+ * (browser, platform, device) combinations that correspond to setups people
3
+ * actually run. Anything not listed here (e.g. `edge` on android, `safari` on
4
+ * windows, `desktop` mobile platforms) is left out so a randomized default
5
+ * never produces a fingerprint that would itself be a giveaway.
6
+ */
7
+ const PROFILES_BY_PLATFORM = [
8
+ { browser: 'chrome', platform: 'windows', device: 'desktop' },
9
+ { browser: 'firefox', platform: 'windows', device: 'desktop' },
10
+ { browser: 'edge', platform: 'windows', device: 'desktop' },
11
+ { browser: 'chrome', platform: 'macos', device: 'desktop' },
12
+ { browser: 'firefox', platform: 'macos', device: 'desktop' },
13
+ { browser: 'safari', platform: 'macos', device: 'desktop' },
14
+ { browser: 'edge', platform: 'macos', device: 'desktop' },
15
+ { browser: 'chrome', platform: 'linux', device: 'desktop' },
16
+ { browser: 'firefox', platform: 'linux', device: 'desktop' },
17
+ { browser: 'chrome', platform: 'android', device: 'mobile' },
18
+ { browser: 'firefox', platform: 'android', device: 'mobile' },
19
+ { browser: 'safari', platform: 'ios', device: 'mobile' },
20
+ ];
21
+ /**
22
+ * Build a {@link SessionFingerprint} whose `platform` matches the host OS
23
+ * and whose `browser`/`device` are randomized within the realistic profiles for
24
+ * that platform. Used by {@link SessionPool} as the default fingerprint for
25
+ * freshly created sessions; callers can override by passing their own
26
+ * `fingerprint` in `sessionOptions`.
27
+ */
28
+ export function createDefaultSessionFingerprint() {
29
+ return { ...PROFILES_BY_PLATFORM[Math.floor(Math.random() * PROFILES_BY_PLATFORM.length)] };
30
+ }
@@ -1,6 +1,4 @@
1
1
  export * from './errors.js';
2
- export * from './events.js';
3
2
  export * from './session.js';
4
3
  export * from './session_pool.js';
5
4
  export * from './consts.js';
6
- //# sourceMappingURL=index.d.ts.map
@@ -1,6 +1,4 @@
1
1
  export * from './errors.js';
2
- export * from './events.js';
3
2
  export * from './session.js';
4
3
  export * from './session_pool.js';
5
4
  export * from './consts.js';
6
- //# sourceMappingURL=index.js.map
@@ -1,24 +1,6 @@
1
- import type { Cookie as CookieObject, Dictionary } from '@crawlee/types';
2
- import type { Cookie, SerializedCookieJar } from 'tough-cookie';
1
+ import type { Dictionary, ISession, ProxyInfo, SessionFingerprint, SessionState } from '@crawlee/types';
3
2
  import { CookieJar } from 'tough-cookie';
4
- import type { Log } from '@apify/log';
5
- import type { ProxyInfo } from '../proxy_configuration.js';
6
- /**
7
- * Persistable {@link Session} state.
8
- */
9
- export interface SessionState {
10
- id: string;
11
- cookieJar: SerializedCookieJar;
12
- proxyInfo?: ProxyInfo;
13
- userData: object;
14
- errorScore: number;
15
- maxErrorScore: number;
16
- errorScoreDecrement: number;
17
- usageCount: number;
18
- maxUsageCount: number;
19
- expiresAt: string;
20
- createdAt: string;
21
- }
3
+ import type { CrawleeLogger } from '../log.js';
22
4
  export interface SessionOptions {
23
5
  /** Id of session used for generating fingerprints. It is used as proxy session name. */
24
6
  id?: string;
@@ -59,12 +41,22 @@ export interface SessionOptions {
59
41
  * @default 50
60
42
  */
61
43
  maxUsageCount?: number;
62
- /** SessionPool instance. Session will emit the `sessionRetired` event on this instance. */
63
- sessionPool?: import('./session_pool.js').SessionPool;
64
- log?: Log;
44
+ /**
45
+ * Marks the session as already retired. Used when restoring a previously persisted session
46
+ * so that `isUsable()` reflects the terminal state regardless of error score or usage count.
47
+ * @default false
48
+ */
49
+ retired?: boolean;
50
+ log?: CrawleeLogger;
65
51
  errorScore?: number;
66
52
  cookieJar?: CookieJar;
67
53
  proxyInfo?: ProxyInfo;
54
+ /**
55
+ * Browser / HTTP client fingerprint tied to this session. Backends use this to make
56
+ * repeated requests with the same session look consistent (same user-agent, headers,
57
+ * TLS profile). See {@link SessionFingerprint}.
58
+ */
59
+ fingerprint?: SessionFingerprint;
68
60
  }
69
61
  /**
70
62
  * Sessions are used to store information such as cookies and can be used for generating fingerprints and proxy sessions.
@@ -72,21 +64,10 @@ export interface SessionOptions {
72
64
  * Session internal state can be enriched with custom user data for example some authorization tokens and specific headers in general.
73
65
  * @category Scaling
74
66
  */
75
- export declare class Session {
67
+ export declare class Session implements ISession {
68
+ #private;
76
69
  readonly id: string;
77
- private maxAgeSecs;
78
- userData: Dictionary;
79
- private _maxErrorScore;
80
- private _errorScoreDecrement;
81
- private _createdAt;
82
- private _expiresAt;
83
- private _usageCount;
84
- private _maxUsageCount;
85
- private sessionPool;
86
- private _errorScore;
87
- private _proxyInfo?;
88
- private _cookieJar;
89
- private log;
70
+ readonly userData: Dictionary;
90
71
  get errorScore(): number;
91
72
  get usageCount(): number;
92
73
  get maxErrorScore(): number;
@@ -96,10 +77,17 @@ export declare class Session {
96
77
  get maxUsageCount(): number;
97
78
  get cookieJar(): CookieJar;
98
79
  get proxyInfo(): ProxyInfo | undefined;
80
+ get fingerprint(): SessionFingerprint | undefined;
81
+ set fingerprint(fingerprint: SessionFingerprint | undefined);
82
+ /**
83
+ * `true` once {@link Session.retire|`retire()`} has been called. Retirement is terminal:
84
+ * a retired session is never picked by the pool and cannot be revived via `markGood()`.
85
+ */
86
+ get retired(): boolean;
99
87
  /**
100
88
  * Session configuration.
101
89
  */
102
- constructor(options: SessionOptions);
90
+ constructor(options?: SessionOptions);
103
91
  /**
104
92
  * Indicates whether the session is blocked.
105
93
  * Session is blocked once it reaches the `maxErrorScore`.
@@ -118,7 +106,7 @@ export declare class Session {
118
106
  isMaxUsageCountReached(): boolean;
119
107
  /**
120
108
  * Indicates whether the session can be used for next requests.
121
- * Session is usable when it is not expired, not blocked and the maximum usage count has not be reached.
109
+ * Session is usable when it is not retired, not expired, not blocked and the maximum usage count has not be reached.
122
110
  */
123
111
  isUsable(): boolean;
124
112
  /**
@@ -132,11 +120,11 @@ export declare class Session {
132
120
  */
133
121
  getState(): SessionState;
134
122
  /**
135
- * Marks session as blocked and emits event on the `SessionPool`
136
- * This method should be used if the session usage was unsuccessful
137
- * and you are sure that it is because of the session configuration and not any external matters.
138
- * For example when server returns 403 status code.
139
- * If the session does not work due to some external factors as server error such as 5XX you probably want to use `markBad` method.
123
+ * Permanently retires the session `isUsable()` will return `false` from here on,
124
+ * and no `markGood()` / `markBad()` can revive it. Calling `retire()` again is a no-op.
125
+ *
126
+ * Use this when you're confident the session itself is the problem (e.g. a `403` response).
127
+ * For transient external failures (such as `5XX` responses), use `markBad()` instead.
140
128
  */
141
129
  retire(): void;
142
130
  /**
@@ -144,60 +132,19 @@ export declare class Session {
144
132
  * Should be used when the session has been used unsuccessfully. For example because of timeouts.
145
133
  */
146
134
  markBad(): void;
147
- /**
148
- * With certain status codes: `401`, `403` or `429` we can be certain
149
- * that the target website is blocking us. This function helps to do this conveniently
150
- * by retiring the session when such code is received. Optionally, the default status
151
- * codes can be extended in the second parameter.
152
- * @param statusCode HTTP status code.
153
- * @returns Whether the session was retired.
154
- */
155
- retireOnBlockedStatusCodes(statusCode: number): boolean;
156
- /**
157
- * Saves cookies from an HTTP response to be used with the session.
158
- * It expects an object with a `headers` property that's either an `Object`
159
- * (typical Node.js responses) or a `Function` (Puppeteer Response).
160
- *
161
- * It then parses and saves the cookies from the `set-cookie` header, if available.
162
- */
163
- setCookiesFromResponse(response: Response): void;
164
- /**
165
- * Saves an array with cookie objects to be used with the session.
166
- * The objects should be in the format that
167
- * [Puppeteer uses](https://pptr.dev/#?product=Puppeteer&version=v2.0.0&show=api-pagecookiesurls),
168
- * but you can also use this function to set cookies manually:
169
- *
170
- * ```
171
- * [
172
- * { name: 'cookie1', value: 'my-cookie' },
173
- * { name: 'cookie2', value: 'your-cookie' }
174
- * ]
175
- * ```
176
- */
177
- setCookies(cookies: CookieObject[], url: string): void;
178
- /**
179
- * Returns cookies in a format compatible with puppeteer/playwright and ready to be used with `page.setCookie`.
180
- * @param url website url. Only cookies stored for this url will be returned
181
- */
182
- getCookies(url: string): CookieObject[];
183
135
  /**
184
136
  * Returns cookies saved with the session in the typical
185
137
  * key1=value1; key2=value2 format, ready to be used in
186
138
  * a cookie header or elsewhere.
187
139
  * @returns Represents `Cookie` header.
188
140
  */
189
- getCookieString(url: string): string;
141
+ getCookieString(url: string): Promise<string>;
190
142
  /**
191
143
  * Sets a cookie within this session for the specific URL.
192
144
  */
193
- setCookie(rawCookie: string, url: string): void;
194
- /**
195
- * Sets cookies.
196
- */
197
- protected _setCookies(cookies: Cookie[], url: string): void;
145
+ setCookie(rawCookie: string, url: string): Promise<void>;
198
146
  /**
199
147
  * Checks if session is not usable. if it is not retires the session.
200
148
  */
201
- protected _maybeSelfRetire(): void;
149
+ private maybeSelfRetire;
202
150
  }
203
- //# sourceMappingURL=session.d.ts.map