recker 1.0.43 → 1.0.44

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 (459) hide show
  1. package/README.md +47 -0
  2. package/dist/bin/recker-linux-x64 +0 -0
  3. package/dist/bin/recker-macos-x64 +0 -0
  4. package/dist/bin/recker-win-x64.exe +0 -0
  5. package/dist/bin/rek.cjs +85152 -100207
  6. package/dist/browser/ai/adaptive-timeout.d.ts +50 -0
  7. package/dist/browser/ai/adaptive-timeout.js +208 -0
  8. package/dist/browser/ai/client.d.ts +22 -0
  9. package/dist/browser/ai/client.js +294 -0
  10. package/dist/browser/ai/index.d.ts +14 -0
  11. package/dist/browser/ai/index.js +11 -0
  12. package/dist/browser/ai/providers/anthropic.d.ts +63 -0
  13. package/dist/browser/ai/providers/anthropic.js +370 -0
  14. package/dist/browser/ai/providers/base.d.ts +48 -0
  15. package/dist/browser/ai/providers/base.js +150 -0
  16. package/dist/browser/ai/providers/google.d.ts +59 -0
  17. package/dist/browser/ai/providers/google.js +305 -0
  18. package/dist/browser/ai/providers/ollama.d.ts +44 -0
  19. package/dist/browser/ai/providers/ollama.js +240 -0
  20. package/dist/browser/ai/providers/openai.d.ts +64 -0
  21. package/dist/browser/ai/providers/openai.js +298 -0
  22. package/dist/browser/ai/rate-limiter.d.ts +43 -0
  23. package/dist/browser/ai/rate-limiter.js +215 -0
  24. package/dist/browser/ai/vector/index.d.ts +2 -0
  25. package/dist/browser/ai/vector/index.js +2 -0
  26. package/dist/browser/ai/vector/similarity.d.ts +2 -0
  27. package/dist/browser/ai/vector/similarity.js +27 -0
  28. package/dist/browser/ai/vector/store.d.ts +27 -0
  29. package/dist/browser/ai/vector/store.js +82 -0
  30. package/dist/browser/browser/cache.d.ts +2 -40
  31. package/dist/browser/browser/cache.js +2 -199
  32. package/dist/browser/browser/index.d.ts +8 -0
  33. package/dist/browser/browser/index.js +8 -0
  34. package/dist/browser/browser/recker.d.ts +8 -1
  35. package/dist/browser/browser/recker.js +8 -2
  36. package/dist/browser/cache/indexed-db.d.ts +10 -0
  37. package/dist/browser/cache/indexed-db.js +88 -0
  38. package/dist/browser/cache/service-worker-cache.d.ts +18 -0
  39. package/dist/browser/cache/service-worker-cache.js +103 -0
  40. package/dist/browser/cache.d.ts +2 -40
  41. package/dist/browser/cache.js +2 -199
  42. package/dist/browser/constants/user-agents.d.ts +7 -0
  43. package/dist/browser/constants/user-agents.js +7 -0
  44. package/dist/browser/core/client.d.ts +2 -0
  45. package/dist/browser/core/client.js +19 -1
  46. package/dist/browser/index.d.ts +8 -0
  47. package/dist/browser/index.js +8 -0
  48. package/dist/browser/plugins/har-recorder.d.ts +40 -0
  49. package/dist/browser/plugins/har-recorder.js +120 -0
  50. package/dist/browser/plugins/network-simulation.d.ts +7 -0
  51. package/dist/browser/plugins/network-simulation.js +13 -0
  52. package/dist/browser/presets/android.d.ts +2 -0
  53. package/dist/browser/presets/android.js +16 -0
  54. package/dist/browser/presets/anthropic.d.ts +8 -0
  55. package/dist/browser/presets/anthropic.js +27 -0
  56. package/dist/browser/presets/aws.d.ts +19 -0
  57. package/dist/browser/presets/aws.js +68 -0
  58. package/dist/browser/presets/azure-openai.d.ts +10 -0
  59. package/dist/browser/presets/azure-openai.js +35 -0
  60. package/dist/browser/presets/azure.d.ts +41 -0
  61. package/dist/browser/presets/azure.js +104 -0
  62. package/dist/browser/presets/chaturbate.d.ts +2 -0
  63. package/dist/browser/presets/chaturbate.js +17 -0
  64. package/dist/browser/presets/cloudflare.d.ts +12 -0
  65. package/dist/browser/presets/cloudflare.js +39 -0
  66. package/dist/browser/presets/cohere.d.ts +7 -0
  67. package/dist/browser/presets/cohere.js +22 -0
  68. package/dist/browser/presets/deepseek.d.ts +7 -0
  69. package/dist/browser/presets/deepseek.js +22 -0
  70. package/dist/browser/presets/digitalocean.d.ts +5 -0
  71. package/dist/browser/presets/digitalocean.js +16 -0
  72. package/dist/browser/presets/discord.d.ts +6 -0
  73. package/dist/browser/presets/discord.js +17 -0
  74. package/dist/browser/presets/elevenlabs.d.ts +6 -0
  75. package/dist/browser/presets/elevenlabs.js +20 -0
  76. package/dist/browser/presets/enhancers.d.ts +20 -0
  77. package/dist/browser/presets/enhancers.js +85 -0
  78. package/dist/browser/presets/fireworks.d.ts +7 -0
  79. package/dist/browser/presets/fireworks.js +22 -0
  80. package/dist/browser/presets/gcp.d.ts +34 -0
  81. package/dist/browser/presets/gcp.js +91 -0
  82. package/dist/browser/presets/gemini.d.ts +7 -0
  83. package/dist/browser/presets/gemini.js +23 -0
  84. package/dist/browser/presets/github.d.ts +6 -0
  85. package/dist/browser/presets/github.js +17 -0
  86. package/dist/browser/presets/gitlab.d.ts +6 -0
  87. package/dist/browser/presets/gitlab.js +16 -0
  88. package/dist/browser/presets/groq.d.ts +7 -0
  89. package/dist/browser/presets/groq.js +22 -0
  90. package/dist/browser/presets/hubspot.d.ts +9 -0
  91. package/dist/browser/presets/hubspot.js +28 -0
  92. package/dist/browser/presets/huggingface.d.ts +7 -0
  93. package/dist/browser/presets/huggingface.js +23 -0
  94. package/dist/browser/presets/index.d.ts +47 -0
  95. package/dist/browser/presets/index.js +47 -0
  96. package/dist/browser/presets/ios.d.ts +2 -0
  97. package/dist/browser/presets/ios.js +13 -0
  98. package/dist/browser/presets/linear.d.ts +5 -0
  99. package/dist/browser/presets/linear.js +16 -0
  100. package/dist/browser/presets/mailgun.d.ts +7 -0
  101. package/dist/browser/presets/mailgun.js +20 -0
  102. package/dist/browser/presets/meta.d.ts +10 -0
  103. package/dist/browser/presets/meta.js +33 -0
  104. package/dist/browser/presets/mistral.d.ts +7 -0
  105. package/dist/browser/presets/mistral.js +22 -0
  106. package/dist/browser/presets/notion.d.ts +6 -0
  107. package/dist/browser/presets/notion.js +17 -0
  108. package/dist/browser/presets/openai.d.ts +9 -0
  109. package/dist/browser/presets/openai.js +30 -0
  110. package/dist/browser/presets/oracle.d.ts +19 -0
  111. package/dist/browser/presets/oracle.js +117 -0
  112. package/dist/browser/presets/perplexity.d.ts +7 -0
  113. package/dist/browser/presets/perplexity.js +22 -0
  114. package/dist/browser/presets/pinecone.d.ts +8 -0
  115. package/dist/browser/presets/pinecone.js +42 -0
  116. package/dist/browser/presets/registry.d.ts +23 -0
  117. package/dist/browser/presets/registry.js +519 -0
  118. package/dist/browser/presets/replicate.d.ts +7 -0
  119. package/dist/browser/presets/replicate.js +23 -0
  120. package/dist/browser/presets/sendgrid.d.ts +6 -0
  121. package/dist/browser/presets/sendgrid.js +20 -0
  122. package/dist/browser/presets/sentry.d.ts +11 -0
  123. package/dist/browser/presets/sentry.js +48 -0
  124. package/dist/browser/presets/sinch.d.ts +9 -0
  125. package/dist/browser/presets/sinch.js +39 -0
  126. package/dist/browser/presets/slack.d.ts +5 -0
  127. package/dist/browser/presets/slack.js +16 -0
  128. package/dist/browser/presets/square.d.ts +10 -0
  129. package/dist/browser/presets/square.js +33 -0
  130. package/dist/browser/presets/stripe.d.ts +7 -0
  131. package/dist/browser/presets/stripe.js +23 -0
  132. package/dist/browser/presets/supabase.d.ts +6 -0
  133. package/dist/browser/presets/supabase.js +18 -0
  134. package/dist/browser/presets/tiktok.d.ts +10 -0
  135. package/dist/browser/presets/tiktok.js +38 -0
  136. package/dist/browser/presets/together.d.ts +7 -0
  137. package/dist/browser/presets/together.js +22 -0
  138. package/dist/browser/presets/twilio.d.ts +6 -0
  139. package/dist/browser/presets/twilio.js +17 -0
  140. package/dist/browser/presets/vercel.d.ts +6 -0
  141. package/dist/browser/presets/vercel.js +23 -0
  142. package/dist/browser/presets/vultr.d.ts +5 -0
  143. package/dist/browser/presets/vultr.js +16 -0
  144. package/dist/browser/presets/xai.d.ts +8 -0
  145. package/dist/browser/presets/xai.js +23 -0
  146. package/dist/browser/presets/youtube.d.ts +5 -0
  147. package/dist/browser/presets/youtube.js +20 -0
  148. package/dist/browser/recker.d.ts +8 -1
  149. package/dist/browser/recker.js +8 -2
  150. package/dist/browser/scrape/document.d.ts +5 -4
  151. package/dist/browser/scrape/document.js +89 -76
  152. package/dist/browser/scrape/element.d.ts +10 -8
  153. package/dist/browser/scrape/element.js +295 -81
  154. package/dist/browser/scrape/extractors.d.ts +11 -11
  155. package/dist/browser/scrape/extractors.js +145 -113
  156. package/dist/browser/scrape/parser/back.d.ts +1 -0
  157. package/dist/browser/scrape/parser/back.js +3 -0
  158. package/dist/browser/scrape/parser/index.d.ts +20 -0
  159. package/dist/browser/scrape/parser/index.js +19 -0
  160. package/dist/browser/scrape/parser/matcher.d.ts +30 -0
  161. package/dist/browser/scrape/parser/matcher.js +99 -0
  162. package/dist/browser/scrape/parser/nodes/comment.d.ts +12 -0
  163. package/dist/browser/scrape/parser/nodes/comment.js +21 -0
  164. package/dist/browser/scrape/parser/nodes/html.d.ts +110 -0
  165. package/dist/browser/scrape/parser/nodes/html.js +978 -0
  166. package/dist/browser/scrape/parser/nodes/node.d.ts +18 -0
  167. package/dist/browser/scrape/parser/nodes/node.js +31 -0
  168. package/dist/browser/scrape/parser/nodes/text.d.ts +14 -0
  169. package/dist/browser/scrape/parser/nodes/text.js +30 -0
  170. package/dist/browser/scrape/parser/nodes/type.d.ts +6 -0
  171. package/dist/browser/scrape/parser/nodes/type.js +7 -0
  172. package/dist/browser/scrape/parser/parse.d.ts +1 -0
  173. package/dist/browser/scrape/parser/parse.js +1 -0
  174. package/dist/browser/scrape/parser/valid.d.ts +2 -0
  175. package/dist/browser/scrape/parser/valid.js +5 -0
  176. package/dist/browser/scrape/parser/void-tag.d.ts +7 -0
  177. package/dist/browser/scrape/parser/void-tag.js +43 -0
  178. package/dist/browser/scrape/types.d.ts +7 -0
  179. package/dist/browser/seo/analyzer.d.ts +59 -0
  180. package/dist/browser/seo/analyzer.js +1399 -0
  181. package/dist/browser/seo/keywords.d.ts +16 -0
  182. package/dist/browser/seo/keywords.js +55 -0
  183. package/dist/browser/seo/rules/accessibility.d.ts +2 -0
  184. package/dist/browser/seo/rules/accessibility.js +733 -0
  185. package/dist/browser/seo/rules/ai-search.d.ts +2 -0
  186. package/dist/browser/seo/rules/ai-search.js +436 -0
  187. package/dist/browser/seo/rules/analytics.d.ts +2 -0
  188. package/dist/browser/seo/rules/analytics.js +306 -0
  189. package/dist/browser/seo/rules/best-practices.d.ts +2 -0
  190. package/dist/browser/seo/rules/best-practices.js +195 -0
  191. package/dist/browser/seo/rules/canonical.d.ts +12 -0
  192. package/dist/browser/seo/rules/canonical.js +270 -0
  193. package/dist/browser/seo/rules/content.d.ts +2 -0
  194. package/dist/browser/seo/rules/content.js +522 -0
  195. package/dist/browser/seo/rules/crawl.d.ts +2 -0
  196. package/dist/browser/seo/rules/crawl.js +435 -0
  197. package/dist/browser/seo/rules/cwv.d.ts +2 -0
  198. package/dist/browser/seo/rules/cwv.js +248 -0
  199. package/dist/browser/seo/rules/ecommerce.d.ts +2 -0
  200. package/dist/browser/seo/rules/ecommerce.js +312 -0
  201. package/dist/browser/seo/rules/i18n.d.ts +2 -0
  202. package/dist/browser/seo/rules/i18n.js +288 -0
  203. package/dist/browser/seo/rules/images.d.ts +2 -0
  204. package/dist/browser/seo/rules/images.js +255 -0
  205. package/dist/browser/seo/rules/index.d.ts +52 -0
  206. package/dist/browser/seo/rules/index.js +159 -0
  207. package/dist/browser/seo/rules/internal-linking.d.ts +2 -0
  208. package/dist/browser/seo/rules/internal-linking.js +394 -0
  209. package/dist/browser/seo/rules/links.d.ts +2 -0
  210. package/dist/browser/seo/rules/links.js +498 -0
  211. package/dist/browser/seo/rules/local.d.ts +2 -0
  212. package/dist/browser/seo/rules/local.js +289 -0
  213. package/dist/browser/seo/rules/meta.d.ts +2 -0
  214. package/dist/browser/seo/rules/meta.js +805 -0
  215. package/dist/browser/seo/rules/mobile.d.ts +2 -0
  216. package/dist/browser/seo/rules/mobile.js +161 -0
  217. package/dist/browser/seo/rules/performance.d.ts +2 -0
  218. package/dist/browser/seo/rules/performance.js +738 -0
  219. package/dist/browser/seo/rules/pwa.d.ts +2 -0
  220. package/dist/browser/seo/rules/pwa.js +299 -0
  221. package/dist/browser/seo/rules/readability.d.ts +2 -0
  222. package/dist/browser/seo/rules/readability.js +264 -0
  223. package/dist/browser/seo/rules/redirects.d.ts +16 -0
  224. package/dist/browser/seo/rules/redirects.js +199 -0
  225. package/dist/browser/seo/rules/resources.d.ts +2 -0
  226. package/dist/browser/seo/rules/resources.js +390 -0
  227. package/dist/browser/seo/rules/schema.d.ts +2 -0
  228. package/dist/browser/seo/rules/schema.js +379 -0
  229. package/dist/browser/seo/rules/security.d.ts +2 -0
  230. package/dist/browser/seo/rules/security.js +877 -0
  231. package/dist/browser/seo/rules/social.d.ts +2 -0
  232. package/dist/browser/seo/rules/social.js +603 -0
  233. package/dist/browser/seo/rules/structural.d.ts +2 -0
  234. package/dist/browser/seo/rules/structural.js +223 -0
  235. package/dist/browser/seo/rules/technical-advanced.d.ts +10 -0
  236. package/dist/browser/seo/rules/technical-advanced.js +289 -0
  237. package/dist/browser/seo/rules/technical.d.ts +2 -0
  238. package/dist/browser/seo/rules/technical.js +480 -0
  239. package/dist/browser/seo/rules/thresholds.d.ts +196 -0
  240. package/dist/browser/seo/rules/thresholds.js +118 -0
  241. package/dist/browser/seo/rules/types.d.ts +498 -0
  242. package/dist/browser/seo/rules/types.js +11 -0
  243. package/dist/browser/seo/types.d.ts +211 -0
  244. package/dist/browser/seo/types.js +1 -0
  245. package/dist/browser/transport/curl.d.ts +4 -0
  246. package/dist/browser/transport/curl.js +101 -0
  247. package/dist/browser/transport/undici.js +1 -2
  248. package/dist/browser/transport/worker.d.ts +18 -0
  249. package/dist/browser/transport/worker.js +278 -0
  250. package/dist/browser/types/index.d.ts +4 -1
  251. package/dist/browser/utils/binary-manager.d.ts +4 -0
  252. package/dist/browser/utils/binary-manager.js +72 -0
  253. package/dist/browser/utils/user-agent.js +2 -13
  254. package/dist/cache/indexed-db.d.ts +10 -0
  255. package/dist/cache/indexed-db.js +88 -0
  256. package/dist/cache/service-worker-cache.d.ts +18 -0
  257. package/dist/cache/service-worker-cache.js +103 -0
  258. package/dist/cli/commands/ai.d.ts +2 -0
  259. package/dist/cli/commands/ai.js +162 -0
  260. package/dist/cli/commands/bench.d.ts +2 -0
  261. package/dist/cli/commands/bench.js +51 -0
  262. package/dist/cli/commands/dns.d.ts +2 -0
  263. package/dist/cli/commands/dns.js +295 -0
  264. package/dist/cli/commands/har.d.ts +2 -0
  265. package/dist/cli/commands/har.js +171 -0
  266. package/dist/cli/commands/hls.d.ts +2 -0
  267. package/dist/cli/commands/hls.js +192 -0
  268. package/dist/cli/commands/network.d.ts +2 -0
  269. package/dist/cli/commands/network.js +288 -0
  270. package/dist/cli/commands/protocols.d.ts +2 -0
  271. package/dist/cli/commands/protocols.js +344 -0
  272. package/dist/cli/commands/scrape.d.ts +2 -0
  273. package/dist/cli/commands/scrape.js +176 -0
  274. package/dist/cli/commands/security.d.ts +2 -0
  275. package/dist/cli/commands/security.js +57 -0
  276. package/dist/cli/commands/seo.d.ts +2 -0
  277. package/dist/cli/commands/seo.js +125 -0
  278. package/dist/cli/commands/serve.d.ts +2 -0
  279. package/dist/cli/commands/serve.js +531 -0
  280. package/dist/cli/commands/spider.d.ts +3 -0
  281. package/dist/cli/commands/spider.js +456 -0
  282. package/dist/cli/commands/utils.d.ts +2 -0
  283. package/dist/cli/commands/utils.js +176 -0
  284. package/dist/cli/commands/vector.d.ts +2 -0
  285. package/dist/cli/commands/vector.js +158 -0
  286. package/dist/cli/handler.d.ts +2 -2
  287. package/dist/cli/handler.js +6 -6
  288. package/dist/cli/helpers.d.ts +7 -0
  289. package/dist/cli/helpers.js +128 -0
  290. package/dist/cli/index.js +96 -5228
  291. package/dist/cli/parser/help.d.ts +2 -0
  292. package/dist/cli/parser/help.js +52 -0
  293. package/dist/cli/parser/index.d.ts +3 -0
  294. package/dist/cli/parser/index.js +3 -0
  295. package/dist/cli/parser/parser.d.ts +4 -0
  296. package/dist/cli/parser/parser.js +146 -0
  297. package/dist/cli/parser/types.d.ts +41 -0
  298. package/dist/cli/parser/types.js +1 -0
  299. package/dist/cli/presets.d.ts +1 -1
  300. package/dist/cli/presets.js +1 -1
  301. package/dist/cli/router.d.ts +36 -0
  302. package/dist/cli/router.js +195 -0
  303. package/dist/cli/tui/ai-chat.js +1 -1
  304. package/dist/cli/tui/commands/context.d.ts +9 -0
  305. package/dist/cli/tui/commands/context.js +1 -0
  306. package/dist/cli/tui/commands/dns.d.ts +10 -0
  307. package/dist/cli/tui/commands/dns.js +461 -0
  308. package/dist/cli/tui/commands/hls.d.ts +2 -0
  309. package/dist/cli/tui/commands/hls.js +162 -0
  310. package/dist/cli/tui/commands/ip.d.ts +2 -0
  311. package/dist/cli/tui/commands/ip.js +45 -0
  312. package/dist/cli/tui/commands/network.d.ts +3 -0
  313. package/dist/cli/tui/commands/network.js +81 -0
  314. package/dist/cli/tui/commands/protocols.d.ts +6 -0
  315. package/dist/cli/tui/commands/protocols.js +531 -0
  316. package/dist/cli/tui/commands/security.d.ts +2 -0
  317. package/dist/cli/tui/commands/security.js +48 -0
  318. package/dist/cli/tui/commands/seo.d.ts +2 -0
  319. package/dist/cli/tui/commands/seo.js +74 -0
  320. package/dist/cli/tui/context.d.ts +12 -0
  321. package/dist/cli/tui/context.js +1 -0
  322. package/dist/cli/tui/shell.d.ts +11 -20
  323. package/dist/cli/tui/shell.js +216 -1873
  324. package/dist/constants/user-agents.d.ts +7 -0
  325. package/dist/constants/user-agents.js +7 -0
  326. package/dist/core/client.d.ts +2 -0
  327. package/dist/core/client.js +19 -1
  328. package/dist/index.d.ts +1 -0
  329. package/dist/index.js +1 -0
  330. package/dist/mcp/cli.js +2 -3
  331. package/dist/mcp/data/embeddings.json +1 -1
  332. package/dist/mcp/tools/network.js +298 -158
  333. package/dist/plugins/har-player.d.ts +23 -0
  334. package/dist/plugins/har-player.js +49 -0
  335. package/dist/plugins/har-recorder.d.ts +37 -3
  336. package/dist/plugins/har-recorder.js +116 -63
  337. package/dist/plugins/network-simulation.d.ts +7 -0
  338. package/dist/plugins/network-simulation.js +13 -0
  339. package/dist/presets/android.d.ts +2 -0
  340. package/dist/presets/android.js +16 -0
  341. package/dist/presets/chaturbate.d.ts +2 -0
  342. package/dist/presets/chaturbate.js +17 -0
  343. package/dist/presets/elevenlabs.d.ts +6 -0
  344. package/dist/presets/elevenlabs.js +20 -0
  345. package/dist/presets/enhancers.d.ts +20 -0
  346. package/dist/presets/enhancers.js +85 -0
  347. package/dist/presets/hubspot.d.ts +9 -0
  348. package/dist/presets/hubspot.js +28 -0
  349. package/dist/presets/index.d.ts +10 -0
  350. package/dist/presets/index.js +10 -0
  351. package/dist/presets/ios.d.ts +2 -0
  352. package/dist/presets/ios.js +13 -0
  353. package/dist/presets/pinecone.d.ts +8 -0
  354. package/dist/presets/pinecone.js +42 -0
  355. package/dist/presets/registry.js +60 -0
  356. package/dist/presets/sendgrid.d.ts +6 -0
  357. package/dist/presets/sendgrid.js +20 -0
  358. package/dist/presets/sentry.d.ts +11 -0
  359. package/dist/presets/sentry.js +48 -0
  360. package/dist/presets/square.d.ts +10 -0
  361. package/dist/presets/square.js +33 -0
  362. package/dist/recker.d.ts +3 -0
  363. package/dist/recker.js +4 -0
  364. package/dist/scrape/document.d.ts +5 -4
  365. package/dist/scrape/document.js +89 -76
  366. package/dist/scrape/element.d.ts +10 -8
  367. package/dist/scrape/element.js +295 -81
  368. package/dist/scrape/extractors.d.ts +11 -11
  369. package/dist/scrape/extractors.js +145 -113
  370. package/dist/scrape/index.d.ts +2 -0
  371. package/dist/scrape/index.js +1 -0
  372. package/dist/scrape/parser/back.d.ts +1 -0
  373. package/dist/scrape/parser/back.js +3 -0
  374. package/dist/scrape/parser/index.d.ts +20 -0
  375. package/dist/scrape/parser/index.js +19 -0
  376. package/dist/scrape/parser/matcher.d.ts +30 -0
  377. package/dist/scrape/parser/matcher.js +99 -0
  378. package/dist/scrape/parser/nodes/comment.d.ts +12 -0
  379. package/dist/scrape/parser/nodes/comment.js +21 -0
  380. package/dist/scrape/parser/nodes/html.d.ts +110 -0
  381. package/dist/scrape/parser/nodes/html.js +978 -0
  382. package/dist/scrape/parser/nodes/node.d.ts +18 -0
  383. package/dist/scrape/parser/nodes/node.js +31 -0
  384. package/dist/scrape/parser/nodes/text.d.ts +14 -0
  385. package/dist/scrape/parser/nodes/text.js +30 -0
  386. package/dist/scrape/parser/nodes/type.d.ts +6 -0
  387. package/dist/scrape/parser/nodes/type.js +7 -0
  388. package/dist/scrape/parser/parse.d.ts +1 -0
  389. package/dist/scrape/parser/parse.js +1 -0
  390. package/dist/scrape/parser/valid.d.ts +2 -0
  391. package/dist/scrape/parser/valid.js +5 -0
  392. package/dist/scrape/parser/void-tag.d.ts +7 -0
  393. package/dist/scrape/parser/void-tag.js +43 -0
  394. package/dist/scrape/spider.d.ts +19 -0
  395. package/dist/scrape/spider.js +28 -3
  396. package/dist/scrape/types.d.ts +7 -0
  397. package/dist/seo/analyzer.d.ts +15 -5
  398. package/dist/seo/analyzer.js +636 -175
  399. package/dist/seo/formatter.d.ts +16 -0
  400. package/dist/seo/formatter.js +228 -0
  401. package/dist/seo/index.d.ts +2 -0
  402. package/dist/seo/index.js +1 -0
  403. package/dist/seo/keywords.d.ts +16 -0
  404. package/dist/seo/keywords.js +55 -0
  405. package/dist/seo/rules/accessibility.js +96 -57
  406. package/dist/seo/rules/ai-search.js +44 -31
  407. package/dist/seo/rules/analytics.d.ts +2 -0
  408. package/dist/seo/rules/analytics.js +306 -0
  409. package/dist/seo/rules/best-practices.js +21 -14
  410. package/dist/seo/rules/canonical.js +53 -32
  411. package/dist/seo/rules/content.js +317 -31
  412. package/dist/seo/rules/crawl.js +55 -40
  413. package/dist/seo/rules/cwv.js +21 -15
  414. package/dist/seo/rules/ecommerce.js +82 -22
  415. package/dist/seo/rules/i18n.js +75 -36
  416. package/dist/seo/rules/images.js +109 -30
  417. package/dist/seo/rules/index.js +2 -0
  418. package/dist/seo/rules/internal-linking.js +58 -39
  419. package/dist/seo/rules/links.js +79 -52
  420. package/dist/seo/rules/local.js +49 -25
  421. package/dist/seo/rules/meta.js +339 -81
  422. package/dist/seo/rules/mobile.js +112 -2
  423. package/dist/seo/rules/performance.js +434 -66
  424. package/dist/seo/rules/pwa.js +36 -39
  425. package/dist/seo/rules/readability.js +31 -22
  426. package/dist/seo/rules/redirects.js +21 -15
  427. package/dist/seo/rules/resources.js +59 -42
  428. package/dist/seo/rules/schema.js +333 -8
  429. package/dist/seo/rules/security.js +142 -80
  430. package/dist/seo/rules/social.js +277 -47
  431. package/dist/seo/rules/structural.js +87 -19
  432. package/dist/seo/rules/technical-advanced.js +30 -24
  433. package/dist/seo/rules/technical.js +243 -42
  434. package/dist/seo/rules/types.d.ts +53 -1
  435. package/dist/seo/seo-spider.d.ts +22 -0
  436. package/dist/seo/seo-spider.js +77 -13
  437. package/dist/seo/types.d.ts +8 -1
  438. package/dist/seo/validators/llms-txt.js +19 -0
  439. package/dist/seo/validators/rss.d.ts +11 -0
  440. package/dist/seo/validators/rss.js +93 -0
  441. package/dist/seo/validators/sitemap.js +36 -26
  442. package/dist/transport/curl.d.ts +4 -0
  443. package/dist/transport/curl.js +101 -0
  444. package/dist/transport/udp.js +0 -1
  445. package/dist/transport/undici.js +1 -2
  446. package/dist/transport/worker.d.ts +18 -0
  447. package/dist/transport/worker.js +278 -0
  448. package/dist/types/index.d.ts +4 -1
  449. package/dist/utils/binary-manager.d.ts +4 -0
  450. package/dist/utils/binary-manager.js +72 -0
  451. package/dist/utils/optional-require.d.ts +7 -8
  452. package/dist/utils/optional-require.js +2 -21
  453. package/dist/utils/upload.d.ts +6 -0
  454. package/dist/utils/upload.js +11 -0
  455. package/dist/utils/user-agent.js +2 -13
  456. package/dist/version.js +1 -1
  457. package/package.json +12 -6
  458. package/dist/browser/utils/optional-require.d.ts +0 -19
  459. package/dist/browser/utils/optional-require.js +0 -105
