@wenathlan/saddle 1.8.2 → 1.8.5

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 (257) hide show
  1. package/README.md +9 -9
  2. package/browser/playwright.js +22 -0
  3. package/docs/.gitkeep +0 -0
  4. package/docs/gapmatrix.md +3 -3
  5. package/docs/libraryapi.md +1 -0
  6. package/docs/logs/.gitkeep +0 -0
  7. package/docs/packageaudit185.md +23 -0
  8. package/docs/plans/00.index.md +50 -0
  9. package/docs/plans/01.architecture.md +86 -0
  10. package/docs/plans/02.research.computer.use.md +58 -0
  11. package/docs/plans/03.research.captcha.bypass.md +68 -0
  12. package/docs/plans/04.research.sandbox.ai.md +52 -0
  13. package/docs/plans/05.capture.platform.md +57 -0
  14. package/docs/plans/06.dependencies.md +97 -0
  15. package/docs/plans/07.captcha.test.page.md +41 -0
  16. package/docs/plans/08.production.infra.md +70 -0
  17. package/docs/plans/09.database.schema.md +121 -0
  18. package/docs/plans/10.cloudinary.storage.md +57 -0
  19. package/docs/plans/11.movement.logs.json.md +72 -0
  20. package/docs/plans/12.research.atlas.agent.browser.md +79 -0
  21. package/docs/plans/13.research.anti.detection.md +898 -0
  22. package/docs/plans/14.research.proxy.md +1495 -0
  23. package/docs/plans/15.research.retry.rate.limit.md +1958 -0
  24. package/docs/plans/16.research.crawling.md +1417 -0
  25. package/docs/plans/17.research.caching.md +1610 -0
  26. package/docs/plans/18.research.content.extraction.md +1952 -0
  27. package/docs/plans/19.research.errors.events.md +1523 -0
  28. package/docs/plans/20.research.zod.validation.md +1350 -0
  29. package/docs/plans/21.research.batch.concurrency.md +1888 -0
  30. package/docs/plans/22.research.universal.runtime.md +944 -0
  31. package/docs/plans/23.research.ai.integration.md +1465 -0
  32. package/docs/plans/24.research.memory.persistence.md +1979 -0
  33. package/docs/plans/25.research.server.api.md +342 -0
  34. package/docs/plans/26.research.compilation.md +249 -0
  35. package/docs/plans/27.research.html.parsing.md +251 -0
  36. package/docs/plans/28.action.plan.md +50 -0
  37. package/docs/plans/29.api.reference.md +174 -0
  38. package/docs/plans/30.architecture.plan.md +94 -0
  39. package/docs/plans/31.auditoria.dados.md +163 -0
  40. package/docs/plans/32.bots.automacao.computacional.md +214 -0
  41. package/docs/plans/33.bots.codigo.revisao.md +220 -0
  42. package/docs/plans/34.bots.seguranca.cicd.md +366 -0
  43. package/docs/plans/35.comparativo.concorrencia.md +464 -0
  44. package/docs/plans/36.computational.memory.md +340 -0
  45. package/docs/plans/37.deploystrategy.md +394 -0
  46. package/docs/plans/38.flow.md +155 -0
  47. package/docs/plans/39.multi.platform.bot.md +252 -0
  48. package/docs/plans/40.npm.publish.md +250 -0
  49. package/docs/plans/41.o.que.falta.md +407 -0
  50. package/docs/plans/42.pesquisa.concorrencia.md +721 -0
  51. package/docs/plans/43.plan.universal.architecture.md +496 -0
  52. package/docs/plans/44.reference.md +100 -0
  53. package/docs/plans/45.robotarchitecture.md +237 -0
  54. package/docs/plans/46.scdnintegration.md +284 -0
  55. package/docs/plans/47.multiforge.readme.md +129 -0
  56. package/docs/plans/48.theory.v4.repo.os.md +152 -0
  57. package/docs/plans/49.third.party.infra.md +12 -0
  58. package/docs/plans/50.file.as.compute.md +39 -0
  59. package/docs/plans/51.architecture.virtual.processor.md +80 -0
  60. package/docs/plans/52.manifesto.v8.md +11 -0
  61. package/docs/plans/58.cdn.list.md +23 -0
  62. package/docs/plans/59.sql.frameworks.md +33 -0
  63. package/docs/plans/60.sql.thirdparty.md +26 -0
  64. package/docs/plans/61.objective.multiforge.md +63 -0
  65. package/docs/plans/62.huggingface.upload.md +26 -0
  66. package/docs/plans/63.kaggle.upload.md +24 -0
  67. package/docs/plans/64.npm.storage.md +30 -0
  68. package/docs/plans/65.rclone.terabox.md +32 -0
  69. package/docs/plans/66.buckets.and.models.todo.md +14 -0
  70. package/docs/plans/67.database.todo.md +13 -0
  71. package/docs/plans/68.deploy.packages.todo.md +12 -0
  72. package/docs/plans/69.report.human.operator.md +133 -0
  73. package/docs/plans/70.report.brain2qwerty.ems.md +135 -0
  74. package/docs/plans/71.report.hd.infinito.vram.md +155 -0
  75. package/docs/plans/72.plan.hd.infinito.node.md +146 -0
  76. package/docs/plans/73.plan.scifi.repos.md +125 -0
  77. package/docs/plans/74.000.manifesto.v8.flat.2..md +11 -0
  78. package/docs/plans/README.md +489 -0
  79. package/docs/plans/aggregate_platforms.mjs +146 -0
  80. package/docs/plans/examplesession.json +36 -0
  81. package/docs/plans/missing-facts.md +192 -0
  82. package/docs/plans/models.md +64 -0
  83. package/docs/plans/organize.cjs +270 -0
  84. package/docs/plans/platforms.md +2887 -0
  85. package/docs/plans/sites.md +31322 -0
  86. package/docs/platformpipelineaudit.md +18 -0
  87. package/docs/platformpipelines.md +13 -0
  88. package/docs/registryresearch.md +4 -0
  89. package/docs/release.md +4 -4
  90. package/docs/release182notes.md +2 -0
  91. package/docs/release184notes.md +7 -0
  92. package/docs/release185notes.md +7 -0
  93. package/docs/sources/farm.py +117 -0
  94. package/docs/sources/html/saddle1.html +132 -0
  95. package/docs/sources/html/saddle2.html +157 -0
  96. package/docs/sources/html/saddle3.html +119 -0
  97. package/docs/sources/html/saddle4.html +144 -0
  98. package/docs/sources/html/saddle5.html +72 -0
  99. package/docs/sources/html/saddle6.html +171 -0
  100. package/docs/sources/html/saddle7.html +236 -0
  101. package/docs/sources/saddle.ts +74 -0
  102. package/docs/sources/schema.prisma +88 -0
  103. package/docs/sources/script.sh +64 -0
  104. package/docs/sources/workflows.yml +458 -0
  105. package/docs/talks1/_body.txt +14 -0
  106. package/docs/talks1/_index.md +15 -0
  107. package/docs/talks1/_screenshot.png +0 -0
  108. package/docs/talks1/assistant-01.md +5 -0
  109. package/docs/talks1/assistant-02.md +5 -0
  110. package/docs/talks1/assistant-03.md +531 -0
  111. package/docs/talks1/assistant-04.md +26 -0
  112. package/docs/talks1/assistant-05.md +774 -0
  113. package/docs/talks1/assistant-06.md +1718 -0
  114. package/docs/talks1/scrape-share.cjs +185 -0
  115. package/docs/talks1/scrape-share.ts +183 -0
  116. package/docs/talks1/user-01.md +3 -0
  117. package/docs/talks1/user-02.md +3 -0
  118. package/docs/talks1/user-03.md +88 -0
  119. package/docs/talks1/user-04.md +3 -0
  120. package/docs/talks1/user-05.md +3 -0
  121. package/docs/talks1/user-06.md +88 -0
  122. package/docs/talks1/user-07.md +88 -0
  123. package/docs/talks2/_body.txt +14 -0
  124. package/docs/talks2/_index.md +16 -0
  125. package/docs/talks2/_screenshot.png +0 -0
  126. package/docs/talks2/assistant-01.md +5 -0
  127. package/docs/talks2/assistant-02.md +5 -0
  128. package/docs/talks2/assistant-03.md +424 -0
  129. package/docs/talks2/assistant-04.md +598 -0
  130. package/docs/talks2/assistant-05.md +1280 -0
  131. package/docs/talks2/assistant-06.md +1227 -0
  132. package/docs/talks2/assistant-07.md +1252 -0
  133. package/docs/talks2/user-01.md +3 -0
  134. package/docs/talks2/user-02.md +3 -0
  135. package/docs/talks2/user-03.md +88 -0
  136. package/docs/talks2/user-04.md +88 -0
  137. package/docs/talks2/user-05.md +88 -0
  138. package/docs/talks2/user-06.md +88 -0
  139. package/docs/talks2/user-07.md +3 -0
  140. package/docs/talks3/_body.txt +467 -0
  141. package/docs/talks3/_index.md +10 -0
  142. package/docs/talks3/_screenshot.png +0 -0
  143. package/docs/talks3/assistant-01.md +417 -0
  144. package/docs/talks3/assistant-02.md +417 -0
  145. package/docs/talks3/assistant-03.md +29 -0
  146. package/docs/talks3/assistant-04.md +727 -0
  147. package/docs/talks3/user-01.md +88 -0
  148. package/docs/talks3/user-02.md +88 -0
  149. package/docs/talks3/user-03.md +3 -0
  150. package/docs/talks3/user-04.md +3 -0
  151. package/docs/talks4/_body.txt +14 -0
  152. package/docs/talks4/_index.md +12 -0
  153. package/docs/talks4/_screenshot.png +0 -0
  154. package/docs/talks4/assistant-01.md +5 -0
  155. package/docs/talks4/assistant-02.md +5 -0
  156. package/docs/talks4/assistant-03.md +35 -0
  157. package/docs/talks4/assistant-04.md +512 -0
  158. package/docs/talks4/assistant-05.md +599 -0
  159. package/docs/talks4/user-01.md +3 -0
  160. package/docs/talks4/user-02.md +3 -0
  161. package/docs/talks4/user-03.md +88 -0
  162. package/docs/talks4/user-04.md +88 -0
  163. package/docs/talks4/user-05.md +7 -0
  164. package/docs/talks5/_body.txt +14 -0
  165. package/docs/talks5/_index.md +13 -0
  166. package/docs/talks5/_screenshot.png +0 -0
  167. package/docs/talks5/assistant-01.md +5 -0
  168. package/docs/talks5/assistant-02.md +5 -0
  169. package/docs/talks5/assistant-03.md +690 -0
  170. package/docs/talks5/assistant-04.md +758 -0
  171. package/docs/talks5/assistant-05.md +974 -0
  172. package/docs/talks5/user-01.md +3 -0
  173. package/docs/talks5/user-02.md +3 -0
  174. package/docs/talks5/user-03.md +105 -0
  175. package/docs/talks5/user-04.md +105 -0
  176. package/docs/talks5/user-05.md +63 -0
  177. package/docs/talks5/user-06.md +105 -0
  178. package/docs/talks6/_body.txt +14 -0
  179. package/docs/talks6/_index.md +9 -0
  180. package/docs/talks6/_screenshot.png +0 -0
  181. package/docs/talks6/assistant-01.md +5 -0
  182. package/docs/talks6/assistant-02.md +5 -0
  183. package/docs/talks6/assistant-03.md +1499 -0
  184. package/docs/talks6/user-01.md +3 -0
  185. package/docs/talks6/user-02.md +3 -0
  186. package/docs/talks6/user-03.md +88 -0
  187. package/docs/talks6/user-04.md +88 -0
  188. package/docs/talks7/_body.txt +14 -0
  189. package/docs/talks7/_index.md +10 -0
  190. package/docs/talks7/_screenshot.png +0 -0
  191. package/docs/talks7/assistant-01.md +5 -0
  192. package/docs/talks7/assistant-02.md +5 -0
  193. package/docs/talks7/assistant-03.md +523 -0
  194. package/docs/talks7/assistant-04.md +617 -0
  195. package/docs/talks7/user-01.md +3 -0
  196. package/docs/talks7/user-02.md +3 -0
  197. package/docs/talks7/user-03.md +105 -0
  198. package/docs/talks7/user-04.md +67 -0
  199. package/docs/talks8/conversa1.txt +1322 -0
  200. package/docs/talks8/conversa2.txt +237 -0
  201. package/docs/talks9/Beyond the Obvious_ 50 Plataformas Auto-Hospedadas de Forja de C/303/263digo para Al/303/251m de Gitea e GitLab.md" +174 -0
  202. package/docs/talks9/De NPM a Multi-Linguagem_ Uma Arquitetura T/303/251cnica para a Execu/303/247/303/243o Integrada de C/303/263digo no Ecossistema Node.js.md" +59 -0
  203. package/docs/talks9/De NPM a VMs Virtuais_ Uma An/303/241lise Arquitet/303/264nica para a Realiza/303/247/303/243o do Ciclo de Vida do Projeto SADDLE.md" +91 -0
  204. package/docs/talks9/Mapeamento da Engrenagem Computacional_ Uma Arquitetura para Execu/303/247/303/243o Isolada e Persist/303/252ncia em Ambientes Distribu/303/255dos.md" +116 -0
  205. package/docs/talks9/O Cen/303/241rio Pr/303/241tico do SADDLE_ Uma An/303/241lise de Viabilidade e Modelo de Ciclo de Vida Integrado.md" +128 -0
  206. package/docs/talks9/README (2).md +489 -0
  207. package/docs/talks9/README.md +198 -0
  208. package/docs/talks9/Viabilidade do Saddle_ Uma An/303/241lise T/303/251cnica da Transforma/303/247/303/243o de Armazenamento Remoto em Mem/303/263ria Computacional.md" +80 -0
  209. package/docs/talks9/conversa.txt +544 -0
  210. package/docs/talks9/other (2).md +39 -0
  211. package/docs/talks9/other.md +57 -0
  212. package/docs/talks9/outro.txt +24 -0
  213. package/extension/README.md +3 -3
  214. package/extension/serviceworker.js +63 -4
  215. package/extension/worker.js +3 -1
  216. package/package.json +12 -2
  217. package/packager/manifest.js +1 -1
  218. package/scrape/agent.ts +122 -0
  219. package/scrape/batch.ts +79 -0
  220. package/scrape/biome.json +76 -0
  221. package/scrape/browser.ts +222 -0
  222. package/scrape/cache.ts +84 -0
  223. package/scrape/chunking.ts +193 -0
  224. package/scrape/cli.ts +105 -0
  225. package/scrape/crawler.ts +115 -0
  226. package/scrape/dev-server.ts +94 -0
  227. package/scrape/errors.ts +132 -0
  228. package/scrape/events.ts +26 -0
  229. package/scrape/extract.ts +165 -0
  230. package/scrape/fetch.ts +105 -0
  231. package/scrape/formats.ts +85 -0
  232. package/scrape/headers.ts +71 -0
  233. package/scrape/index.ts +92 -0
  234. package/scrape/jsdom.d.ts +6 -0
  235. package/scrape/llms-txt.ts +84 -0
  236. package/scrape/middleware.ts +90 -0
  237. package/scrape/package-lock.json +9397 -0
  238. package/scrape/package.json +1420 -0
  239. package/scrape/pool.ts +95 -0
  240. package/scrape/port.ts +18 -0
  241. package/scrape/proxy.ts +103 -0
  242. package/scrape/rate-limiter.ts +95 -0
  243. package/scrape/renderer.ts +194 -0
  244. package/scrape/retry.ts +64 -0
  245. package/scrape/robots.ts +137 -0
  246. package/scrape/scrape.ts +123 -0
  247. package/scrape/serialize.ts +310 -0
  248. package/scrape/server.ts +137 -0
  249. package/scrape/session.ts +109 -0
  250. package/scrape/sitemap.ts +131 -0
  251. package/scrape/tokens.ts +45 -0
  252. package/scrape/tsconfig.json +28 -0
  253. package/scrape/types.ts +214 -0
  254. package/scrape/utils.ts +77 -0
  255. package/scrape/vite.config.ts +55 -0
  256. package/scrape/vitest.config.ts +17 -0
  257. package/workflow/templates.js +4 -4
