@crawlee/playwright 4.0.0-beta.99 → 4.0.0-rc.0

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.
package/index.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  export * from '@crawlee/browser';
2
+ export * from './internals/playwright-browser-pool.js';
2
3
  export * from './internals/playwright-crawler.js';
3
4
  export * from './internals/playwright-launcher.js';
4
5
  export * from './internals/adaptive-playwright-crawler.js';
package/index.js CHANGED
@@ -1,4 +1,5 @@
1
1
  export * from '@crawlee/browser';
2
+ export * from './internals/playwright-browser-pool.js';
2
3
  export * from './internals/playwright-crawler.js';
3
4
  export * from './internals/playwright-launcher.js';
4
5
  export * from './internals/adaptive-playwright-crawler.js';
@@ -1,31 +1,40 @@
1
1
  import type { BrowserHook, LoadedRequest, Request, RouterHandler, RouteSchemas, RoutesFromSchemas } from '@crawlee/browser';
2
2
  import type { BasicCrawlerOptions } from '@crawlee/basic';
3
3
  import { BasicCrawler } from '@crawlee/basic';
4
- import type { ContextPipeline, CrawlingContext, EnqueueLinksOptions, GetUserDataFromRequest, RouterRoutes, StatisticsOptions, StatisticState } from '@crawlee/core';
5
- import { RequestHandlerResult, Statistics } from '@crawlee/core';
4
+ import type { ContextPipeline, CrawlingContext, EnqueueLinksOptions, GetUserDataFromRequest, RouterRoutes, StorageTransactionView } from '@crawlee/core';
6
5
  import type { Dictionary, Awaitable } from '@crawlee/types';
7
- import { type CheerioRoot } from '@crawlee/utils';
6
+ import { type CheerioRoot } from '@crawlee/utils/internal';
8
7
  import { type Cheerio } from 'cheerio';
9
8
  import type { AnyNode } from 'domhandler';
10
9
  // @ts-ignore optional peer dependency or compatibility with es2022
11
10
  import type { Page } from 'playwright';
11
+ import { z } from 'zod';
12
12
  import type { PlaywrightCrawlingContext, PlaywrightGotoOptions } from './playwright-crawler.js';
13
13
  import { type IRenderingTypePredictor } from './utils/rendering-type-prediction.js';