@@ -0,0 +1,82 @@
1
+ import { cosineSimilarity } from './similarity.js';
2
+ export class MemoryVectorStore {
3
+ documents = new Map();
4
+ client;
5
+ model;
6
+ constructor(options = {}) {
7
+ this.client = options.client;
8
+ this.model = options.model;
9
+ }
10
+ async add(docs) {
11
+ const docsToEmbed = [];
12
+ const readyDocs = [];
13
+ for (const doc of docs) {
14
+ const id = doc.id || Math.random().toString(36).substring(7);
15
+ const fullDoc = {
16
+ id,
17
+ content: doc.content,
18
+ metadata: doc.metadata || {},
19
+ embedding: doc.embedding,
20
+ };
21
+ if (!fullDoc.embedding) {
22
+ docsToEmbed.push(fullDoc);
23
+ }
24
+ else {
25
+ readyDocs.push(fullDoc);
26
+ }
27
+ }
28
+ if (docsToEmbed.length > 0) {
29
+ if (!this.client) {
30
+ throw new Error('AI Client required to generate embeddings. Pass "client" to constructor or provide "embedding" in document.');
31
+ }
32
+ const contents = docsToEmbed.map(d => d.content);
33
+ const response = await this.client.embed({
34
+ model: this.model,
35
+ input: contents,
36
+ });
37
+ docsToEmbed.forEach((doc, i) => {
38
+ doc.embedding = response.embeddings[i];
39
+ readyDocs.push(doc);
40
+ });
41
+ }
42
+ for (const doc of readyDocs) {
43
+ this.documents.set(doc.id, doc);
44
+ }
45
+ }
46
+ async search(query, limit = 3, threshold = 0.0) {
47
+ if (this.documents.size === 0)
48
+ return [];
49
+ if (!this.client) {
50
+ throw new Error('AI Client required to search by text query.');
51
+ }
52
+ const response = await this.client.embed({
53
+ model: this.model,
54
+ input: query,
55
+ });
56
+ const queryEmbedding = response.embeddings[0];
57
+ const results = [];
58
+ for (const doc of this.documents.values()) {
59
+ if (!doc.embedding)
60
+ continue;
61
+ const score = cosineSimilarity(queryEmbedding, doc.embedding);
62
+ if (score >= threshold) {
63
+ results.push({
64
+ ...doc,
65
+ score,
66
+ });
67
+ }
68
+ }
69
+ return results
70
+ .sort((a, b) => b.score - a.score)
71
+ .slice(0, limit);
72
+ }
73
+ delete(id) {
74
+ return this.documents.delete(id);
75
+ }
76
+ clear() {
77
+ this.documents.clear();
78
+ }
79
+ get count() {
80
+ return this.documents.size;
81
+ }
82
+ }
@@ -1,40 +1,2 @@
1
- export interface CacheEntry<T = unknown> {
2
- key: string;
3
- value: T;
4
- createdAt: number;
5
- expiresAt?: number;
6
- etag?: string;
7
- lastModified?: string;
8
- }
9
- export interface BrowserCacheOptions {
10
- dbName?: string;
11
- storeName?: string;
12
- defaultTTL?: number;
13
- maxEntries?: number;
14
- }
15
- export declare class IndexedDBStorage {
16
- private dbName;
17
- private storeName;
18
- private defaultTTL;
19
- private maxEntries;
20
- private db;
21
- private initPromise;
22
- constructor(options?: BrowserCacheOptions);
23
- init(): Promise<void>;
24
- get<T = unknown>(key: string): Promise<CacheEntry<T> | null>;
25
- set<T = unknown>(key: string, value: T, ttl?: number, metadata?: {
26
- etag?: string;
27
- lastModified?: string;
28
- }): Promise<void>;
29
- delete(key: string): Promise<boolean>;
30
- has(key: string): Promise<boolean>;
31
- clear(): Promise<void>;
32
- keys(): Promise<string[]>;
33
- size(): Promise<number>;
34
- cleanup(): Promise<number>;
35
- private enforceMaxEntries;
36
- close(): void;
37
- destroy(): Promise<void>;
38
- }
39
- export declare function isIndexedDBAvailable(): boolean;
40
- export declare function getBrowserCacheStorage(options?: BrowserCacheOptions): IndexedDBStorage | null;
1
+ export { IndexedDBStorage } from '../cache/indexed-db.js';
2
+ export { ServiceWorkerCache } from '../cache/service-worker-cache.js';
@@ -1,199 +1,2 @@
1
- export class IndexedDBStorage {
2
- dbName;
3
- storeName;
4
- defaultTTL;
5
- maxEntries;
6
- db = null;
7
- initPromise = null;
8
- constructor(options = {}) {
9
- this.dbName = options.dbName ?? 'recker-cache';
10
- this.storeName = options.storeName ?? 'responses';
11
- this.defaultTTL = options.defaultTTL ?? 5 * 60 * 1000;
12
- this.maxEntries = options.maxEntries ?? 1000;
13
- }
14
- async init() {
15
- if (this.db)
16
- return;
17
- if (this.initPromise)
18
- return this.initPromise;
19
- this.initPromise = new Promise((resolve, reject) => {
20
- const request = indexedDB.open(this.dbName, 1);
21
- request.onerror = () => {
22
- reject(new Error(`Failed to open IndexedDB: ${request.error?.message}`));
23
- };
24
- request.onsuccess = () => {
25
- this.db = request.result;
26
- resolve();
27
- };
28
- request.onupgradeneeded = (event) => {
29
- const db = event.target.result;
30
- if (!db.objectStoreNames.contains(this.storeName)) {
31
- const store = db.createObjectStore(this.storeName, { keyPath: 'key' });
32
- store.createIndex('expiresAt', 'expiresAt', { unique: false });
33
- }
34
- };
35
- });
36
- return this.initPromise;
37
- }
38
- async get(key) {
39
- await this.init();
40
- return new Promise((resolve, reject) => {
41
- const transaction = this.db.transaction(this.storeName, 'readonly');
42
- const store = transaction.objectStore(this.storeName);
43
- const request = store.get(key);
44
- request.onerror = () => reject(request.error);
45
- request.onsuccess = () => {
46
- const entry = request.result;
47
- if (!entry) {
48
- resolve(null);
49
- return;
50
- }
51
- if (entry.expiresAt && entry.expiresAt < Date.now()) {
52
- this.delete(key).catch(() => { });
53
- resolve(null);
54
- return;
55
- }
56
- resolve(entry);
57
- };
58
- });
59
- }
60
- async set(key, value, ttl, metadata) {
61
- await this.init();
62
- const entry = {
63
- key,
64
- value,
65
- createdAt: Date.now(),
66
- expiresAt: ttl !== undefined ? Date.now() + ttl : undefined,
67
- etag: metadata?.etag,
68
- lastModified: metadata?.lastModified,
69
- };
70
- return new Promise((resolve, reject) => {
71
- const transaction = this.db.transaction(this.storeName, 'readwrite');
72
- const store = transaction.objectStore(this.storeName);
73
- const request = store.put(entry);
74
- request.onerror = () => reject(request.error);
75
- request.onsuccess = () => resolve();
76
- transaction.oncomplete = () => {
77
- this.enforceMaxEntries().catch(() => { });
78
- };
79
- });
80
- }
81
- async delete(key) {
82
- await this.init();
83
- return new Promise((resolve, reject) => {
84
- const transaction = this.db.transaction(this.storeName, 'readwrite');
85
- const store = transaction.objectStore(this.storeName);
86
- const request = store.delete(key);
87
- request.onerror = () => reject(request.error);
88
- request.onsuccess = () => resolve(true);
89
- });
90
- }
91
- async has(key) {
92
- const entry = await this.get(key);
93
- return entry !== null;
94
- }
95
- async clear() {
96
- await this.init();
97
- return new Promise((resolve, reject) => {
98
- const transaction = this.db.transaction(this.storeName, 'readwrite');
99
- const store = transaction.objectStore(this.storeName);
100
- const request = store.clear();
101
- request.onerror = () => reject(request.error);
102
- request.onsuccess = () => resolve();
103
- });
104
- }
105
- async keys() {
106
- await this.init();
107
- return new Promise((resolve, reject) => {
108
- const transaction = this.db.transaction(this.storeName, 'readonly');
109
- const store = transaction.objectStore(this.storeName);
110
- const request = store.getAllKeys();
111
- request.onerror = () => reject(request.error);
112
- request.onsuccess = () => resolve(request.result);
113
- });
114
- }
115
- async size() {
116
- await this.init();
117
- return new Promise((resolve, reject) => {
118
- const transaction = this.db.transaction(this.storeName, 'readonly');
119
- const store = transaction.objectStore(this.storeName);
120
- const request = store.count();
121
- request.onerror = () => reject(request.error);
122
- request.onsuccess = () => resolve(request.result);
123
- });
124
- }
125
- async cleanup() {
126
- await this.init();
127
- const now = Date.now();
128
- let removed = 0;
129
- return new Promise((resolve, reject) => {
130
- const transaction = this.db.transaction(this.storeName, 'readwrite');
131
- const store = transaction.objectStore(this.storeName);
132
- const index = store.index('expiresAt');
133
- const range = IDBKeyRange.upperBound(now);
134
- const request = index.openCursor(range);
135
- request.onerror = () => reject(request.error);
136
- request.onsuccess = (event) => {
137
- const cursor = event.target.result;
138
- if (cursor) {
139
- cursor.delete();
140
- removed++;
141
- cursor.continue();
142
- }
143
- };
144
- transaction.oncomplete = () => resolve(removed);
145
- });
146
- }
147
- async enforceMaxEntries() {
148
- const currentSize = await this.size();
149
- if (currentSize <= this.maxEntries)
150
- return;
151
- const toRemove = currentSize - this.maxEntries;
152
- return new Promise((resolve, reject) => {
153
- const transaction = this.db.transaction(this.storeName, 'readwrite');
154
- const store = transaction.objectStore(this.storeName);
155
- const index = store.index('expiresAt');
156
- let removed = 0;
157
- const request = index.openCursor();
158
- request.onerror = () => reject(request.error);
159
- request.onsuccess = (event) => {
160
- const cursor = event.target.result;
161
- if (cursor && removed < toRemove) {
162
- cursor.delete();
163
- removed++;
164
- cursor.continue();
165
- }
166
- };
167
- transaction.oncomplete = () => resolve();
168
- });
169
- }
170
- close() {
171
- if (this.db) {
172
- this.db.close();
173
- this.db = null;
174
- this.initPromise = null;
175
- }
176
- }
177
- async destroy() {
178
- this.close();
179
- return new Promise((resolve, reject) => {
180
- const request = indexedDB.deleteDatabase(this.dbName);
181
- request.onerror = () => reject(request.error);
182
- request.onsuccess = () => resolve();
183
- });
184
- }
185
- }
186
- export function isIndexedDBAvailable() {
187
- try {
188
- return typeof indexedDB !== 'undefined' && indexedDB !== null;
189
- }
190
- catch {
191
- return false;
192
- }
193
- }
194
- export function getBrowserCacheStorage(options) {
195
- if (isIndexedDBAvailable()) {
196
- return new IndexedDBStorage(options);
197
- }
198
- return null;
199
- }
1
+ export { IndexedDBStorage } from '../cache/indexed-db.js';
2
+ export { ServiceWorkerCache } from '../cache/service-worker-cache.js';
@@ -4,6 +4,7 @@ export * from '../core/client.js';
4
4
  export * from '../core/request.js';
