@opencraw/core 0.1.2 → 0.1.4

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 (195) hide show
  1. package/README.md +1 -1
  2. package/dist/access/access-broker.use-case.d.ts +43 -0
  3. package/dist/access/access-config.error.d.ts +5 -0
  4. package/dist/access/access-config.repository.d.ts +11 -0
  5. package/dist/access/access-json-schema.mapper.d.ts +8 -0
  6. package/dist/access/access-plugin.contract.d.ts +48 -0
  7. package/dist/access/access-preset.store.d.ts +19 -0
  8. package/dist/access/access-profile.contract.d.ts +95 -0
  9. package/dist/access/index.d.ts +11 -0
  10. package/dist/access/render-access.mapper.d.ts +41 -0
  11. package/dist/access/session-id.algorithm.d.ts +8 -0
  12. package/dist/api-steps/extract-from-document.use-case.d.ts +41 -0
  13. package/dist/api-steps/index.d.ts +4 -0
  14. package/dist/api-steps/run-api-step.use-case.d.ts +20 -0
  15. package/dist/api-steps/send-request.use-case.d.ts +23 -0
  16. package/dist/browser-session/browser-profile.store.d.ts +52 -0
  17. package/dist/browser-session/browser-session.config.d.ts +21 -0
  18. package/dist/browser-session/browser.client.d.ts +75 -0
  19. package/dist/browser-session/index.d.ts +6 -0
  20. package/dist/captcha/captcha-budget.model.d.ts +21 -0
  21. package/dist/captcha/captcha-detection.client.d.ts +28 -0
  22. package/dist/captcha/captcha-guard.use-case.d.ts +64 -0
  23. package/dist/captcha/captcha-solver-registry.store.d.ts +19 -0
  24. package/dist/captcha/captcha-solver.contract.d.ts +47 -0
  25. package/dist/captcha/captcha.error.d.ts +13 -0
  26. package/dist/captcha/index.d.ts +10 -0
  27. package/dist/captcha/resolve-captcha.use-case.d.ts +40 -0
  28. package/dist/crawl-events/crawl-event.contract.d.ts +169 -0
  29. package/dist/crawl-events/event-bus.store.d.ts +10 -0
  30. package/dist/crawl-events/index.d.ts +4 -0
  31. package/dist/crawl-events/trace-line.mapper.d.ts +14 -0
  32. package/dist/crawl-execution/bootstrap-session.use-case.d.ts +79 -0
  33. package/dist/crawl-execution/crawl-options.config.d.ts +67 -0
  34. package/dist/crawl-execution/crawl-report.model.d.ts +33 -0
  35. package/dist/crawl-execution/create-crawler.use-case.d.ts +20 -0
  36. package/dist/crawl-execution/index.d.ts +8 -0
  37. package/dist/crawl-execution/rotating-runner.use-case.d.ts +66 -0
  38. package/dist/crawl-execution/run-crawl.use-case.d.ts +17 -0
  39. package/dist/crawl-execution/run-input-recipe.use-case.d.ts +51 -0
  40. package/dist/deck-document/deck-document.model.d.ts +58 -0
  41. package/dist/deck-document/deck-table.algorithm.d.ts +35 -0
  42. package/dist/deck-document/index.d.ts +6 -0
  43. package/dist/deck-document/read-pptx.client.d.ts +16 -0
  44. package/dist/docx-document/index.d.ts +2 -0
  45. package/dist/docx-document/read-docx-html.client.d.ts +23 -0
  46. package/dist/extraction-scope/extraction-scope.model.d.ts +77 -0
  47. package/dist/extraction-scope/index.d.ts +5 -0
  48. package/dist/extraction-scope/live-element.model.d.ts +28 -0
  49. package/dist/hooks/hook-registry.store.d.ts +16 -0
  50. package/dist/hooks/hook.contract.d.ts +17 -0
  51. package/dist/hooks/hook.error.d.ts +7 -0
  52. package/dist/hooks/index.d.ts +4 -0
  53. package/dist/http-session/http-response.contract.d.ts +58 -0
  54. package/dist/http-session/http.client.d.ts +42 -0
  55. package/dist/http-session/index.d.ts +5 -0
  56. package/dist/http-session/text-decoding.algorithm.d.ts +35 -0
  57. package/dist/index.esm.js +1410 -95
  58. package/dist/markdown-document/index.d.ts +3 -0
  59. package/dist/markdown-document/read-markdown.client.d.ts +39 -0
  60. package/dist/output-mapping/coerce-field.mapper.d.ts +19 -0
  61. package/dist/output-mapping/generated-field.mapper.d.ts +16 -0
  62. package/dist/output-mapping/index.d.ts +9 -0
  63. package/dist/output-mapping/map-record.use-case.d.ts +27 -0
  64. package/dist/output-mapping/mapping.error.d.ts +17 -0
  65. package/dist/output-mapping/missing-value.policy.d.ts +14 -0
  66. package/dist/output-mapping/output-field.validator.d.ts +10 -0
  67. package/dist/output-mapping/output-record.model.d.ts +20 -0
  68. package/dist/pdf-document/index.d.ts +7 -0
  69. package/dist/pdf-document/pdf-document.model.d.ts +51 -0
  70. package/dist/pdf-document/pdf-table.algorithm.d.ts +43 -0
  71. package/dist/pdf-document/read-pdf.client.d.ts +18 -0
  72. package/dist/pdf-document/row-assembly.algorithm.d.ts +26 -0
  73. package/dist/recipe-loading/index.d.ts +9 -0
  74. package/dist/recipe-loading/load-recipe-set.use-case.d.ts +45 -0
  75. package/dist/recipe-loading/read-recipe-source.use-case.d.ts +14 -0
  76. package/dist/recipe-loading/recipe-binding.error.d.ts +14 -0
  77. package/dist/recipe-loading/recipe-binding.validator.d.ts +34 -0
  78. package/dist/recipe-loading/recipe-file.repository.d.ts +11 -0
  79. package/dist/recipe-loading/recipe-set.model.d.ts +12 -0
  80. package/dist/recipe-loading/recipe-source.contract.d.ts +28 -0
  81. package/dist/recipe-loading/recipe-text.mapper.d.ts +14 -0
  82. package/dist/recipe-schema/index.d.ts +15 -0
  83. package/dist/recipe-schema/input-recipe.contract.d.ts +156 -0
  84. package/dist/recipe-schema/json-schema.mapper.d.ts +15 -0
  85. package/dist/recipe-schema/output-recipe.contract.d.ts +47 -0
  86. package/dist/recipe-schema/recipe-kind.enum.d.ts +35 -0
  87. package/dist/recipe-schema/recipe-validation.error.d.ts +17 -0
  88. package/dist/recipe-schema/recipe.validator.d.ts +28 -0
  89. package/dist/recipe-schema/step.contract.d.ts +206 -0
  90. package/dist/recipe-schema/transform-rule.contract.d.ts +120 -0
  91. package/dist/record-diff/index.d.ts +4 -0
  92. package/dist/record-diff/record-diff.algorithm.d.ts +82 -0
  93. package/dist/record-diff/records-file.repository.d.ts +10 -0
  94. package/dist/record-sink/dedupe.policy.d.ts +29 -0
  95. package/dist/record-sink/index.d.ts +9 -0
  96. package/dist/record-sink/json-lines-sink.repository.d.ts +19 -0
  97. package/dist/record-sink/memory-sink.repository.d.ts +9 -0
  98. package/dist/record-sink/record-sink.contract.d.ts +17 -0
  99. package/dist/selection/html-selector.algorithm.d.ts +19 -0
  100. package/dist/selection/index.d.ts +8 -0
  101. package/dist/selection/json-path.algorithm.d.ts +9 -0
  102. package/dist/selection/json-text.algorithm.d.ts +58 -0
  103. package/dist/selection/regex.algorithm.d.ts +12 -0
  104. package/dist/selection/take-value.mapper.d.ts +27 -0
  105. package/dist/src/access/access-profile.contract.d.ts +4 -0
  106. package/dist/src/access/index.d.ts +1 -1
  107. package/dist/src/api-steps/extract-from-document.use-case.d.ts +5 -5
  108. package/dist/src/api-steps/send-request.use-case.d.ts +3 -2
  109. package/dist/src/browser-session/browser-profile.store.d.ts +52 -0
  110. package/dist/src/browser-session/browser.client.d.ts +8 -0
  111. package/dist/src/browser-session/index.d.ts +1 -0
  112. package/dist/src/crawl-events/crawl-event.contract.d.ts +8 -0
  113. package/dist/src/crawl-execution/bootstrap-session.use-case.d.ts +23 -2
  114. package/dist/src/crawl-execution/crawl-options.config.d.ts +27 -0
  115. package/dist/src/crawl-execution/rotating-runner.use-case.d.ts +9 -0
  116. package/dist/src/crawl-execution/run-crawl.use-case.d.ts +6 -2
  117. package/dist/src/crawl-execution/run-input-recipe.use-case.d.ts +11 -3
  118. package/dist/src/docx-document/index.d.ts +2 -0
  119. package/dist/src/docx-document/read-docx-html.client.d.ts +23 -0
  120. package/dist/src/extraction-scope/extraction-scope.model.d.ts +2 -1
  121. package/dist/src/http-session/http-response.contract.d.ts +2 -1
  122. package/dist/src/index.d.ts +9 -4
  123. package/dist/src/markdown-document/index.d.ts +1 -1
  124. package/dist/src/markdown-document/read-markdown.client.d.ts +10 -0
  125. package/dist/src/recipe-schema/index.d.ts +2 -2
  126. package/dist/src/recipe-schema/input-recipe.contract.d.ts +24 -1
  127. package/dist/src/recipe-schema/recipe-kind.enum.d.ts +1 -1
  128. package/dist/src/recipe-schema/step.contract.d.ts +4 -0
  129. package/dist/src/record-diff/index.d.ts +4 -0
  130. package/dist/src/record-diff/record-diff.algorithm.d.ts +82 -0
  131. package/dist/src/record-diff/records-file.repository.d.ts +10 -0
  132. package/dist/src/record-sink/dedupe.policy.d.ts +19 -7
  133. package/dist/src/record-sink/index.d.ts +1 -0
  134. package/dist/src/selection/html-selector.algorithm.d.ts +2 -1
  135. package/dist/src/step-flow/for-each.use-case.d.ts +4 -2
  136. package/dist/src/step-flow/host-throttle.policy.d.ts +49 -0
  137. package/dist/src/step-flow/index.d.ts +5 -0
  138. package/dist/src/step-flow/run-gate.policy.d.ts +12 -1
  139. package/dist/src/step-flow/step-runner.contract.d.ts +13 -0
  140. package/dist/src/step-flow/transport-retry.policy.d.ts +76 -0
  141. package/dist/src/web-steps/navigate.use-case.d.ts +3 -2
  142. package/dist/src/web-steps/run-web-step.use-case.d.ts +8 -1
  143. package/dist/src/xml-document/index.d.ts +6 -0
  144. package/dist/src/xml-document/xml-document.model.d.ts +13 -0
  145. package/dist/src/xml-document/xml-parser.client.d.ts +49 -0
  146. package/dist/src/xml-document/xpath.algorithm.d.ts +30 -0
  147. package/dist/step-flow/block-rule.policy.d.ts +21 -0
  148. package/dist/step-flow/blocked.error.d.ts +9 -0
  149. package/dist/step-flow/for-each.use-case.d.ts +20 -0
  150. package/dist/step-flow/host-throttle.policy.d.ts +49 -0
  151. package/dist/step-flow/index.d.ts +15 -0
  152. package/dist/step-flow/paginate.use-case.d.ts +17 -0
  153. package/dist/step-flow/retry.policy.d.ts +21 -0
  154. package/dist/step-flow/run-gate.policy.d.ts +50 -0
  155. package/dist/step-flow/run-steps.use-case.d.ts +39 -0
  156. package/dist/step-flow/step-failure.error.d.ts +14 -0
  157. package/dist/step-flow/step-runner.contract.d.ts +52 -0
  158. package/dist/step-flow/transport-retry.policy.d.ts +76 -0
  159. package/dist/template/expression.algorithm.d.ts +53 -0
  160. package/dist/template/index.d.ts +7 -0
  161. package/dist/template/template.algorithm.d.ts +53 -0
  162. package/dist/template/value-path.algorithm.d.ts +29 -0
  163. package/dist/template/value-text.algorithm.d.ts +18 -0
  164. package/dist/transformation/apply-transform-chain.use-case.d.ts +17 -0
  165. package/dist/transformation/collection.algorithm.d.ts +15 -0
  166. package/dist/transformation/currency.algorithm.d.ts +15 -0
  167. package/dist/transformation/date.algorithm.d.ts +13 -0
  168. package/dist/transformation/index.d.ts +10 -0
  169. package/dist/transformation/lookup.algorithm.d.ts +24 -0
  170. package/dist/transformation/number.algorithm.d.ts +30 -0
  171. package/dist/transformation/string.algorithm.d.ts +18 -0
  172. package/dist/transformation/transform-registry.store.d.ts +36 -0
  173. package/dist/transformation/transform.error.d.ts +8 -0
  174. package/dist/transformation/url.algorithm.d.ts +20 -0
  175. package/dist/web-steps/evaluate-script.use-case.d.ts +10 -0
  176. package/dist/web-steps/extract-from-page.use-case.d.ts +10 -0
  177. package/dist/web-steps/index.d.ts +2 -0
  178. package/dist/web-steps/interact.use-case.d.ts +36 -0
  179. package/dist/web-steps/navigate.use-case.d.ts +15 -0
  180. package/dist/web-steps/run-web-step.use-case.d.ts +37 -0
  181. package/dist/web-steps/snapshot-elements.use-case.d.ts +13 -0
  182. package/dist/workbook-document/csv-parser.algorithm.d.ts +26 -0
  183. package/dist/workbook-document/csv-workbook.mapper.d.ts +24 -0
  184. package/dist/workbook-document/grid-table.algorithm.d.ts +53 -0
  185. package/dist/workbook-document/html-tables.mapper.d.ts +14 -0
  186. package/dist/workbook-document/index.d.ts +9 -0
  187. package/dist/workbook-document/read-xlsx.client.d.ts +18 -0
  188. package/dist/workbook-document/workbook-document.model.d.ts +51 -0
  189. package/dist/xml-document/index.d.ts +6 -0
  190. package/dist/xml-document/xml-document.model.d.ts +13 -0
  191. package/dist/xml-document/xml-parser.client.d.ts +49 -0
  192. package/dist/xml-document/xpath.algorithm.d.ts +30 -0
  193. package/dist/yaml-document/index.d.ts +3 -0
  194. package/dist/yaml-document/read-yaml.client.d.ts +25 -0
  195. package/package.json +4 -2