14
- interface AdaptivePlaywrightCrawlerStatisticState extends StatisticState {
15
- httpOnlyRequestHandlerRuns?: number;
16
- browserRequestHandlerRuns?: number;
17
- renderingTypeMispredictions?: number;
18
- }
19
- declare class AdaptivePlaywrightCrawlerStatistics extends Statistics {
20
- state: AdaptivePlaywrightCrawlerStatisticState;
21
- constructor(options?: StatisticsOptions);
22
- reset(): void;
23
- protected maybeLoadStatistics(): Promise<void>;
24
- trackHttpOnlyRequestHandlerRun(): void;
25
- trackBrowserRequestHandlerRun(): void;
26
- trackRenderingTypeMisprediction(): void;
27
- }
28
- export interface AdaptivePlaywrightCrawlerContext<UserData extends Dictionary = Dictionary> extends CrawlingContext<UserData> {
14
+ declare const adaptiveStatisticStateSchema: z.ZodObject<{
15
+ httpOnlyRequestHandlerRuns: z.ZodDefault<z.ZodNumber>;
16
+ browserRequestHandlerRuns: z.ZodDefault<z.ZodNumber>;
17
+ renderingTypeMispredictions: z.ZodDefault<z.ZodNumber>;
18
+ }, z.core.$strip>;
19
+ /**
20
+ * The extra statistics fields {@link AdaptivePlaywrightCrawler} tracks on top of the built-in
21
+ * {@link StatisticState} ones. They are available on `crawler.statistics.state` and are persisted with the rest of
22
+ * the statistics.
23
+ */
24
+ export type AdaptivePlaywrightCrawlerStatisticState = z.infer<typeof adaptiveStatisticStateSchema>;
25
+ /**
26
+ * The {@link AdaptivePlaywrightCrawlerStatisticState} fields as a {@link Statistics} state extension, defaults
27
+ * and all. A {@link Statistics} instance to be injected into an {@link AdaptivePlaywrightCrawler} has to carry
28
+ * them - `deserialize.extend()` your own fields onto this one and pass the result as `stateExtension`.
29
+ */
30
+ export declare const adaptivePlaywrightCrawlerStatisticState: {
31
+ deserialize: z.ZodObject<{
32
+ httpOnlyRequestHandlerRuns: z.ZodDefault<z.ZodNumber>;
33
+ browserRequestHandlerRuns: z.ZodDefault<z.ZodNumber>;
34
+ renderingTypeMispredictions: z.ZodDefault<z.ZodNumber>;
35
+ }, z.core.$strip>;
36
+ };
37
+ export interface AdaptivePlaywrightCrawlerContext<UserData extends Dictionary = any> extends CrawlingContext<UserData> {
29
38
  request: LoadedRequest<Request<UserData>>;
30
39
  /**
31
40
  * The HTTP response, either from the HTTP client or from the initial request from playwright's navigation.
@@ -83,7 +92,7 @@ type AdaptiveHook<ContextExtension = Dictionary<never>> = BrowserHook<AdaptiveHo
83
92
  type AdaptivePostNavigationHook<ContextExtension = Dictionary<never>> = BrowserHook<Omit<AdaptiveHookContext, 'request'> & {
84
93
  request: LoadedRequest<Request>;
85
94
  }, ContextExtension>;
86
- export interface AdaptivePlaywrightCrawlerOptions<ContextExtension = Dictionary<never>, ExtendedContext extends AdaptivePlaywrightCrawlerContext = AdaptivePlaywrightCrawlerContext & ContextExtension, Routes extends Record<keyof Routes, Dictionary> = Record<string, GetUserDataFromRequest<AdaptivePlaywrightCrawlerContext['request']>>> extends Omit<BasicCrawlerOptions<AdaptivePlaywrightCrawlerContext, ContextExtension, ExtendedContext, Routes>, 'preNavigationHooks' | 'postNavigationHooks'> {
95
+ export interface AdaptivePlaywrightCrawlerOptions<ContextExtension = Dictionary<never>, ExtendedContext extends AdaptivePlaywrightCrawlerContext = AdaptivePlaywrightCrawlerContext & ContextExtension, Routes extends Record<keyof Routes, Dictionary> = Record<string, GetUserDataFromRequest<AdaptivePlaywrightCrawlerContext['request']>>, StatisticStateExtension extends AdaptivePlaywrightCrawlerStatisticState = AdaptivePlaywrightCrawlerStatisticState> extends Omit<BasicCrawlerOptions<AdaptivePlaywrightCrawlerContext, ContextExtension, ExtendedContext, Routes, StatisticStateExtension>, 'preNavigationHooks' | 'postNavigationHooks'> {
87
96
  /**
88
97
  * Async functions that are sequentially evaluated before the navigation. Good for setting additional cookies.
89
98
  * The function accepts a subset of the crawling context. If you attempt to access the `page` property during HTTP-only crawling,
@@ -108,11 +117,12 @@ export interface AdaptivePlaywrightCrawlerOptions<ContextExtension = Dictionary<
108
117
  */
109
118
  renderingTypeDetectionRatio?: number;
110
119
  /**
111
- * An optional callback that is called on dataset items found by the request handler in plain HTTP mode.
120
+ * An optional callback that is called on the storage writes recorded by the request handler in plain
121
+ * HTTP mode (exposed as a read-only {@link StorageTransactionView}).
112
122
  * If it returns false, the request is retried in a browser.
113
- * If no callback is specified, every dataset item is considered valid.
123
+ * If no callback is specified, every result is considered valid.
114
124
  */
115
- resultChecker?: (result: RequestHandlerResult) => boolean;
125
+ resultChecker?: (result: StorageTransactionView) => boolean;
116
126
  /**
117
127
  * An optional callback that decides whether an error thrown during the plain HTTP request handler
118
128
  * should be propagated (instead of falling back to browser navigation).
@@ -135,18 +145,13 @@ export interface AdaptivePlaywrightCrawlerOptions<ContextExtension = Dictionary<
135
145
  *
136
146
  * For a stricter, ready-made comparator that also takes enqueued requests and key-value store changes into account, see {@link fullResultComparator}.
137
147
  */
138
- resultComparator?: (resultA: RequestHandlerResult, resultB: RequestHandlerResult) => boolean | 'equal' | 'different' | 'inconclusive';
148
+ resultComparator?: (resultA: StorageTransactionView, resultB: StorageTransactionView) => boolean | 'equal' | 'different' | 'inconclusive';
139
149
  /**
140
150
  * A custom rendering type predictor. A predictor passed here is borrowed - the crawler never drives its
141
151
  * lifecycle, so set it up yourself (the built-in {@link RenderingTypePredictor} needs `initialize()`).
142
152
  * Omit the option and the crawler builds its own from `renderingTypeDetectionRatio` - and initializes it.
143
153
  */
144
154
  renderingTypePredictor?: IRenderingTypePredictor;
145
- /**
146
- * Prevent direct access to storage in request handlers (only allow using context helpers).
147
- * Defaults to `true`
148
- */
149
- preventDirectStorageAccess?: boolean;
150
155
  }
151
156
  /**
152
157
  * An extension of {@link PlaywrightCrawler} that uses a more limited request handler interface so that it is able to switch to HTTP-only crawling when it detects it may be possible.
@@ -177,21 +182,10 @@ export interface AdaptivePlaywrightCrawlerOptions<ContextExtension = Dictionary<
177
182
  *
178
183
  * @experimental
179
184
  */
180
- export declare class AdaptivePlaywrightCrawler<ContextExtension = Dictionary<never>, ExtendedContext extends AdaptivePlaywrightCrawlerContext = AdaptivePlaywrightCrawlerContext & ContextExtension, Routes extends Record<keyof Routes, Dictionary> = Record<string, GetUserDataFromRequest<AdaptivePlaywrightCrawlerContext['request']>>> extends BasicCrawler<AdaptivePlaywrightCrawlerContext, ContextExtension, ExtendedContext, Routes> {
181
- private renderingTypePredictor;
182
- private resultChecker;
183
- private shouldPropagateError;
184
- private resultComparator;
185
- private preventDirectStorageAccess;
186
- private staticContextPipeline;
187
- private browserContextPipeline;
188
- private individualRequestHandlerTimeoutMillis;
189
- readonly stats: AdaptivePlaywrightCrawlerStatistics;
190
- private resultObjects;
191
- private inFlightRenderingTypeDetections;
192
- private teardownHooks;
193
- constructor(options?: AdaptivePlaywrightCrawlerOptions<ContextExtension, ExtendedContext, Routes>);
194
- protected _init(): Promise<void>;
185
+ export declare class AdaptivePlaywrightCrawler<ContextExtension = Dictionary<never>, ExtendedContext extends AdaptivePlaywrightCrawlerContext = AdaptivePlaywrightCrawlerContext & ContextExtension, Routes extends Record<keyof Routes, Dictionary> = Record<string, GetUserDataFromRequest<AdaptivePlaywrightCrawlerContext['request']>>, StatisticStateExtension extends AdaptivePlaywrightCrawlerStatisticState = AdaptivePlaywrightCrawlerStatisticState> extends BasicCrawler<AdaptivePlaywrightCrawlerContext, ContextExtension, ExtendedContext, Routes, StatisticStateExtension> {
186
+ #private;
187
+ constructor(options?: AdaptivePlaywrightCrawlerOptions<ContextExtension, ExtendedContext, Routes, StatisticStateExtension>);
188
+ protected init(): Promise<void>;
195
189
  protected buildContextPipeline(): ContextPipeline<CrawlingContext<Dictionary>, CrawlingContext<Dictionary> & {
196
190
  readonly request: LoadedRequest<Request<Dictionary>>;
197
191
  readonly response: Response;
@@ -200,19 +194,18 @@ export declare class AdaptivePlaywrightCrawler<ContextExtension = Dictionary<nev
200
194
  readonly querySelectorAll: AdaptivePlaywrightCrawlerContext["querySelectorAll"];
201
195
  readonly waitForSelector: AdaptivePlaywrightCrawlerContext["waitForSelector"];
202
196
  readonly parseWithCheerio: AdaptivePlaywrightCrawlerContext["parseWithCheerio"];
197
+ readonly enqueueLinks: AdaptivePlaywrightCrawlerContext["enqueueLinks"];
203
198
  }>;
204
199
  private adaptCheerioContext;
205
200
  private adaptPlaywrightContext;
206
- private crawlOne;
207
- protected runRequestHandler(crawlingContext: CrawlingContext): Promise<void>;
208
- private commitResult;
209
- private allowStorageAccess;
210
201
  /**
211
- * Reading the pending request count queries the underlying request manager, which counts as storage access.
212
- * Since this is internal crawler bookkeeping used to compute the `enqueueLinks` limit (not user-initiated storage
213
- * access), it must be allowed even while a request handler runs inside the storage-access guard.
202
+ * Runs one request handler attempt inside its own {@link StorageTransaction}, wrapping the inner
203
+ * (static or browser) context pipeline. The transaction is pushed to `transactions` *at creation
204
+ * time, before the `try`* - the `ok: false` branch of the returned {@link Result} carries no
205
+ * result, and failed attempts are routine here. The caller owns the outcome and disposal.
214
206
  */
215
- protected getPendingRequestCountApproximation(): Promise<number>;
207
+ private crawlOne;
208
+ protected runRequestHandler(crawlingContext: CrawlingContext): Promise<void>;
216
209
  private enqueueLinks;
217
210
  private createLogProxy;
218
211
  teardown(): Promise<void>;
@@ -243,5 +236,5 @@ export declare function createAdaptivePlaywrightRouter<Context extends AdaptiveP
243
236
  * });
244
237
  * ```
245
238
  */
246
- export declare function fullResultComparator(resultA: RequestHandlerResult, resultB: RequestHandlerResult): boolean;
239
+ export declare function fullResultComparator(resultA: StorageTransactionView, resultB: StorageTransactionView): boolean;
247
240
  export {};