5
5
  export * from '../core/response.js';
6
6
  export * from '../transport/fetch.js';
7
+ export * from '../transport/worker.js';
7
8
  export * from '../plugins/retry.js';
8
9
  export * from '../plugins/rate-limit.js';
9
10
  export * from '../plugins/dedup.js';
@@ -18,12 +19,19 @@ export * from '../plugins/jsonrpc.js';
18
19
  export * from '../plugins/grpc-web.js';
19
20
  export * from '../plugins/soap.js';
20
21
  export * from '../plugins/odata.js';
22
+ export * from '../plugins/har-recorder.js';
23
+ export * from '../plugins/network-simulation.js';
21
24
  export * from '../plugins/auth.js';
22
25
  export * from '../cache/memory-storage.js';
26
+ export * from '../cache/indexed-db.js';
23
27
  export * from '../utils/body.js';
24
28
  export * from '../utils/header-parser.js';
25
29
  export * from '../utils/link-header.js';
30
+ export * from '../utils/user-agent.js';
26
31
  export * from '../utils/charset.js';
32
+ export * from '../seo/analyzer.js';
33
+ export * as ai from '../ai/index.js';
34
+ export * as presets from '../presets/index.js';
27
35
  export * from '../constants/http-status.js';
28
36
  export * from './crypto.js';