@@ -1,10 +1,12 @@
1
1
  import type { AccessBroker } from '../access/index.js';
2
2
  import { BrowserClient } from '../browser-session/index.js';
3
+ import type { BrowserProfiles } from '../browser-session/index.js';
3
4
  import { CaptchaSolverRegistry } from '../captcha/index.js';
4
5
  import type { EventBus } from '../crawl-events/index.js';
5
6
  import type { HookRegistry } from '../hooks/index.js';
6
- import type { InputRecipe, OutputRecipe } from '../recipe-schema/index.js';
7
+ import type { InputRecipe, OutputRecipe, RetryRule } from '../recipe-schema/index.js';
7
8
  import type { DedupePolicy, RecordSink } from '../record-sink/index.js';
9
+ import type { HostThrottle } from '../step-flow/index.js';
8
10
  import type { RecipeReport } from './crawl-report.model.js';
9
11
  export interface RecipeRunDependencies {
10
12
  browser: () => Promise<BrowserClient>;
@@ -23,6 +25,12 @@ export interface RecipeRunDependencies {
23
25
  access: AccessBroker;
24
26
  /** The solvers recipes name; none when omitted. */
25
27
  captchaSolvers?: CaptchaSolverRegistry;
28
+ /** The crawler's per-site throttle, shared by every recipe. */
29
+ hosts?: HostThrottle;
30
+ /** The runner's persistent browser profiles, for `session.browserProfile`. */
31
+ profiles?: BrowserProfiles;
32
+ /** The crawler's retry rule, under each recipe's `limits.retry`. */
33
+ retry?: RetryRule;
26
34
  }
27
35
  /**
28
36
  * Runs one input recipe end to end: session, runner, the step walk, and for
@@ -34,10 +42,10 @@ export interface RecipeRunDependencies {
34
42
  * the sink sees one record at a time and `maxRecords` is exact: once reached,
35
43
  * every later emit returns `stop` before mapping.
36
44
  *
37
- * @param input - The input recipe.
45
+ * @param recipe - The input recipe.
38
46
  * @param output - The output recipe it feeds.
39
47
  * @param deps - Shared browser, hooks, events, sink and de-duplication.
40
48
  * @returns What happened.
41
49
  */
42
- export declare function runInputRecipe(input: InputRecipe, output: OutputRecipe, deps: RecipeRunDependencies): Promise<RecipeReport>;
50
+ export declare function runInputRecipe(recipe: InputRecipe, output: OutputRecipe, deps: RecipeRunDependencies): Promise<RecipeReport>;
43
51
  //# sourceMappingURL=run-input-recipe.use-case.d.ts.map
@@ -0,0 +1,2 @@
1
+ export { readDocxHtml } from './read-docx-html.client.js';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Reads a `.docx` Word document into HTML, through `@opencraw/office-reader`,
3
+ * so every selector that reads a page reads a Word document too:
4
+ *
5
+ * - headings become `<h1>`…`<h6>` inside `<section data-heading="…">`, as in
6
+ * rendered Markdown;
7
+ * - list items become nested `<ul>` / `<ol>`;
8
+ * - tables become `<table>`s with their merged cells as `colspan` / `rowspan`,
9
+ * so a `table` extract reads them like any HTML table;
10
+ * - a paragraph keeps its style as `data-style` and its links as `<a href>`;
11
+ * - headers, footers and notes follow the body, in `<header>`, `<footer>`
12
+ * and `<aside data-part="notes">`; the title goes to `<title>`.
13
+ *
14
+ * The reader is imported on first use.
15
+ *
16
+ * @param bytes - The file.
17
+ * @param source - Where it came from, for messages.
18
+ * @returns The HTML document.
19
+ * @throws Error naming the source, and saying what to do, for a file that is
20
+ * not a readable Word document (a legacy `.doc`, a password-protected file, an `.odt`…).
21
+ */
22
+ export declare function readDocxHtml(bytes: Uint8Array, source: string): Promise<string>;
23
+ //# sourceMappingURL=read-docx-html.client.d.ts.map
@@ -7,11 +7,12 @@
7
7
  * Page state (the current URL, page number and the document `extract` reads by
8
8
  * default) is scope state too, bound in the innermost scope that navigated.
9
9
  */
10
+ import type { XmlDocument } from '../xml-document/index.js';
10
11
  import type { DeckDocument } from '../deck-document/index.js';
11
12
  import type { PdfDocument } from '../pdf-document/index.js';
12
13
  import type { WorkbookDocument } from '../workbook-document/index.js';
13
14
  /** A fetched or rendered document a later `extract` can read. */
14
- export type ScopeDocument = PdfDocument | WorkbookDocument | DeckDocument | {
15
+ export type ScopeDocument = PdfDocument | WorkbookDocument | DeckDocument | XmlDocument | {
15
16
  kind: 'json';
16
17
  data: unknown;
17
18
  } | {
@@ -1,6 +1,7 @@
1
1
  import type { DeckDocument } from '../deck-document/index.js';
2
2
  import type { PdfDocument } from '../pdf-document/index.js';
3
3
  import type { WorkbookDocument } from '../workbook-document/index.js';
4
+ import type { XmlDocument } from '../xml-document/index.js';
4
5
  import type { BodyKind, HttpMethod } from '../recipe-schema/index.js';
5
6
  /** One HTTP request as the api runner sends it, templates already rendered. */
6
7
  export interface HttpRequest {
@@ -20,7 +21,7 @@ export interface HttpRequest {
20
21
  timeoutMs?: number;
21
22
  }
22
23
  /** A parsed response body. Structurally the same as a scope document, on purpose. */
23
- export type HttpBody = PdfDocument | WorkbookDocument | DeckDocument | {
24
+ export type HttpBody = PdfDocument | WorkbookDocument | DeckDocument | XmlDocument | {
24
25
  kind: 'json';
25
26
  data: unknown;
26
27
  } | {
@@ -1,11 +1,11 @@
1
1
  export { createCrawler } from './crawl-execution/index.js';
2
- export { AccessBroker, AccessConfigError, ACCESS_PRESETS, loadAccessConfig, accessConfigSchema, accessConfigJsonSchema } from './access/index.js';
2
+ export { AccessBroker, AccessConfigError, ACCESS_PRESETS, loadAccessConfig, accessConfigSchema, accessConfigJsonSchema, throttleConfigSchema } from './access/index.js';
3
3
  export type { AccessConfig, AccessProfile, AccessPlugin, AccessLease, LeaseRequest, PluginLeaseRequest, ProxySettings, AccessPreset } from './access/index.js';
4
4
  export type { Crawler, CrawlOptions, CrawlReport, RecipeReport } from './crawl-execution/index.js';
5
5
  export { loadRecipeSet, loadRecipes, readRecipeSource, bindRecipeSet, RecipeSet, RecipeBindingError, validateBinding } from './recipe-loading/index.js';
6
6
  export type { RecipeSetSource, RecipeSource, RecipeBytes, RecipeDocument, BindingIssue } from './recipe-loading/index.js';
7
- export { parseInputRecipe, parseOutputRecipe, RecipeValidationError, inputRecipeJsonSchema, outputRecipeJsonSchema, inputRecipeSchema, outputRecipeSchema } from './recipe-schema/index.js';
8
- export type { InputRecipe, OutputRecipe, FieldSpec, Step, StepType, MappingRule, TransformRule, ErrorPolicy, PaginateNext, SessionSpec, SessionAccess, CaptchaSettings, CaptchaStep, RecipeIssue } from './recipe-schema/index.js';
7
+ export { parseInputRecipe, parseOutputRecipe, RecipeValidationError, inputRecipeJsonSchema, outputRecipeJsonSchema, inputRecipeSchema, outputRecipeSchema, retryRuleSchema } from './recipe-schema/index.js';
8
+ export type { InputRecipe, OutputRecipe, FieldSpec, Step, StepType, MappingRule, TransformRule, ErrorPolicy, PaginateNext, SessionSpec, SessionAccess, CaptchaSettings, CaptchaStep, RetryRule, RecipeIssue } from './recipe-schema/index.js';
9
9
  export type { Hook, HookMap, HookContext } from './hooks/index.js';
10
10
  export { UnknownHookError } from './hooks/index.js';
11
11
  export type { OutputRecord } from './output-mapping/index.js';
@@ -24,11 +24,16 @@ export type { PdfDocument, PdfPage, PdfRow, PdfCell, PdfTable, TableQuery, Table
24
24
  export { parseCsv, detectDelimiter, csvWorkbook, findGridTables, fillDown, workbookText, isWorkbookDocument, htmlTableSheets } from './workbook-document/index.js';
25
25
  export { readMarkdown } from './markdown-document/index.js';
26
26
  export { readYaml } from './yaml-document/index.js';
27
+ export { parseXml, selectXpath, takeFromXml, isXmlDocument } from './xml-document/index.js';
28
+ export type { XmlDocument, XpathOptions, XpathValue } from './xml-document/index.js';
27
29
  export { findDeckTables, deckText, isDeckDocument } from './deck-document/index.js';
28
30
  export type { DeckDocument, DeckSlide, DeckShape, DeckChart, DeckTable, DeckTableQuery } from './deck-document/index.js';
29
31
  export type { WorkbookDocument, WorkbookCell, Sheet, CsvFormat, GridTable, GridTableQuery } from './workbook-document/index.js';
30
- export { StepFailure } from './step-flow/index.js';
32
+ export { StepFailure, HostThrottle, DEFAULT_RETRY_RULE } from './step-flow/index.js';
33
+ export type { ThrottleConfig, HostRule } from './step-flow/index.js';
31
34
  export { TransformError } from './transformation/index.js';
35
+ export { diffRecords, diffOptionsFor, readableKey, readRecordsFile } from './record-diff/index.js';
36
+ export type { RecordDiff, RecordChange, FieldChange, DiffOptions, StoredRecord } from './record-diff/index.js';
32
37
  export { CaptchaError, DEFAULT_CAPTCHA_SELECTOR, detectChallenge } from './captcha/index.js';
33
38
  export type { CaptchaSolver, CaptchaChallenge, CaptchaContext, CaptchaOutcome, CaptchaKind, CaptchaLog } from './captcha/index.js';
34
39
  //# sourceMappingURL=index.d.ts.map
@@ -1,3 +1,3 @@
1
- export { readMarkdown } from './read-markdown.client.js';
1
+ export { readMarkdown, sectioned } from './read-markdown.client.js';
2
2
  export type { MarkdownRead } from './read-markdown.client.js';
3
3
  //# sourceMappingURL=index.d.ts.map
@@ -26,4 +26,14 @@ export interface MarkdownRead {
26
26
  * @throws Error naming the source when the front matter is not YAML.
27
27
  */
28
28
  export declare function readMarkdown(text: string, source: string): Promise<MarkdownRead>;
29
+ /**
30
+ * Wraps each heading and what follows it, up to the next heading of the same
31
+ * or a higher level, in `<section data-heading="…" data-level="…">`, sections
32
+ * nesting; headings get slug ids. Rendered Markdown and Word documents both go
33
+ * through it, so one selector finds "the table under *Prezzi*" in either.
34
+ *
35
+ * @param html - Top-level HTML: headings among paragraphs, lists, tables.
36
+ * @returns The same content, sectioned.
37
+ */
38
+ export declare function sectioned(html: string): string;
29
39
  //# sourceMappingURL=read-markdown.client.d.ts.map
@@ -5,8 +5,8 @@ export { stepSchema, errorPolicySchema, paginateNextSchema } from './step.contra
5
5
  export type { Step, StepType, StepBaseFields, TargetFields, ErrorPolicy, PaginateNext, TakeKind, GotoStep, ClickStep, FillStep, PressStep, SelectStep, ScrollStep, WaitStep, EvaluateStep, ScreenshotStep, RequestStep, ExtractStep, SetStep, CollectStep, ForEachStep, IfStep, PaginateStep, EmitStep, HookStep, CaptchaStep, CaptchaCheck, } from './step.contract.js';
6
6
  export { transformRuleSchema, mappingRuleSchema } from './transform-rule.contract.js';
7
7
  export type { TransformRule, TransformOp, MappingRule, FromRule, EachRule } from './transform-rule.contract.js';
8
- export { inputRecipeSchema, sessionSpecSchema, startPointSchema } from './input-recipe.contract.js';
9
- export type { InputRecipe, SessionSpec, SessionBootstrap, SessionAccess, BlockRule, BlockRotation, CaptchaSettings, StartPoint, CrawlLimits, RecipeCookie } from './input-recipe.contract.js';
8
+ export { inputRecipeSchema, sessionSpecSchema, startPointSchema, retryRuleSchema } from './input-recipe.contract.js';
9
+ export type { InputRecipe, SessionSpec, SessionBootstrap, SessionAccess, BlockRule, BlockRotation, CaptchaSettings, RetryRule, StartPoint, CrawlLimits, RecipeCookie } from './input-recipe.contract.js';
10
10
  export { parseInputRecipe, parseOutputRecipe, recipeKindOf } from './recipe.validator.js';
11
11
  export { RecipeValidationError } from './recipe-validation.error.js';
12
12
  export type { RecipeIssue } from './recipe-validation.error.js';
@@ -99,14 +99,36 @@ export interface SessionSpec {
99
99
  blockedWhen?: BlockRule;
100
100
  onBlock?: BlockRotation;
101
101
  captcha?: CaptchaSettings;
102
+ /**
103
+ * A browser profile of the runner that persists between runs (cookies,
104
+ * storage, cache): web recipes and bootstraps run in it. A name; the runner
105
+ * decides where profiles live.
106
+ */
107
+ browserProfile?: string;
108
+ }
109
+ /**
110
+ * How a request that fails in passing (a dropped connection, a timeout, a
111
+ * 503, a 429) is sent again. On by default: three tries in all.
112
+ */
113
+ export interface RetryRule {
114
+ /** Tries per request, the first included; `1` turns retrying off. Default 3. */
115
+ attempts?: number;
116
+ /** The first pause; it doubles on every retry. Default 1000. */
117
+ backoffMs?: number;
118
+ /** The longest pause, `Retry-After` included; a server asking for longer is not retried. Default 30000. */
119
+ maxDelayMs?: number;
120
+ /** The statuses retried. Default `[408, 425, 429, 500, 502, 503, 504]`. */
121
+ statuses?: number[];
102
122
  }
103
123
  export interface CrawlLimits {
104
124
  maxRecords?: number;
105
125
  /** Minimum interval between two request starts across the recipe, whatever runs in parallel. */
106
126
  delayMs?: number;
107
127
  timeoutMs?: number;
108
- /** How many `forEach` iterations may run at once (api mode; a web recipe drives one page). Default 1. */
128
+ /** How many `forEach` iterations over a list may run at once: requests in api mode, tabs in web mode. Default 1. */
109
129
  concurrency?: number;
130
+ /** How requests that fail in passing are sent again; the crawler's `retry`, else three tries, when omitted. */
131
+ retry?: RetryRule;
110
132
  }
111
133
  /** Where to start, how to navigate, what to extract, and how it maps to one output recipe. */
112
134
  export interface InputRecipe {
@@ -129,5 +151,6 @@ export interface InputRecipe {
129
151
  }
130
152
  export declare const startPointSchema: z.ZodType<StartPoint>;
131
153
  export declare const sessionSpecSchema: z.ZodType<SessionSpec>;
154
+ export declare const retryRuleSchema: z.ZodType<RetryRule>;
132
155
  export declare const inputRecipeSchema: z.ZodType<InputRecipe>;
133
156
  //# sourceMappingURL=input-recipe.contract.d.ts.map
@@ -4,7 +4,7 @@ export declare const CRAWL_MODES: readonly ["web", "api"];
4
4
  export declare const SELECTOR_KINDS: readonly ["css", "xpath", "jsonpath", "regex", "table"];
5
5
  /** `take` also accepts `attr:<name>`, which is validated by pattern rather than listed. */
6
6
  export declare const TAKE_KINDS: readonly ["text", "html", "value", "json"];
7
- export declare const BODY_KINDS: readonly ["json", "jsonl", "html", "text", "pdf", "csv", "xlsx", "pptx", "yaml", "markdown"];
7
+ export declare const BODY_KINDS: readonly ["json", "jsonl", "html", "text", "pdf", "csv", "xlsx", "pptx", "yaml", "markdown", "xml", "docx"];
8
8
  export declare const YAML_SCALARS: readonly ["typed", "text"];
9
9
  /** How a PDF table aligns a row's values against a cell wrapped over several lines. */
10
10
  export declare const TABLE_ALIGNS: readonly ["auto", "top", "center", "bottom"];
@@ -119,6 +119,10 @@ export interface ExtractStep extends StepBaseFields {
119
119
  slide?: string;
120
120
  /** `table` only: read text boxes laid out as a table instead of native tables (deck). */
121
121
  shapes?: boolean;
122
+ /** `xpath` on XML only: prefix to namespace URI (`{ "atom": "http://www.w3.org/2005/Atom" }`). Prefixes the root declares are known already. */
123
+ namespaces?: Record<string, string>;
124
+ /** `xpath` on XML only: drop the document's namespaces, so `//entry/title` matches `<entry xmlns="…">`. */
125
+ ignoreNamespaces?: boolean;
122
126
  }
123
127
  export interface SetStep extends StepBaseFields {
124
128
  type: 'set';
@@ -0,0 +1,4 @@
1
+ export { diffRecords, diffOptionsFor, readableKey } from './record-diff.algorithm.js';
2
+ export type { RecordDiff, RecordChange, FieldChange, DiffOptions, StoredRecord } from './record-diff.algorithm.js';
3
+ export { readRecordsFile } from './records-file.repository.js';
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,82 @@
1
+ import type { OutputRecipe } from '../recipe-schema/index.js';
2
+ /** A record as a JSON Lines file holds it: the data, plus the sink's `_source` (and `_key` in append mode). */
3
+ export type StoredRecord = Record<string, unknown>;
4
+ /** One field whose value changed; nested objects are compared field by field (`price.amount`). */
5
+ export interface FieldChange {
6
+ field: string;
7
+ before: unknown;
8
+ after: unknown;
9
+ }
10
+ export type RecordChange = {
11
+ change: 'added';
12
+ key: string;
13
+ after: StoredRecord;
14
+ } | {
15
+ change: 'removed';
16
+ key: string;
17
+ before: StoredRecord;
18
+ } | {
19
+ change: 'changed';
20
+ key: string;
21
+ before: StoredRecord;
22
+ after: StoredRecord;
23
+ fields: FieldChange[];
24
+ };
25
+ /** How two runs differ, by record key. */
26
+ export interface RecordDiff {
27
+ added: number;
28
+ removed: number;
29
+ changed: number;
30
+ unchanged: number;
31
+ /** Every change, removed first, then changed, then added, each in file order. */
32
+ changes: RecordChange[];
33
+ /** Records on either side the key cannot tell apart from an earlier one: only the first counts. */
34
+ repeated: number;
35
+ /** How many records each side holds. */
36
+ counts: {
37
+ previous: number;
38
+ current: number;
39
+ };
40
+ /** Set when the current run holds far fewer records: the usual sign a site changed and a recipe broke quietly. */
41
+ shrunk?: {
42
+ previous: number;
43
+ current: number;
44
+ };
45
+ }
46
+ export interface DiffOptions {
47
+ /** The fields that identify a record. Default: the `_key` each line carries (a sink in append mode writes it). */
48
+ key?: readonly string[];
49
+ /** Fields not compared (their dotted paths match nested ones too). `_source` and `_key` never are. */
50
+ ignore?: readonly string[];
51
+ /** The share of records a run may lose before `shrunk` is set; default 0.5 (half). */
52
+ shrink?: number;
53
+ }
54
+ /**
55
+ * Compares two runs' records by key: what was added, what was removed, and
56
+ * for the records in both, which fields changed, before and after. Like a
57
+ * `git diff` of a price list, but row by row instead of line by line, so a
58
+ * reordered file is not a change.
59
+ *
60
+ * @param previous - The earlier run's records.
61
+ * @param current - The later run's records.
62
+ * @param options - The key fields, the fields to ignore, the shrink threshold.
63
+ * @returns The differences.
64
+ * @throws Error when records carry no key: without `key`, every line needs `_key`.
65
+ */
66
+ export declare function diffRecords(previous: readonly StoredRecord[], current: readonly StoredRecord[], options?: DiffOptions): RecordDiff;
67
+ /**
68
+ * The diff options an output recipe implies: its key fields, and its fields
69
+ * the engine fills differently every run (`generated: now`, `uuid`).
70
+ *
71
+ * @param output - The output recipe.
72
+ * @returns The key and the fields to ignore.
73
+ */
74
+ export declare function diffOptionsFor(output: OutputRecipe): Required<Pick<DiffOptions, 'key' | 'ignore'>>;
75
+ /**
76
+ * A key as people read it: the key fields' values joined (`Pandina · 1.0 Hybrid`).
77
+ *
78
+ * @param key - A record key (a JSON array of the key values).
79
+ * @returns The readable form.
80
+ */
81
+ export declare function readableKey(key: string): string;
82
+ //# sourceMappingURL=record-diff.algorithm.d.ts.map
@@ -0,0 +1,10 @@
1
+ import type { StoredRecord } from './record-diff.algorithm.js';
2
+ /**
3
+ * The records of a JSON Lines file, as a sink wrote them.
4
+ *
5
+ * @param path - The file.
6
+ * @returns One record per non-empty line.
7
+ * @throws Error naming the file and the line that is not a JSON object.
8
+ */
9
+ export declare function readRecordsFile(path: string): Promise<StoredRecord[]>;
10
+ //# sourceMappingURL=records-file.repository.d.ts.map
@@ -1,17 +1,29 @@
1
1
  import type { OutputRecord } from '../output-mapping/index.js';
2
2
  /** How far de-duplication reaches: the whole run, one input recipe, or not at all. */
3
3
  export type DedupeScope = 'run' | 'recipe' | 'off';
4
- /** Drops records whose key was already seen. First record wins; keyless records always pass. */
4
+ /** One input recipe's view of de-duplication: whether a record repeats a key already seen. */
5
+ export interface RecipeDedupe {
6
+ /**
7
+ * @param record - A validated record.
8
+ * @returns `true` when the record repeats an earlier key and must be dropped.
9
+ */
10
+ isDuplicate: (record: OutputRecord) => boolean;
11
+ }
12
+ /**
13
+ * Drops records whose key was already seen. First record wins; keyless
14
+ * records always pass. Recipes running in parallel each get their own view:
15
+ * under `recipe` scope they never see each other's keys, under `run` scope
16
+ * they share them (and whichever emits a key first keeps it).
17
+ */
5
18
  export declare class DedupePolicy {
6
19
  readonly scope: DedupeScope;
7
- private seen;
20
+ private readonly shared;
8
21
  constructor(scope?: DedupeScope);
9
- /** Called when an input recipe starts; forgets keys under `recipe` scope. */
10
- startRecipe(): void;
11
22
  /**
12
- * @param record - A validated record.
13
- * @returns `true` when the record repeats an earlier key and must be dropped.
23
+ * The de-duplication one input recipe run uses.
24
+ *
25
+ * @returns Its view: keys shared with the run, its own, or none checked.
14
26
  */
15
- isDuplicate(record: OutputRecord): boolean;
27
+ forRecipe(): RecipeDedupe;
16
28
  }
17
29
  //# sourceMappingURL=dedupe.policy.d.ts.map
@@ -4,5 +4,6 @@ export type { MemorySink } from './memory-sink.repository.js';
4
4
  export { jsonLinesSink } from './json-lines-sink.repository.js';
5
5
  export type { JsonLinesSinkOptions } from './json-lines-sink.repository.js';
6
6
  export { DedupePolicy } from './dedupe.policy.js';
7
+ export type { RecipeDedupe } from './dedupe.policy.js';
7
8
  export type { DedupeScope } from './dedupe.policy.js';
8
9
  //# sourceMappingURL=index.d.ts.map
@@ -12,7 +12,8 @@ export interface HtmlMatch {
12
12
  *
13
13
  * @param html - The markup (a whole document or a fragment).
14
14
  * @param selector - A CSS selector.
15
+ * @param xml - Read the markup as XML: names keep their case, `take: "html"` gives XML.
15
16
  * @returns Every match, in document order.
16
17
  */
17
- export declare function selectHtml(html: string, selector: string): HtmlMatch[];
18
+ export declare function selectHtml(html: string, selector: string, xml?: boolean): HtmlMatch[];
18
19
  //# sourceMappingURL=html-selector.algorithm.d.ts.map
@@ -6,8 +6,10 @@ import type { EmitOutcome, StepWalk } from './run-steps.use-case.js';
6
6
  * matching `selector`, each in a fresh child scope with the item bound under
7
7
  * `as`; emits a record per iteration when asked.
8
8
  *
9
- * With a concurrent gate, iterations run as permits allow and records come
10
- * out in completion order; without one, in list order.
9
+ * With a concurrent gate, iterations of a list run as permits allow and
10
+ * records come out in completion order; without one, in list order. In web
11
+ * mode each parallel iteration runs in a tab of its own (`runner.fork`); a
12
+ * loop over live elements stays sequential, since its elements live on one page.
11
13
  *
12
14
  * @param step - The forEach step.
13
15
  * @param scope - The scope the list lives in.
@@ -0,0 +1,49 @@
1
+ /** How gently one site is crawled. */
2
+ export interface HostRule {
3
+ /** Minimum time between two request starts to the site, whatever recipe sends them. */
4
+ delayMs?: number;
5
+ /** Requests to the site in flight at once. */
6
+ concurrency?: number;
7
+ }
8
+ /**
9
+ * The crawler's politeness towards each site, across every recipe and run it
10
+ * executes: a default rule for any host, and rules by domain (`example.com`
11
+ * also covers `www.example.com`; the longest match wins).
12
+ */
13
+ export interface ThrottleConfig extends HostRule {
14
+ domains?: Record<string, HostRule>;
15
+ }
16
+ /**
17
+ * Spaces and bounds requests per site, shared by every recipe of a crawler,
18
+ * so two recipes (or two parallel iterations) that hit one site add up to one
19
+ * polite client rather than two. A recipe's own `limits.delayMs` still applies
20
+ * on top, per recipe.
21
+ *
22
+ * Like a single-lane bridge with a traffic light: whoever arrives waits for
23
+ * the car ahead to be far enough, and for a free lane.
24
+ */
25
+ export declare class HostThrottle {
26
+ private readonly config;
27
+ private readonly buckets;
28
+ private readonly domains;
29
+ constructor(config?: ThrottleConfig);
30
+ private bucketFor;
31
+ /** Whether any rule can hold a request back. */
32
+ get active(): boolean;
33
+ /**
34
+ * Waits until a request to `url` may start, then holds one of its site's
35
+ * lanes until the returned release is called.
36
+ *
37
+ * @param url - Where the request goes; anything but `http(s):` passes at once.
38
+ * @returns The release: call it once, when the response arrived or the request failed.
39
+ */
40
+ slot(url: string): Promise<() => void>;
41
+ /**
42
+ * Holds every request to the site of `url` back until `untilMs` (a `Retry-After`).
43
+ *
44
+ * @param url - A URL of the site.
45
+ * @param untilMs - An epoch time.
46
+ */
47
+ pause(url: string, untilMs: number): void;
48
+ }
49
+ //# sourceMappingURL=host-throttle.policy.d.ts.map
@@ -1,9 +1,14 @@
1
1
  export { runSteps } from './run-steps.use-case.js';
2
2
  export type { StepWalkOptions, EmitOutcome } from './run-steps.use-case.js';
3
3
  export type { StepRunner, NextPageResult } from './step-runner.contract.js';
4
+ export { disposeQuietly } from './step-runner.contract.js';
4
5
  export { StepFailure, NoMatchError } from './step-failure.error.js';
5
6
  export { resolveErrorPolicy, backoffFor, sleep } from './retry.policy.js';
6
7
  export { RunGate } from './run-gate.policy.js';
8
+ export { HostThrottle } from './host-throttle.policy.js';
9
+ export { withTransportRetry, resolveRetryRule, transientError, retryDelay, DEFAULT_RETRY_RULE, RETRY_STATUSES } from './transport-retry.policy.js';
10
+ export type { ResolvedRetryRule, Transient, TransportAttempt, RetryContext } from './transport-retry.policy.js';
11
+ export type { HostRule, ThrottleConfig } from './host-throttle.policy.js';
7
12
  export { BlockedError } from './blocked.error.js';
8
13
  export { detectBlock, DEFAULT_BLOCK_RULE } from './block-rule.policy.js';
9
14
  export type { ObservedResponse } from './block-rule.policy.js';
@@ -1,3 +1,4 @@
1
+ import type { HostThrottle } from './host-throttle.policy.js';
1
2
  /**
2
3
  * What bounds a recipe run: how many `forEach` iterations may be in flight and
3
4
  * how close together requests may start. One gate per recipe run, shared by
@@ -10,6 +11,7 @@
10
11
  export declare class RunGate {
11
12
  readonly permits: number;
12
13
  readonly minIntervalMs: number;
14
+ readonly hosts?: HostThrottle | undefined;
13
15
  private readonly shared?;
14
16
  private inFlight;
15
17
  private readonly waiting;
@@ -17,9 +19,10 @@ export declare class RunGate {
17
19
  /**
18
20
  * @param permits - Iterations allowed in flight; 1 is sequential.
19
21
  * @param minIntervalMs - Minimum time between two request starts across the run.
22
+ * @param hosts - The crawler's per-site throttle, shared with every other recipe.
20
23
  * @param shared - The throttle state to share (internal: `nested` gates keep their parent's).
21
24
  */
22
- constructor(permits: number, minIntervalMs: number, shared?: RunGate | undefined);
25
+ constructor(permits: number, minIntervalMs: number, hosts?: HostThrottle | undefined, shared?: RunGate | undefined);
23
26
  /** Whether this gate lets more than one iteration run at once. */
24
27
  get concurrent(): boolean;
25
28
  /**
@@ -33,6 +36,14 @@ export declare class RunGate {
33
36
  * whichever loop started it. Returns at once when the interval has passed.
34
37
  */
35
38
  throttle(): Promise<void>;
39
+ /**
40
+ * Waits until a request to `url` may start: the recipe's interval, then its
41
+ * site's turn in the crawler's per-site throttle.
42
+ *
43
+ * @param url - Where the request goes.
44
+ * @returns The release of the site's lane: call it once the response arrived or the request failed.
45
+ */
46
+ request(url: string): Promise<() => void>;
36
47
  /** The gate for a body running inside an iteration that holds a permit: sequential, same throttle. */
37
48
  nested(): RunGate;
38
49
  }
@@ -1,6 +1,13 @@
1
1
  import type { ExtractionScope, LiveElement } from '../extraction-scope/index.js';
2
2
  import type { PaginateNext, Step } from '../recipe-schema/index.js';
3
3
  import type { BlockedError } from './blocked.error.js';
4
+ /**
5
+ * Disposes a runner, ignoring a failure: a tab whose browser already went
6
+ * away (a rotation, a crash) has nothing left to close.
7
+ *
8
+ * @param runner - The runner.
9
+ */
10
+ export declare function disposeQuietly(runner: StepRunner): Promise<void>;
4
11
  /** What `paginate` learns from the runner after a page body ran. */
5
12
  export type NextPageResult =
6
13
  /** The next page is at this URL (the runner already navigated in web mode). */
@@ -34,6 +41,12 @@ export interface StepRunner {
34
41
  * `false` means it cannot, and the block fails the step like any error.
35
42
  */
36
43
  rotate?: (error: BlockedError) => Promise<boolean>;
44
+ /**
45
+ * A runner of its own for one parallel `forEach` iteration: a new tab in the
46
+ * same browser context (same cookies, its own page), disposed when the
47
+ * iteration ends. Web mode; an api runner is shared as it is.
48
+ */
49
+ fork?: () => Promise<StepRunner>;
37
50
  dispose: () => Promise<void>;
38
51
  }
39
52
  //# sourceMappingURL=step-runner.contract.d.ts.map
@@ -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, records the page's real URL in the
9
- * scope, and checks the response against the recipe's block rule.
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
  */