@@ -0,0 +1,85 @@
1
+ import type { ScrapeFormat, SerializeTarget, SerializeOptions, ScrapeResult } from './types.js';
2
+ import { serializeResult as sr } from './serialize.js';
3
+
4
+ const FORMAT_ALIASES: Record<string, ScrapeFormat> = {
5
+ md: 'markdown',
6
+ txt: 'text',
7
+ plain: 'text',
8
+ xml: 'xml',
9
+ json: 'json',
10
+ redis: 'redis',
11
+ html: 'html',
12
+ h: 'html',
13
+ };
14
+
15
+ const FORMAT_EXTENSIONS: Record<string, ScrapeFormat> = {
16
+ '.md': 'markdown',
17
+ '.markdown': 'markdown',
18
+ '.html': 'html',
19
+ '.htm': 'html',
20
+ '.txt': 'text',
21
+ '.json': 'json',
22
+ '.xml': 'xml',
23
+ '.redis': 'redis',
24
+ };
25
+
26
+ export function resolveFormat(format: string): ScrapeFormat {
27
+ const lower = format.toLowerCase().trim();
28
+ return FORMAT_ALIASES[lower] || (lower as ScrapeFormat);
29
+ }
30
+
31
+ export function formatFromExtension(ext: string): ScrapeFormat | null {
32
+ return FORMAT_EXTENSIONS[ext.toLowerCase()] ?? null;
33
+ }
34
+
35
+ export function extensionForFormat(format: ScrapeFormat): string {
36
+ const map: Record<ScrapeFormat, string> = {
37
+ markdown: '.md',
38
+ html: '.html',
39
+ text: '.txt',
40
+ json: '.json',
41
+ xml: '.xml',
42
+ redis: '.redis',
43
+ };
44
+ return map[format] || '.md';
45
+ }
46
+
47
+ export function detectContentType(html: string): 'article' | 'list' | 'page' | 'other' {
48
+ if (html.includes('<article') || html.includes('entry-content') || html.includes('class="post-content"') || html.includes('class="article-content"') || html.includes('role="main"')) {
49
+ return 'article';
50
+ }
51
+ const listCount = (html.match(/<li>/gi) || []).length;
52
+ if (listCount > 20) return 'list';
53
+ if (html.includes('<article') || html.includes('entry-content')) return 'article';
54
+ return 'page';
55
+ }
56
+
57
+ export function buildSerializeOptions(format: ScrapeFormat, pretty = true): SerializeOptions {
58
+ const targetMap: Record<ScrapeFormat, SerializeTarget> = {
59
+ markdown: 'markdown',
60
+ html: 'markdown',
61
+ text: 'text',
62
+ json: 'json',
63
+ xml: 'xml',
64
+ redis: 'redis',
65
+ };
66
+ return {
67
+ format: targetMap[format] || 'markdown',
68
+ pretty,
69
+ includeMetadata: true,
70
+ };
71
+ }
72
+
73
+ export async function convertResult(result: ScrapeResult, targetFormat: ScrapeFormat): Promise<ScrapeResult> {
74
+ if (result.format === targetFormat) return result;
75
+
76
+ const opts = buildSerializeOptions(targetFormat);
77
+ const serialized = sr(result, opts);
78
+
79
+ return {
80
+ ...result,
81
+ content: serialized.content,
82
+ format: targetFormat,
83
+ size: serialized.size,
84
+ };
85
+ }
@@ -0,0 +1,71 @@
1
+ export interface HeaderProfile {
2
+ userAgent: string;
3
+ accept: string;
4
+ acceptLanguage: string;
5
+ secChUa: string;
6
+ secChUaPlatform: string;
7
+ }
8
+
9
+ const CHROME_PROFILES: HeaderProfile[] = [
10
+ {
11
+ userAgent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36',
12
+ accept: 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8',
13
+ acceptLanguage: 'en-US,en;q=0.9',
14
+ secChUa: '"Chromium";v="131", "Not_A Brand";v="24"',
15
+ secChUaPlatform: '"Windows"',
16
+ },
17
+ {
18
+ userAgent: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36',
19
+ accept: 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8',
20
+ acceptLanguage: 'en-US,en;q=0.9',
21
+ secChUa: '"Chromium";v="131", "Not_A Brand";v="24"',
22
+ secChUaPlatform: '"macOS"',
23
+ },
24
+ {
25
+ userAgent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:133.0) Gecko/20100101 Firefox/133.0',
26
+ accept: 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8',
27
+ acceptLanguage: 'en-US,en;q=0.5',
28
+ secChUa: '',
29
+ secChUaPlatform: '"Windows"',
30
+ },
31
+ {
32
+ userAgent: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.2 Safari/605.1.15',
33
+ accept: 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
34
+ acceptLanguage: 'en-US,en;q=0.9',
35
+ secChUa: '',
36
+ secChUaPlatform: '"macOS"',
37
+ },
38
+ ];
39
+
40
+ export function getRandomProfile(): HeaderProfile {
41
+ return CHROME_PROFILES[Math.floor(Math.random() * CHROME_PROFILES.length)];
42
+ }
43
+
44
+ export function getHeaders(profile?: HeaderProfile): Record<string, string> {
45
+ const p = profile || getRandomProfile();
46
+ const headers: Record<string, string> = {
47
+ 'User-Agent': p.userAgent,
48
+ 'Accept': p.accept,
49
+ 'Accept-Language': p.acceptLanguage,
50
+ 'Accept-Encoding': 'gzip, deflate, br',
51
+ 'Connection': 'keep-alive',
52
+ 'Upgrade-Insecure-Requests': '1',
53
+ 'Sec-Fetch-Dest': 'document',
54
+ 'Sec-Fetch-Mode': 'navigate',
55
+ 'Sec-Fetch-Site': 'none',
56
+ 'Sec-Fetch-User': '?1',
57
+ };
58
+ if (p.secChUa) {
59
+ headers['sec-ch-ua'] = p.secChUa;
60
+ headers['sec-ch-ua-mobile'] = '?0';
61
+ headers['sec-ch-ua-platform'] = p.secChUaPlatform;
62
+ }
63
+ return headers;
64
+ }
65
+
66
+ export function mergeHeaders(
67
+ base: Record<string, string>,
68
+ override: Record<string, string>
69
+ ): Record<string, string> {
70
+ return { ...base, ...override };
71
+ }
@@ -0,0 +1,92 @@
1
+ // ─── Core Scraping ───
2
+ export { AgentBrowser, createBrowser } from './browser.js';
3
+ export { scrapeUrl, scrapeHtml, scrapeWithBrowser } from './scrape.js';
4
+ export { extractContent, extractReadable } from './extract.js';
5
+ export type { ExtractedContent } from './extract.js';
6
+ export { fetchHtml, fetchAndParse, detectRenderingMode } from './fetch.js';
7
+ export type { FetchResult } from './fetch.js';
8
+
9
+ // ─── Serialization ───
10
+ export { serializeResult, serializeHtml } from './serialize.js';
11
+ export { resolveFormat, formatFromExtension, extensionForFormat, buildSerializeOptions, convertResult } from './formats.js';
12
+
13
+ // ─── Renderer ───
14
+ export { PygameRenderer, createRenderer } from './renderer.js';
15
+
16
+ // ─── AI/LLM ───
17
+ export { formatForAgent, buildContext } from './agent.js';
18
+ export { estimateTokens, countTokens, fitsInContext, truncateToTokens, tokenCost } from './tokens.js';
19
+ export type { ModelType } from './tokens.js';
20
+ export { chunkMarkdown, chunkText, formatChunksForRAG } from './chunking.js';
21
+ export type { Chunk, ChunkOptions } from './chunking.js';
22
+ export { generateLlmsTxt, generateLlmsFullTxt } from './llms-txt.js';
23
+ export type { LlmsTxtOptions } from './llms-txt.js';
24
+
25
+ // ─── Infrastructure ───
26
+ export { WebScrapeError, ValidationError, TimeoutError, BlockedError, RateLimitError, ProxyError, ParseError, AuthError, NetworkError, BrowserNotAvailableError } from './errors.js';
27
+ export type { ErrorCode } from './errors.js';
28
+ export { createEventEmitter, globalEmitter } from './events.js';
29
+ export type { WebScrapeEvents, EventEmitter } from './events.js';
30
+ export { withRetry, isRetryableError, AbortError } from './retry.js';
31
+ export { RateLimiter, createRateLimiter } from './rate-limiter.js';
32
+ export type { RateLimiterConfig } from './rate-limiter.js';
33
+ export { ProxyPool, createProxyPool } from './proxy.js';
34
+ export type { ProxyPoolConfig, ProxyRotationStrategy } from './proxy.js';
35
+ export { CookieJar, ScrapingSession, createSession } from './session.js';
36
+ export type { Cookie } from './session.js';
37
+ export { getRandomProfile, getHeaders, mergeHeaders } from './headers.js';
38
+ export type { HeaderProfile } from './headers.js';
39
+ export { WebScrapeCache, createCache } from './cache.js';
40
+ export type { CacheConfig, CacheEntry } from './cache.js';
41
+ export { MiddlewarePipeline, createPipeline, loggingMiddleware, timeoutMiddleware, retryMiddleware } from './middleware.js';
42
+ export type { Middleware, MiddlewareContext, MiddlewareNext } from './middleware.js';
43
+
44
+ // ─── Crawling ───
45
+ export { crawl } from './crawler.js';
46
+ export type { CrawlOptions } from './crawler.js';
47
+ export { fetchSitemap, discoverSitemaps, parseSitemap } from './sitemap.js';
48
+ export type { SitemapUrl, SitemapResult } from './sitemap.js';
49
+ export { fetchRobotsTxt, isAllowed, getCrawlDelay, getSitemaps } from './robots.js';
50
+ export type { RobotsTxt, RobotsDirective } from './robots.js';
51
+
52
+ // ─── Batch & Pool ───
53
+ export { batchScrape, batchScrapeSequential } from './batch.js';
54
+ export type { BatchResult } from './batch.js';
55
+ export { BrowserPool, createPool } from './pool.js';
56
+ export type { PoolConfig } from './pool.js';
57
+
58
+ // ─── Server ───
59
+ export { createServer, app } from './server.js';
60
+ export type { ServerConfig } from './server.js';
61
+
62
+ // ─── Utilities ───
63
+ export { ensureDir, writeOutput, slugify, truncate, chunkText as chunkTextUtil, delay, isValidUrl, normalizeUrl, isInternalUrl } from './utils.js';
64
+ export { randomPort, resetPort } from './utils/port.js';
65
+
66
+ // ─── Types ───
67
+ export {
68
+ ScrapeOptionsSchema,
69
+ BrowserAgentConfigSchema,
70
+ } from './types.js';
71
+ export type {
72
+ ScrapeFormat,
73
+ SerializeTarget,
74
+ ScrapeOptions,
75
+ ScrapeResult,
76
+ PageMetadata,
77
+ LinkInfo,
78
+ ImageInfo,
79
+ TableInfo,
80
+ BrowserAgentConfig,
81
+ ExtractOptions,
82
+ SerializeOptions,
83
+ SerializedOutput,
84
+ AgentOutput,
85
+ RenderOptions,
86
+ ChromeCommand,
87
+ CliOptions,
88
+ RetryConfig,
89
+ ProxyConfig,
90
+ CrawlStats,
91
+ BatchOptions,
92
+ } from './types.js';
@@ -0,0 +1,6 @@
1
+ declare module 'jsdom' {
2
+ export class JSDOM {
3
+ constructor(html?: string, options?: Record<string, unknown>);
4
+ window: Window;
5
+ }
6
+ }
@@ -0,0 +1,84 @@
1
+ import type { ScrapeResult } from './types.js';
2
+
3
+ export interface LlmsTxtOptions {
4
+ siteName?: string;
5
+ description?: string;
6
+ includeOptional?: boolean;
7
+ }
8
+
9
+ export function generateLlmsTxt(
10
+ results: ScrapeResult[],
11
+ options: LlmsTxtOptions = {}
12
+ ): string {
13
+ const siteName = options.siteName || results[0]?.metadata?.title || 'Site';
14
+ const description = options.description || results[0]?.metadata?.description || '';
15
+
16
+ const lines: string[] = [];
17
+ lines.push(`# ${siteName}`);
18
+ lines.push('');
19
+ if (description) {
20
+ lines.push(`> ${description}`);
21
+ lines.push('');
22
+ }
23
+
24
+ const pages: ScrapeResult[] = [];
25
+ const docs: ScrapeResult[] = [];
26
+
27
+ for (const result of results) {
28
+ const url = result.url.toLowerCase();
29
+ if (url.includes('doc') || url.includes('guide') || url.includes('api')) {
30
+ docs.push(result);
31
+ } else {
32
+ pages.push(result);
33
+ }
34
+ }
35
+
36
+ if (pages.length > 0) {
37
+ lines.push('## Pages');
38
+ lines.push('');
39
+ for (const page of pages.slice(0, 20)) {
40
+ const title = page.metadata.title || page.title;
41
+ const desc = page.metadata.description || '';
42
+ lines.push(`- ${title}: ${desc || page.url}`);
43
+ }
44
+ lines.push('');
45
+ }
46
+
47
+ if (docs.length > 0) {
48
+ lines.push('## Documentation');
49
+ lines.push('');
50
+ for (const doc of docs.slice(0, 20)) {
51
+ const title = doc.metadata.title || doc.title;
52
+ const desc = doc.metadata.description || '';
53
+ lines.push(`- ${title}: ${desc || doc.url}`);
54
+ }
55
+ lines.push('');
56
+ }
57
+
58
+ if (options.includeOptional && results.length > 5) {
59
+ lines.push('## Optional');
60
+ lines.push('');
61
+ lines.push(`- Full content: ${results.length} pages scraped`);
62
+ lines.push(`- Last updated: ${new Date().toISOString().split('T')[0]}`);
63
+ lines.push('');
64
+ }
65
+
66
+ return lines.join('\n');
67
+ }
68
+
69
+ export function generateLlmsFullTxt(results: ScrapeResult[]): string {
70
+ const parts: string[] = [];
71
+
72
+ for (const result of results) {
73
+ parts.push(`# ${result.title || result.metadata.title || 'Untitled'}`);
74
+ parts.push('');
75
+ parts.push(`Source: ${result.url}`);
76
+ parts.push('');
77
+ parts.push(result.content);
78
+ parts.push('');
79
+ parts.push('---');
80
+ parts.push('');
81
+ }
82
+
83
+ return parts.join('\n');
84
+ }
@@ -0,0 +1,90 @@
1
+ export interface MiddlewareContext<T = Record<string, unknown>> {
2
+ data: T;
3
+ state: Record<string, unknown>;
4
+ startTime: number;
5
+ aborted: boolean;
6
+ abort(): void;
7
+ }
8
+
9
+ export type MiddlewareNext = () => Promise<void>;
10
+ export type Middleware<T = Record<string, unknown>> = (
11
+ ctx: MiddlewareContext<T>,
12
+ next: MiddlewareNext
13
+ ) => Promise<void>;
14
+
15
+ export class MiddlewarePipeline<T = Record<string, unknown>> {
16
+ private middlewares: Middleware<T>[] = [];
17
+
18
+ use(middleware: Middleware<T>): this {
19
+ this.middlewares.push(middleware);
20
+ return this;
21
+ }
22
+
23
+ async execute(initialData: T): Promise<MiddlewareContext<T>> {
24
+ const ctx: MiddlewareContext<T> = {
25
+ data: initialData,
26
+ state: {},
27
+ startTime: Date.now(),
28
+ aborted: false,
29
+ abort() { this.aborted = true; },
30
+ };
31
+
32
+ let index = 0;
33
+
34
+ const next = async (): Promise<void> => {
35
+ if (ctx.aborted) return;
36
+ if (index < this.middlewares.length) {
37
+ const middleware = this.middlewares[index++];
38
+ await middleware(ctx, next);
39
+ }
40
+ };
41
+
42
+ await next();
43
+ return ctx;
44
+ }
45
+
46
+ clear(): void {
47
+ this.middlewares = [];
48
+ }
49
+ }
50
+
51
+ export function loggingMiddleware(logger?: { info: (msg: string) => void }): Middleware {
52
+ return async (_ctx, next) => {
53
+ const start = Date.now();
54
+ await next();
55
+ const duration = Date.now() - start;
56
+ logger?.info(`Request completed in ${duration}ms`);
57
+ };
58
+ }
59
+
60
+ export function timeoutMiddleware(timeoutMs: number): Middleware {
61
+ return async (ctx, next) => {
62
+ const timer = setTimeout(() => ctx.abort(), timeoutMs);
63
+ try {
64
+ await next();
65
+ } finally {
66
+ clearTimeout(timer);
67
+ }
68
+ };
69
+ }
70
+
71
+ export function retryMiddleware(maxRetries: number, delayMs: number): Middleware {
72
+ return async (ctx, next) => {
73
+ let attempt = 0;
74
+ while (attempt <= maxRetries) {
75
+ ctx.state.attempt = attempt;
76
+ try {
77
+ await next();
78
+ return;
79
+ } catch (error) {
80
+ if (attempt === maxRetries) throw error;
81
+ await new Promise(r => setTimeout(r, delayMs * Math.pow(2, attempt)));
82
+ attempt++;
83
+ }
84
+ }
85
+ };
86
+ }
87
+
88
+ export function createPipeline<T = Record<string, unknown>>(): MiddlewarePipeline<T> {
89
+ return new MiddlewarePipeline<T>();
90
+ }