29
37
  export * from './cache.js';
@@ -4,6 +4,7 @@ export * from '../core/client.js';
4
4
  export * from '../core/request.js';
5
5
  export * from '../core/response.js';
6
6
  export * from '../transport/fetch.js';
7
+ export * from '../transport/worker.js';
7
8
  export * from '../plugins/retry.js';
8
9
  export * from '../plugins/rate-limit.js';
9
10
  export * from '../plugins/dedup.js';
@@ -18,12 +19,19 @@ export * from '../plugins/jsonrpc.js';
18
19
  export * from '../plugins/grpc-web.js';
19
20
  export * from '../plugins/soap.js';
20
21
  export * from '../plugins/odata.js';
22
+ export * from '../plugins/har-recorder.js';
23
+ export * from '../plugins/network-simulation.js';
21
24
  export * from '../plugins/auth.js';
22
25
  export * from '../cache/memory-storage.js';
26
+ export * from '../cache/indexed-db.js';
23
27
  export * from '../utils/body.js';
24
28
  export * from '../utils/header-parser.js';
25
29
  export * from '../utils/link-header.js';
30
+ export * from '../utils/user-agent.js';
26
31
  export * from '../utils/charset.js';
32
+ export * from '../seo/analyzer.js';
33
+ export * as ai from '../ai/index.js';
34
+ export * as presets from '../presets/index.js';
27
35
  export * from '../constants/http-status.js';
