@opencraw/core 0.1.2 → 0.1.3
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/README.md +1 -1
- package/dist/index.esm.js +762 -71
- package/dist/src/access/access-profile.contract.d.ts +4 -0
- package/dist/src/access/index.d.ts +1 -1
- package/dist/src/api-steps/send-request.use-case.d.ts +3 -2
- package/dist/src/browser-session/browser-profile.store.d.ts +52 -0
- package/dist/src/browser-session/browser.client.d.ts +8 -0
- package/dist/src/browser-session/index.d.ts +1 -0
- package/dist/src/crawl-events/crawl-event.contract.d.ts +8 -0
- package/dist/src/crawl-execution/bootstrap-session.use-case.d.ts +23 -2
- package/dist/src/crawl-execution/crawl-options.config.d.ts +27 -0
- package/dist/src/crawl-execution/rotating-runner.use-case.d.ts +9 -0
- package/dist/src/crawl-execution/run-crawl.use-case.d.ts +6 -2
- package/dist/src/crawl-execution/run-input-recipe.use-case.d.ts +11 -3
- package/dist/src/index.d.ts +5 -4
- package/dist/src/recipe-schema/index.d.ts +2 -2
- package/dist/src/recipe-schema/input-recipe.contract.d.ts +24 -1
- package/dist/src/record-sink/dedupe.policy.d.ts +19 -7
- package/dist/src/record-sink/index.d.ts +1 -0
- package/dist/src/step-flow/for-each.use-case.d.ts +4 -2
- package/dist/src/step-flow/host-throttle.policy.d.ts +49 -0
- package/dist/src/step-flow/index.d.ts +5 -0
- package/dist/src/step-flow/run-gate.policy.d.ts +12 -1
- package/dist/src/step-flow/step-runner.contract.d.ts +13 -0
- package/dist/src/step-flow/transport-retry.policy.d.ts +76 -0
- package/dist/src/web-steps/navigate.use-case.d.ts +3 -2
- package/dist/src/web-steps/run-web-step.use-case.d.ts +8 -1
- package/package.json +1 -1
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import type { EventBus } from '../crawl-events/index.js';
|
|
2
|
+
import type { RetryRule } from '../recipe-schema/index.js';
|
|
3
|
+
import type { RunGate } from './run-gate.policy.js';
|
|
4
|
+
/** A retry rule with every default filled in. */
|
|
5
|
+
export type ResolvedRetryRule = Required<RetryRule>;
|
|
6
|
+
/** Statuses a server uses for "not now": timeout, too early, too many requests, and the 5xx that pass. */
|
|
7
|
+
export declare const RETRY_STATUSES: readonly number[];
|
|
8
|
+
/** Three tries, one second then two apart, never a wait over 30 seconds. */
|
|
9
|
+
export declare const DEFAULT_RETRY_RULE: ResolvedRetryRule;
|
|
10
|
+
/** Why an attempt may be worth repeating, and the server's own `Retry-After`, if it sent one. */
|
|
11
|
+
export interface Transient {
|
|
12
|
+
reason: string;
|
|
13
|
+
retryAfter?: string;
|
|
14
|
+
}
|
|
15
|
+
/** One try of a request, and how to tell a passing failure in what it gave. */
|
|
16
|
+
export interface TransportAttempt<T> {
|
|
17
|
+
run: () => Promise<T>;
|
|
18
|
+
/** A transient problem in the outcome (a retry status, a connection error), or `undefined` when the outcome stands. */
|
|
19
|
+
problem: (outcome: {
|
|
20
|
+
value: T;
|
|
21
|
+
} | {
|
|
22
|
+
error: unknown;
|
|
23
|
+
}) => Transient | undefined;
|
|
24
|
+
}
|
|
25
|
+
export interface RetryContext {
|
|
26
|
+
recipeId: string;
|
|
27
|
+
gate: RunGate;
|
|
28
|
+
events: EventBus;
|
|
29
|
+
rule: ResolvedRetryRule;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* The retry rule a recipe runs with: its `limits.retry` over the crawler's
|
|
33
|
+
* default over `DEFAULT_RETRY_RULE`.
|
|
34
|
+
*
|
|
35
|
+
* @param own - The recipe's `limits.retry`.
|
|
36
|
+
* @param crawler - The crawler's `retry` option.
|
|
37
|
+
* @returns The rule.
|
|
38
|
+
*/
|
|
39
|
+
export declare function resolveRetryRule(own?: RetryRule, crawler?: RetryRule): ResolvedRetryRule;
|
|
40
|
+
/**
|
|
41
|
+
* Whether an error is a connection failure worth another try.
|
|
42
|
+
*
|
|
43
|
+
* @param error - What the request threw.
|
|
44
|
+
* @returns The reason, or `undefined`.
|
|
45
|
+
*/
|
|
46
|
+
export declare function transientError(error: unknown): Transient | undefined;
|
|
47
|
+
/**
|
|
48
|
+
* How long to wait before attempt `attempt + 1`: the server's `Retry-After`
|
|
49
|
+
* when it gave one, else `backoffMs` doubling per attempt with a little
|
|
50
|
+
* jitter; `undefined` when the server asks for longer than `maxDelayMs` (it
|
|
51
|
+
* means "come back much later", which a crawl cannot wait for).
|
|
52
|
+
*
|
|
53
|
+
* @param rule - The retry rule.
|
|
54
|
+
* @param attempt - The attempt that just failed, from 1.
|
|
55
|
+
* @param retryAfter - The `Retry-After` header: seconds, or an HTTP date.
|
|
56
|
+
* @param now - The current time, for dates.
|
|
57
|
+
* @returns Milliseconds, or `undefined` for no retry.
|
|
58
|
+
*/
|
|
59
|
+
export declare function retryDelay(rule: ResolvedRetryRule, attempt: number, retryAfter?: string, now?: number): number | undefined;
|
|
60
|
+
/**
|
|
61
|
+
* Sends a request through the gate (the recipe's rate, the site's lane), and
|
|
62
|
+
* sends it again after a pause while it fails in a passing way, up to
|
|
63
|
+
* `rule.attempts` tries in all. A `Retry-After` holds back every request to
|
|
64
|
+
* that site, not only this one. Each retry is reported as `request:retry`.
|
|
65
|
+
*
|
|
66
|
+
* Like redialling a busy number: wait a moment, dial again, give up after a
|
|
67
|
+
* few tries; and if the other end said "call back in a minute", wait that minute.
|
|
68
|
+
*
|
|
69
|
+
* @param url - Where the request goes.
|
|
70
|
+
* @param attempt - How to send it and how to judge the outcome.
|
|
71
|
+
* @param context - The recipe, gate, events and rule.
|
|
72
|
+
* @returns What the last try gave.
|
|
73
|
+
* @throws What the last try threw.
|
|
74
|
+
*/
|
|
75
|
+
export declare function withTransportRetry<T>(url: string, attempt: TransportAttempt<T>, context: RetryContext): Promise<T>;
|
|
76
|
+
//# sourceMappingURL=transport-retry.policy.d.ts.map
|
|
@@ -5,8 +5,9 @@ import type { GotoStep, InputRecipe } from '../recipe-schema/index.js';
|
|
|
5
5
|
import type { RunGate } from '../step-flow/index.js';
|
|
6
6
|
/**
|
|
7
7
|
* Runs a `goto` step: renders the URL (relative to the current page), waits for
|
|
8
|
-
* the gate's throttle (`delayMs`), navigates,
|
|
9
|
-
*
|
|
8
|
+
* the gate's throttle (`delayMs`), navigates (again, after a pause, while it
|
|
9
|
+
* fails in passing: `limits.retry`), records the page's real URL in the scope,
|
|
10
|
+
* and checks the response against the recipe's block rule.
|
|
10
11
|
*
|
|
11
12
|
* @throws BlockedError when the response is a block.
|
|
12
13
|
*/
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { BrowserSession } from '../browser-session/index.js';
|
|
2
2
|
import type { CaptchaGuard } from '../captcha/index.js';
|
|
3
3
|
import type { EventBus } from '../crawl-events/index.js';
|
|
4
4
|
import type { ExtractionScope, LiveElement } from '../extraction-scope/index.js';
|
|
@@ -24,6 +24,13 @@ export declare class WebStepRunner implements StepRunner {
|
|
|
24
24
|
private visit;
|
|
25
25
|
runLeaf(step: Step, scope: ExtractionScope): Promise<void>;
|
|
26
26
|
nextPage(next: PaginateNext, scope: ExtractionScope): Promise<NextPageResult>;
|
|
27
|
+
/**
|
|
28
|
+
* A runner on a new tab of the same context, for one parallel iteration:
|
|
29
|
+
* it shares cookies, the gate and the captcha guard; disposing it closes the tab only.
|
|
30
|
+
*
|
|
31
|
+
* @returns The forked runner.
|
|
32
|
+
*/
|
|
33
|
+
fork(): Promise<WebStepRunner>;
|
|
27
34
|
elements(selector: string): Promise<LiveElement[]>;
|
|
28
35
|
dispose(): Promise<void>;
|
|
29
36
|
}
|