28
36
  export * from './crypto.js';
29
37
  export * from './cache.js';
@@ -1,6 +1,9 @@
1
1
  import { Client, type ExtendedClientOptions } from '../core/client.js';
2
2
  import { type RequestPromise } from '../core/request-promise.js';
3
3
  import type { RequestOptions } from '../types/index.js';
4
+ import { analyzeSeo } from '../seo/analyzer.js';
5
+ import { createAI } from '../ai/index.js';
6
+ import { simulateNetwork } from '../plugins/network-simulation.js';
4
7
  export declare function get(url: string, options?: RequestOptions): RequestPromise;
5
8
  export declare function post(url: string, options?: RequestOptions): RequestPromise;
6
9
  export declare function put(url: string, options?: RequestOptions): RequestPromise;
@@ -18,9 +21,13 @@ export declare const recker: {
18
21
  head: typeof head;
19
22
  options: typeof options;
20
23
  ws: typeof ws;
24
+ seo: typeof analyzeSeo;
25
+ ai: typeof createAI;
26
+ har: import("../plugins/har-recorder.js").HarRecorder;
27
+ simulateNetwork: typeof simulateNetwork;
21
28
  client: (opts?: ExtendedClientOptions) => Client;
22
29
  reset: () => void;
23
30
  isBrowser: true;
24
- unavailable: readonly ["whois", "whoisAvailable", "dns", "dnsSecurity", "dnsClient", "whoisClient", "ai", "aiClient"];
31
+ unavailable: readonly ["whois", "whoisAvailable", "dns", "dnsSecurity", "dnsClient", "whoisClient"];
25
32
  };
26
33
  export default recker;
@@ -1,5 +1,9 @@
1
1
  import { createClient } from '../core/client.js';
2
2
  import { FetchTransport } from '../transport/fetch.js';
3
+ import { analyzeSeo } from '../seo/analyzer.js';
4
+ import { createAI } from '../ai/index.js';
5
+ import { harRecorder } from '../plugins/har-recorder.js';
6
+ import { simulateNetwork } from '../plugins/network-simulation.js';
3
7
  let _defaultClient = null;
4
8
  function getDefaultClient() {
5
9
  if (!_defaultClient) {
@@ -42,6 +46,10 @@ export const recker = {
42
46
  head,
43
47
  options,
44
48
  ws,
49
+ seo: analyzeSeo,
50
+ ai: createAI,
51
+ har: harRecorder,
52
+ simulateNetwork,
45
53
  client: (opts) => createClient({ ...opts, transport: new FetchTransport() }),
46
54
  reset: () => {
47
55
  _defaultClient = null;
@@ -54,8 +62,6 @@ export const recker = {
54
62
  'dnsSecurity',
55
63
  'dnsClient',
56
64
  'whoisClient',
57
- 'ai',
58
- 'aiClient',
59
65
  ],
60
66
  };
61
67
  export default recker;
@@ -0,0 +1,10 @@
1
+ import type { CacheStorage, CacheEntry } from '../types/index.js';
2
+ export declare class IndexedDBStorage implements CacheStorage {
3
+ private dbPromise;
4
+ constructor(dbName?: string);
5
+ private openDB;
6
+ get(key: string): Promise<CacheEntry | undefined | null>;
7
+ set(key: string, value: CacheEntry, ttl: number): Promise<void>;
8
+ delete(key: string): Promise<void>;
9
+ clear(): Promise<void>;
10
+ }
@@ -0,0 +1,88 @@
1
+ const DB_NAME = 'recker-cache';
2
+ const STORE_NAME = 'entries';
3
+ const DB_VERSION = 1;
4
+ export class IndexedDBStorage {
5
+ dbPromise;
6
+ constructor(dbName = DB_NAME) {
7
+ this.dbPromise = this.openDB(dbName);
8
+ }
9
+ openDB(dbName) {
10
+ return new Promise((resolve, reject) => {
11
+ if (typeof indexedDB === 'undefined') {
12
+ reject(new Error('IndexedDB is not supported in this environment'));
13
+ return;
14
+ }
15
+ const request = indexedDB.open(dbName, DB_VERSION);
16
+ request.onupgradeneeded = (event) => {
17
+ const db = event.target.result;
18
+ if (!db.objectStoreNames.contains(STORE_NAME)) {
19
+ db.createObjectStore(STORE_NAME, { keyPath: 'key' });
20
+ }
21
+ };
22
+ request.onsuccess = (event) => {
23
+ resolve(event.target.result);
24
+ };
25
+ request.onerror = (event) => {
26
+ reject(event.target.error);
27
+ };
28
+ });
29
+ }
30
+ async get(key) {
31
+ const db = await this.dbPromise;
32
+ return new Promise((resolve, reject) => {
33
+ const transaction = db.transaction(STORE_NAME, 'readonly');
34
+ const store = transaction.objectStore(STORE_NAME);
35
+ const request = store.get(key);
36
+ request.onsuccess = () => {
37
+ const result = request.result;
38
+ if (!result) {
39
+ resolve(null);
40
+ return;
41
+ }
42
+ if (result.expiresAt && Date.now() > result.expiresAt) {
43
+ this.delete(key).catch(() => { });
44
+ resolve(null);
45
+ return;
46
+ }
47
+ resolve(result.value);
48
+ };
49
+ request.onerror = () => reject(request.error);
50
+ });
51
+ }
52
+ async set(key, value, ttl) {
53
+ const db = await this.dbPromise;
54
+ return new Promise((resolve, reject) => {
55
+ const transaction = db.transaction(STORE_NAME, 'readwrite');
56
+ const store = transaction.objectStore(STORE_NAME);
57
+ const expiresAt = Date.now() + ttl;
58
+ const item = {
59
+ key,
60
+ value,
61
+ expiresAt
62
+ };
63
+ const request = store.put(item);
64
+ request.onsuccess = () => resolve();
65
+ request.onerror = () => reject(request.error);
66
+ });
67
+ }
68
+ async delete(key) {
69
+ const db = await this.dbPromise;
70
+ return new Promise((resolve, reject) => {
71
+ const transaction = db.transaction(STORE_NAME, 'readwrite');
72
+ const store = transaction.objectStore(STORE_NAME);
73
+ const request = store.delete(key);
74
+ request.onsuccess = () => resolve();
75
+ request.onerror = () => reject(request.error);
76
+ });
77
+ }
78
+ async clear() {
79
+ const db = await this.dbPromise;
80
+ return new Promise((resolve, reject) => {
81
+ const transaction = db.transaction(STORE_NAME, 'readwrite');
82
+ const store = transaction.objectStore(STORE_NAME);
83
+ const request = store.clear();
84
+ request.onsuccess = () => resolve();
85
+ request.onerror = () => reject(request.error);
86
+ });
87
+ }
88
+ }
@@ -0,0 +1,18 @@
1
+ import type { CacheStorage, CacheEntry } from '../types/index.js';
2
+ export declare class ServiceWorkerCache implements CacheStorage {
3
+ private cacheName;
4
+ private cachePromise;
5
+ constructor(options?: {
6
+ cacheName?: string;
7
+ });
8
+ static isSupported(): boolean;
9
+ private getCache;
10
+ private keyToUrl;
11
+ get(key: string): Promise<CacheEntry | undefined | null>;
12
+ set(key: string, value: CacheEntry, ttl: number): Promise<void>;
13
+ delete(key: string): Promise<void>;
14
+ clear(): Promise<void>;
15
+ keys(): Promise<string[]>;
16
+ size(): Promise<number>;
17
+ prune(): Promise<number>;
18
+ }
@@ -0,0 +1,103 @@
1
+ const CACHE_NAME = 'recker-cache-v1';
2
+ export class ServiceWorkerCache {
3
+ cacheName;
4
+ cachePromise = null;
5
+ constructor(options = {}) {
6
+ this.cacheName = options.cacheName || CACHE_NAME;
7
+ }
8
+ static isSupported() {
9
+ return typeof caches !== 'undefined';
10
+ }
11
+ async getCache() {
12
+ if (!this.cachePromise) {
13
+ if (!ServiceWorkerCache.isSupported()) {
14
+ throw new Error('Cache API is not supported in this environment');
15
+ }
16
+ this.cachePromise = caches.open(this.cacheName);
17
+ }
18
+ return this.cachePromise;
19
+ }
20
+ keyToUrl(key) {
21
+ return `https://recker-cache.local/${encodeURIComponent(key)}`;
22
+ }
23
+ async get(key) {
24
+ try {
25
+ const cache = await this.getCache();
26
+ const url = this.keyToUrl(key);
27
+ const response = await cache.match(url);
28
+ if (!response) {
29
+ return null;
30
+ }
31
+ const data = await response.json();
32
+ if (data.expiresAt && Date.now() > data.expiresAt) {
33
+ this.delete(key).catch(() => { });
34
+ return null;
35
+ }
36
+ return data.entry;
37
+ }
38
+ catch {
39
+ return null;
40
+ }
41
+ }
42
+ async set(key, value, ttl) {
43
+ const cache = await this.getCache();
44
+ const url = this.keyToUrl(key);
45
+ const item = {
46
+ entry: value,
47
+ expiresAt: Date.now() + ttl,
48
+ };
49
+ const response = new Response(JSON.stringify(item), {
50
+ headers: {
51
+ 'Content-Type': 'application/json',
52
+ 'X-Recker-Cache': 'true',
53
+ 'X-Recker-Expires': String(item.expiresAt),
54
+ },
55
+ });
56
+ await cache.put(url, response);
57
+ }
58
+ async delete(key) {
59
+ const cache = await this.getCache();
60
+ const url = this.keyToUrl(key);
61
+ await cache.delete(url);
62
+ }
63
+ async clear() {
64
+ await caches.delete(this.cacheName);
65
+ this.cachePromise = null;
66
+ }
67
+ async keys() {
68
+ const cache = await this.getCache();
69
+ const requests = await cache.keys();
70
+ return requests
71
+ .map((req) => {
72
+ const url = new URL(req.url);
73
+ return decodeURIComponent(url.pathname.slice(1));
74
+ })
75
+ .filter((key) => key.length > 0);
76
+ }
77
+ async size() {
78
+ const keys = await this.keys();
79
+ return keys.length;
80
+ }
81
+ async prune() {
82
+ const cache = await this.getCache();
83
+ const requests = await cache.keys();
84
+ let removed = 0;
85
+ for (const request of requests) {
86
+ const response = await cache.match(request);
87
+ if (response) {
88
+ try {
89
+ const data = await response.json();
90
+ if (data.expiresAt && Date.now() > data.expiresAt) {
91
+ await cache.delete(request);
92
+ removed++;
93
+ }
94
+ }
95
+ catch {
96
+ await cache.delete(request);
97
+ removed++;
98
+ }
99
+ }
100
+ }
101
+ return removed;
102
+ }
103
+ }