@storyshelf/core 0.6.2 → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (727) hide show
  1. package/README.md +49 -32
  2. package/dist/adapter/capture-queue.d.mts +44 -4
  3. package/dist/adapter/capture-runner.d.mts +134 -12
  4. package/dist/adapter/capture-runner.mjs +9 -12
  5. package/dist/adapter/database.d.mts +89 -10
  6. package/dist/adapter/database.mjs +4 -3
  7. package/dist/adapter/database.mjs.map +1 -1
  8. package/dist/adapter/design.d.mts +83 -0
  9. package/dist/adapter/design.mjs +27 -0
  10. package/dist/adapter/design.mjs.map +1 -0
  11. package/dist/adapter/email-sender.d.mts +0 -2
  12. package/dist/adapter/metadata.d.mts +3 -12
  13. package/dist/adapter/notifier.d.mts +6 -3
  14. package/dist/adapter/notifier.mjs +5 -1
  15. package/dist/adapter/oauth.d.mts +50 -0
  16. package/dist/adapter/setup.d.mts +4 -7
  17. package/dist/adapter/setup.mjs +3 -3
  18. package/dist/adapter/setup.mjs.map +1 -1
  19. package/dist/adapter/storage.d.mts +1 -3
  20. package/dist/adapter/webhook-events.d.mts +0 -2
  21. package/dist/adapter/webhook-events.mjs +13 -14
  22. package/dist/adapter/webhook-events.mjs.map +1 -1
  23. package/dist/adapters/capture-target-offers.d.mts +26 -0
  24. package/dist/adapters/capture-target-offers.mjs +57 -0
  25. package/dist/adapters/capture-target-offers.mjs.map +1 -0
  26. package/dist/adapters/capture-target.d.mts +69 -0
  27. package/dist/adapters/capture-target.mjs +75 -0
  28. package/dist/adapters/capture-target.mjs.map +1 -0
  29. package/dist/adapters/notifier/build-comment.d.mts +22 -0
  30. package/dist/adapters/notifier/build-comment.mjs +23 -0
  31. package/dist/adapters/notifier/build-comment.mjs.map +1 -0
  32. package/dist/adapters/notifier/build-state.d.mts +97 -0
  33. package/dist/adapters/notifier/build-state.mjs +217 -0
  34. package/dist/adapters/notifier/build-state.mjs.map +1 -0
  35. package/dist/adapters/notifier/events.d.mts +4 -4
  36. package/dist/adapters/notifier/events.mjs +32 -20
  37. package/dist/adapters/notifier/events.mjs.map +1 -1
  38. package/dist/adapters/notifier/format.d.mts +0 -2
  39. package/dist/adapters/notifier/format.mjs +1 -2
  40. package/dist/adapters/notifier/provider.d.mts +53 -9
  41. package/dist/adapters/notifier/provider.mjs +11 -0
  42. package/dist/adapters/notifier/provider.mjs.map +1 -0
  43. package/dist/adapters/notifier/state.d.mts +22 -0
  44. package/dist/adapters/notifier/state.mjs +65 -0
  45. package/dist/adapters/notifier/state.mjs.map +1 -0
  46. package/dist/adapters/notifier/types.d.mts +51 -4
  47. package/dist/adapters/remote-browser.d.mts +168 -0
  48. package/dist/adapters/remote-browser.mjs +201 -0
  49. package/dist/adapters/remote-browser.mjs.map +1 -0
  50. package/dist/adapters/remote-lease-attempt.mjs +39 -0
  51. package/dist/adapters/remote-lease-attempt.mjs.map +1 -0
  52. package/dist/adapters/remote-lease-error.d.mts +25 -0
  53. package/dist/adapters/remote-lease-error.mjs +54 -0
  54. package/dist/adapters/remote-lease-error.mjs.map +1 -0
  55. package/dist/adapters/remote-lease-held.d.mts +15 -0
  56. package/dist/adapters/remote-lease-held.mjs +86 -0
  57. package/dist/adapters/remote-lease-held.mjs.map +1 -0
  58. package/dist/adapters/remote-lease-shutdown.d.mts +12 -0
  59. package/dist/adapters/remote-lease-shutdown.mjs +32 -0
  60. package/dist/adapters/remote-lease-shutdown.mjs.map +1 -0
  61. package/dist/adapters/remote-lease.d.mts +39 -0
  62. package/dist/adapters/remote-lease.mjs +175 -0
  63. package/dist/adapters/remote-lease.mjs.map +1 -0
  64. package/dist/adapters/remote-limiter.mjs +121 -0
  65. package/dist/adapters/remote-limiter.mjs.map +1 -0
  66. package/dist/adapters/remote-pool.d.mts +56 -0
  67. package/dist/adapters/remote-pool.mjs +195 -0
  68. package/dist/adapters/remote-pool.mjs.map +1 -0
  69. package/dist/adapters/render-runs.d.mts +23 -0
  70. package/dist/adapters/render-runs.mjs +40 -0
  71. package/dist/adapters/render-runs.mjs.map +1 -0
  72. package/dist/adapters/setup-runner.d.mts +0 -2
  73. package/dist/adapters/setup-runner.mjs +3 -6
  74. package/dist/adapters/setup-runner.mjs.map +1 -1
  75. package/dist/adapters/sources.d.mts +10 -0
  76. package/dist/adapters/sources.mjs +19 -0
  77. package/dist/adapters/sources.mjs.map +1 -0
  78. package/dist/adapters/validate.d.mts +0 -2
  79. package/dist/adapters/validate.mjs +27 -20
  80. package/dist/adapters/validate.mjs.map +1 -1
  81. package/dist/ai.d.mts +103 -0
  82. package/dist/ai.mjs +18 -0
  83. package/dist/ai.mjs.map +1 -0
  84. package/dist/auth.d.mts +0 -2
  85. package/dist/auth.mjs +1 -2
  86. package/dist/brand-packs.d.mts +0 -2
  87. package/dist/brand-packs.mjs +0 -1
  88. package/dist/capture/a11y/axe-source.d.mts +16 -0
  89. package/dist/capture/a11y/axe-source.mjs +36 -0
  90. package/dist/capture/a11y/axe-source.mjs.map +1 -0
  91. package/dist/capture/a11y/in-page.d.mts +25 -0
  92. package/dist/capture/a11y/in-page.mjs +59 -0
  93. package/dist/capture/a11y/in-page.mjs.map +1 -0
  94. package/dist/capture/a11y/map.d.mts +22 -0
  95. package/dist/capture/a11y/map.mjs +47 -0
  96. package/dist/capture/a11y/map.mjs.map +1 -0
  97. package/dist/capture/a11y/options.d.mts +21 -0
  98. package/dist/capture/a11y/options.mjs +74 -0
  99. package/dist/capture/a11y/options.mjs.map +1 -0
  100. package/dist/capture/adapter.d.mts +46 -5
  101. package/dist/capture/adapter.mjs +1 -2
  102. package/dist/capture/adapter.mjs.map +1 -1
  103. package/dist/capture/affected.d.mts +2 -2
  104. package/dist/capture/affected.mjs +14 -6
  105. package/dist/capture/affected.mjs.map +1 -1
  106. package/dist/capture/attempt-logger.mjs +83 -0
  107. package/dist/capture/attempt-logger.mjs.map +1 -0
  108. package/dist/capture/browsers.d.mts +33 -0
  109. package/dist/capture/browsers.mjs +66 -0
  110. package/dist/capture/browsers.mjs.map +1 -0
  111. package/dist/capture/build-state/deliver.d.mts +30 -0
  112. package/dist/capture/build-state/deliver.mjs +117 -0
  113. package/dist/capture/build-state/deliver.mjs.map +1 -0
  114. package/dist/capture/build-state/index.d.mts +8 -0
  115. package/dist/capture/build-state/notify-job.d.mts +54 -0
  116. package/dist/capture/build-state/notify-job.mjs +132 -0
  117. package/dist/capture/build-state/notify-job.mjs.map +1 -0
  118. package/dist/capture/build-state/publisher.d.mts +21 -0
  119. package/dist/capture/build-state/publisher.mjs +106 -0
  120. package/dist/capture/build-state/publisher.mjs.map +1 -0
  121. package/dist/capture/build-state/resume.d.mts +7 -0
  122. package/dist/capture/build-state/resume.mjs +46 -0
  123. package/dist/capture/build-state/resume.mjs.map +1 -0
  124. package/dist/capture/build-state/types.d.mts +47 -0
  125. package/dist/capture/catalog/catalogue.d.mts +20 -0
  126. package/dist/capture/catalog/catalogue.mjs +52 -0
  127. package/dist/capture/catalog/catalogue.mjs.map +1 -0
  128. package/dist/capture/catalog/components.d.mts +21 -0
  129. package/dist/capture/catalog/components.mjs +54 -0
  130. package/dist/capture/catalog/components.mjs.map +1 -0
  131. package/dist/capture/catalog/history.d.mts +28 -0
  132. package/dist/capture/catalog/history.mjs +50 -0
  133. package/dist/capture/catalog/history.mjs.map +1 -0
  134. package/dist/capture/catalog/hook.d.mts +12 -0
  135. package/dist/capture/catalog/hook.mjs +18 -0
  136. package/dist/capture/catalog/hook.mjs.map +1 -0
  137. package/dist/capture/catalog/index.d.mts +11 -0
  138. package/dist/capture/catalog/load.d.mts +24 -0
  139. package/dist/capture/catalog/load.mjs +48 -0
  140. package/dist/capture/catalog/load.mjs.map +1 -0
  141. package/dist/capture/catalog/parse.d.mts +13 -0
  142. package/dist/capture/catalog/parse.mjs +55 -0
  143. package/dist/capture/catalog/parse.mjs.map +1 -0
  144. package/dist/capture/catalog/read.d.mts +15 -0
  145. package/dist/capture/catalog/read.mjs +39 -0
  146. package/dist/capture/catalog/read.mjs.map +1 -0
  147. package/dist/capture/catalog/types.d.mts +31 -0
  148. package/dist/capture/comparison-reference.d.mts +27 -0
  149. package/dist/capture/comparison-reference.mjs +75 -0
  150. package/dist/capture/comparison-reference.mjs.map +1 -0
  151. package/dist/capture/consumer/capture-handler.d.mts +56 -0
  152. package/dist/capture/consumer/capture-handler.mjs +117 -0
  153. package/dist/capture/consumer/capture-handler.mjs.map +1 -0
  154. package/dist/capture/consumer/idle.d.mts +15 -0
  155. package/dist/capture/consumer/idle.mjs +24 -0
  156. package/dist/capture/consumer/idle.mjs.map +1 -0
  157. package/dist/capture/consumer/index.d.mts +11 -0
  158. package/dist/capture/consumer/index.mjs +138 -0
  159. package/dist/capture/consumer/index.mjs.map +1 -0
  160. package/dist/capture/consumer/loop.mjs +109 -0
  161. package/dist/capture/consumer/loop.mjs.map +1 -0
  162. package/dist/capture/consumer/metrics.d.mts +39 -0
  163. package/dist/capture/consumer/metrics.mjs +37 -0
  164. package/dist/capture/consumer/metrics.mjs.map +1 -0
  165. package/dist/capture/consumer/retry.d.mts +31 -0
  166. package/dist/capture/consumer/retry.mjs +33 -0
  167. package/dist/capture/consumer/retry.mjs.map +1 -0
  168. package/dist/capture/consumer/run-job.mjs +194 -0
  169. package/dist/capture/consumer/run-job.mjs.map +1 -0
  170. package/dist/capture/consumer/startup.mjs +37 -0
  171. package/dist/capture/consumer/startup.mjs.map +1 -0
  172. package/dist/capture/consumer/types.d.mts +95 -0
  173. package/dist/capture/crash-failure.d.mts +23 -0
  174. package/dist/capture/crash-failure.mjs +69 -0
  175. package/dist/capture/crash-failure.mjs.map +1 -0
  176. package/dist/capture/db-queue/cadence.d.mts +30 -0
  177. package/dist/capture/db-queue/cadence.mjs +37 -0
  178. package/dist/capture/db-queue/cadence.mjs.map +1 -0
  179. package/dist/capture/db-queue/claim.d.mts +7 -0
  180. package/dist/capture/db-queue/claim.mjs +148 -0
  181. package/dist/capture/db-queue/claim.mjs.map +1 -0
  182. package/dist/capture/db-queue/clock.mjs +11 -0
  183. package/dist/capture/db-queue/clock.mjs.map +1 -0
  184. package/dist/capture/db-queue/codec.mjs +75 -0
  185. package/dist/capture/db-queue/codec.mjs.map +1 -0
  186. package/dist/capture/db-queue/index.d.mts +18 -0
  187. package/dist/capture/db-queue/index.mjs +89 -0
  188. package/dist/capture/db-queue/index.mjs.map +1 -0
  189. package/dist/capture/db-queue/keeper.d.mts +34 -0
  190. package/dist/capture/db-queue/keeper.mjs +91 -0
  191. package/dist/capture/db-queue/keeper.mjs.map +1 -0
  192. package/dist/capture/db-queue/lease.mjs +45 -0
  193. package/dist/capture/db-queue/lease.mjs.map +1 -0
  194. package/dist/capture/db-queue/lifecycle.mjs +35 -0
  195. package/dist/capture/db-queue/lifecycle.mjs.map +1 -0
  196. package/dist/capture/db-queue/operations.mjs +93 -0
  197. package/dist/capture/db-queue/operations.mjs.map +1 -0
  198. package/dist/capture/db-queue/poll-loop.d.mts +28 -0
  199. package/dist/capture/db-queue/poll-loop.mjs +88 -0
  200. package/dist/capture/db-queue/poll-loop.mjs.map +1 -0
  201. package/dist/capture/db-queue/poll.d.mts +8 -0
  202. package/dist/capture/db-queue/poll.mjs +68 -0
  203. package/dist/capture/db-queue/poll.mjs.map +1 -0
  204. package/dist/capture/db-queue/timers.d.mts +10 -0
  205. package/dist/capture/db-queue/timers.mjs +36 -0
  206. package/dist/capture/db-queue/timers.mjs.map +1 -0
  207. package/dist/capture/db-queue/types.d.mts +81 -0
  208. package/dist/capture/db-queue/types.mjs +11 -0
  209. package/dist/capture/db-queue/types.mjs.map +1 -0
  210. package/dist/capture/db-queue/wake.mjs +47 -0
  211. package/dist/capture/db-queue/wake.mjs.map +1 -0
  212. package/dist/capture/design.mjs +38 -0
  213. package/dist/capture/design.mjs.map +1 -0
  214. package/dist/capture/diff-record.mjs +24 -5
  215. package/dist/capture/diff-record.mjs.map +1 -1
  216. package/dist/capture/dispatch.d.mts +13 -10
  217. package/dist/capture/dispatch.mjs +102 -111
  218. package/dist/capture/dispatch.mjs.map +1 -1
  219. package/dist/capture/enrich.mjs +59 -0
  220. package/dist/capture/enrich.mjs.map +1 -0
  221. package/dist/capture/failure-sets.mjs +21 -0
  222. package/dist/capture/failure-sets.mjs.map +1 -0
  223. package/dist/capture/fingerprint.d.mts +40 -0
  224. package/dist/capture/fingerprint.mjs +82 -0
  225. package/dist/capture/fingerprint.mjs.map +1 -0
  226. package/dist/capture/forked/channel.d.mts +23 -0
  227. package/dist/capture/forked/child.d.mts +32 -0
  228. package/dist/capture/forked/child.mjs +201 -0
  229. package/dist/capture/forked/child.mjs.map +1 -0
  230. package/dist/capture/forked/crash-tracker.mjs +22 -0
  231. package/dist/capture/forked/crash-tracker.mjs.map +1 -0
  232. package/dist/capture/forked/decision.d.mts +24 -0
  233. package/dist/capture/forked/decision.mjs +26 -0
  234. package/dist/capture/forked/decision.mjs.map +1 -0
  235. package/dist/capture/forked/exit.mjs +11 -0
  236. package/dist/capture/forked/exit.mjs.map +1 -0
  237. package/dist/capture/forked/fork.d.mts +29 -0
  238. package/dist/capture/forked/fork.mjs +92 -0
  239. package/dist/capture/forked/fork.mjs.map +1 -0
  240. package/dist/capture/forked/forked-capture.d.mts +38 -0
  241. package/dist/capture/forked/forked-capture.mjs +239 -0
  242. package/dist/capture/forked/forked-capture.mjs.map +1 -0
  243. package/dist/capture/forked/lease-book.mjs +45 -0
  244. package/dist/capture/forked/lease-book.mjs.map +1 -0
  245. package/dist/capture/forked/protocol.d.mts +36 -0
  246. package/dist/capture/forked/protocol.mjs +24 -0
  247. package/dist/capture/forked/protocol.mjs.map +1 -0
  248. package/dist/capture/forked/runs.mjs +74 -0
  249. package/dist/capture/forked/runs.mjs.map +1 -0
  250. package/dist/capture/guards.mjs +1 -2
  251. package/dist/capture/ignore-regions.d.mts +36 -0
  252. package/dist/capture/ignore-regions.mjs +65 -0
  253. package/dist/capture/ignore-regions.mjs.map +1 -0
  254. package/dist/capture/isolate.mjs +140 -0
  255. package/dist/capture/isolate.mjs.map +1 -0
  256. package/dist/capture/job-lease.d.mts +26 -0
  257. package/dist/capture/job-lease.mjs +56 -0
  258. package/dist/capture/job-lease.mjs.map +1 -0
  259. package/dist/capture/matrix.mjs +298 -0
  260. package/dist/capture/matrix.mjs.map +1 -0
  261. package/dist/capture/modes.d.mts +23 -0
  262. package/dist/capture/modes.mjs +106 -0
  263. package/dist/capture/modes.mjs.map +1 -0
  264. package/dist/capture/orchestrator.d.mts +37 -7
  265. package/dist/capture/orchestrator.mjs +120 -110
  266. package/dist/capture/orchestrator.mjs.map +1 -1
  267. package/dist/capture/pipeline.d.mts +9 -4
  268. package/dist/capture/pipeline.mjs +284 -48
  269. package/dist/capture/pipeline.mjs.map +1 -1
  270. package/dist/capture/progress.d.mts +9 -0
  271. package/dist/capture/progress.mjs +27 -0
  272. package/dist/capture/progress.mjs.map +1 -0
  273. package/dist/capture/publish/accept.d.mts +37 -0
  274. package/dist/capture/publish/accept.mjs +27 -0
  275. package/dist/capture/publish/accept.mjs.map +1 -0
  276. package/dist/capture/publish/complete.d.mts +44 -0
  277. package/dist/capture/publish/complete.mjs +63 -0
  278. package/dist/capture/publish/complete.mjs.map +1 -0
  279. package/dist/capture/publish/extract.d.mts +18 -0
  280. package/dist/capture/publish/extract.mjs +120 -0
  281. package/dist/capture/publish/extract.mjs.map +1 -0
  282. package/dist/capture/publish/handler.d.mts +26 -0
  283. package/dist/capture/publish/handler.mjs +61 -0
  284. package/dist/capture/publish/handler.mjs.map +1 -0
  285. package/dist/capture/publish/index.d.mts +11 -0
  286. package/dist/capture/publish/invalid-zip.d.mts +8 -0
  287. package/dist/capture/publish/invalid-zip.mjs +11 -0
  288. package/dist/capture/publish/invalid-zip.mjs.map +1 -0
  289. package/dist/capture/publish/limits.d.mts +35 -0
  290. package/dist/capture/publish/limits.mjs +38 -0
  291. package/dist/capture/publish/limits.mjs.map +1 -0
  292. package/dist/capture/publish/published.d.mts +13 -0
  293. package/dist/capture/publish/published.mjs +17 -0
  294. package/dist/capture/publish/published.mjs.map +1 -0
  295. package/dist/capture/publish/run.d.mts +31 -0
  296. package/dist/capture/publish/run.mjs +29 -0
  297. package/dist/capture/publish/run.mjs.map +1 -0
  298. package/dist/capture/rediff.d.mts +1 -3
  299. package/dist/capture/rediff.mjs +23 -9
  300. package/dist/capture/rediff.mjs.map +1 -1
  301. package/dist/capture/render.mjs +52 -0
  302. package/dist/capture/render.mjs.map +1 -0
  303. package/dist/capture/scratch.d.mts +42 -0
  304. package/dist/capture/scratch.mjs +136 -0
  305. package/dist/capture/scratch.mjs.map +1 -0
  306. package/dist/capture/shard-plan.mjs +127 -0
  307. package/dist/capture/shard-plan.mjs.map +1 -0
  308. package/dist/capture/shards/context.mjs +51 -0
  309. package/dist/capture/shards/context.mjs.map +1 -0
  310. package/dist/capture/shards/execute.mjs +175 -0
  311. package/dist/capture/shards/execute.mjs.map +1 -0
  312. package/dist/capture/shards/fan-out.mjs +125 -0
  313. package/dist/capture/shards/fan-out.mjs.map +1 -0
  314. package/dist/capture/shards/history.mjs +34 -0
  315. package/dist/capture/shards/history.mjs.map +1 -0
  316. package/dist/capture/shards/reduce.mjs +96 -0
  317. package/dist/capture/shards/reduce.mjs.map +1 -0
  318. package/dist/capture/sizing.d.mts +0 -2
  319. package/dist/capture/sizing.mjs +2 -13
  320. package/dist/capture/sizing.mjs.map +1 -1
  321. package/dist/capture/skip-checks.mjs +3 -67
  322. package/dist/capture/skip-checks.mjs.map +1 -1
  323. package/dist/capture/statics.d.mts +7 -10
  324. package/dist/capture/statics.mjs +26 -74
  325. package/dist/capture/statics.mjs.map +1 -1
  326. package/dist/capture/storybook-urls.d.mts +38 -0
  327. package/dist/capture/storybook-urls.mjs +41 -0
  328. package/dist/capture/storybook-urls.mjs.map +1 -0
  329. package/dist/capture/storybook.d.mts +12 -6
  330. package/dist/capture/storybook.mjs +63 -19
  331. package/dist/capture/storybook.mjs.map +1 -1
  332. package/dist/capture/target.mjs +20 -0
  333. package/dist/capture/target.mjs.map +1 -0
  334. package/dist/capture/targets.d.mts +23 -0
  335. package/dist/capture/targets.mjs +31 -0
  336. package/dist/capture/targets.mjs.map +1 -0
  337. package/dist/capture/tests.d.mts +35 -0
  338. package/dist/capture/tests.mjs +136 -0
  339. package/dist/capture/tests.mjs.map +1 -0
  340. package/dist/capture/token-chunks.mjs +91 -0
  341. package/dist/capture/token-chunks.mjs.map +1 -0
  342. package/dist/capture.d.mts +63 -7
  343. package/dist/capture.mjs +51 -3
  344. package/dist/config.d.mts +136 -14
  345. package/dist/config.mjs +14 -8
  346. package/dist/config.mjs.map +1 -1
  347. package/dist/diff.d.mts +7 -3
  348. package/dist/diff.mjs +15 -3
  349. package/dist/diff.mjs.map +1 -0
  350. package/dist/index.d.mts +3 -3
  351. package/dist/index.mjs +2 -2
  352. package/dist/insights/budget.d.mts +18 -0
  353. package/dist/insights/budget.mjs +32 -0
  354. package/dist/insights/budget.mjs.map +1 -0
  355. package/dist/insights/envelope.d.mts +57 -0
  356. package/dist/insights/envelope.mjs +59 -0
  357. package/dist/insights/envelope.mjs.map +1 -0
  358. package/dist/insights/evidence-health.d.mts +30 -0
  359. package/dist/insights/evidence-health.mjs +27 -0
  360. package/dist/insights/evidence-health.mjs.map +1 -0
  361. package/dist/insights/evidence.d.mts +53 -0
  362. package/dist/insights/evidence.mjs +63 -0
  363. package/dist/insights/evidence.mjs.map +1 -0
  364. package/dist/insights/hash.d.mts +16 -0
  365. package/dist/insights/hash.mjs +20 -0
  366. package/dist/insights/hash.mjs.map +1 -0
  367. package/dist/insights/limits.d.mts +22 -0
  368. package/dist/insights/limits.mjs +23 -0
  369. package/dist/insights/limits.mjs.map +1 -0
  370. package/dist/insights/prompts/v1.d.mts +11 -0
  371. package/dist/insights/prompts/v1.mjs +33 -0
  372. package/dist/insights/prompts/v1.mjs.map +1 -0
  373. package/dist/insights/redact.d.mts +7 -0
  374. package/dist/insights/redact.mjs +23 -0
  375. package/dist/insights/redact.mjs.map +1 -0
  376. package/dist/insights/text.mjs +43 -0
  377. package/dist/insights/text.mjs.map +1 -0
  378. package/dist/insights.d.mts +11 -0
  379. package/dist/insights.mjs +12 -0
  380. package/dist/logger.d.mts +0 -2
  381. package/dist/logger.mjs +18 -3
  382. package/dist/logger.mjs.map +1 -1
  383. package/dist/models/ai-budget-alert.d.mts +21 -0
  384. package/dist/models/ai-budget-alert.mjs +37 -0
  385. package/dist/models/ai-budget-alert.mjs.map +1 -0
  386. package/dist/models/ai-usage.d.mts +38 -0
  387. package/dist/models/ai-usage.mjs +60 -0
  388. package/dist/models/ai-usage.mjs.map +1 -0
  389. package/dist/models/baseline-approval.d.mts +18 -0
  390. package/dist/models/baseline-approval.mjs +41 -0
  391. package/dist/models/baseline-approval.mjs.map +1 -0
  392. package/dist/models/baseline-archive.d.mts +82 -0
  393. package/dist/models/baseline-archive.mjs +105 -0
  394. package/dist/models/baseline-archive.mjs.map +1 -0
  395. package/dist/models/baseline-atomic.mjs +66 -0
  396. package/dist/models/baseline-atomic.mjs.map +1 -0
  397. package/dist/models/baseline-conflict.d.mts +6 -0
  398. package/dist/models/baseline-conflict.mjs +9 -0
  399. package/dist/models/baseline-conflict.mjs.map +1 -0
  400. package/dist/models/baseline-export.d.mts +17 -0
  401. package/dist/models/baseline-export.mjs +135 -0
  402. package/dist/models/baseline-export.mjs.map +1 -0
  403. package/dist/models/baseline-import.mjs +117 -0
  404. package/dist/models/baseline-import.mjs.map +1 -0
  405. package/dist/models/baseline-origin.d.mts +16 -0
  406. package/dist/models/baseline-origin.mjs +35 -0
  407. package/dist/models/baseline-origin.mjs.map +1 -0
  408. package/dist/models/baseline-status.d.mts +0 -2
  409. package/dist/models/baseline-status.mjs +1 -2
  410. package/dist/models/baseline-transfer.d.mts +48 -0
  411. package/dist/models/baseline-transfer.mjs +149 -0
  412. package/dist/models/baseline-transfer.mjs.map +1 -0
  413. package/dist/models/baseline.d.mts +37 -7
  414. package/dist/models/baseline.mjs +152 -28
  415. package/dist/models/baseline.mjs.map +1 -1
  416. package/dist/models/build-component.d.mts +26 -0
  417. package/dist/models/build-component.mjs +54 -0
  418. package/dist/models/build-component.mjs.map +1 -0
  419. package/dist/models/build-review-status.d.mts +27 -0
  420. package/dist/models/build-review-status.mjs +36 -0
  421. package/dist/models/build-review-status.mjs.map +1 -0
  422. package/dist/models/build-review.d.mts +26 -0
  423. package/dist/models/build-review.mjs +53 -0
  424. package/dist/models/build-review.mjs.map +1 -0
  425. package/dist/models/build.d.mts +25 -5
  426. package/dist/models/build.mjs +53 -15
  427. package/dist/models/build.mjs.map +1 -1
  428. package/dist/models/capture-attempt.d.mts +7 -3
  429. package/dist/models/capture-attempt.mjs +30 -6
  430. package/dist/models/capture-attempt.mjs.map +1 -1
  431. package/dist/models/capture-job.d.mts +104 -0
  432. package/dist/models/capture-job.mjs +287 -0
  433. package/dist/models/capture-job.mjs.map +1 -0
  434. package/dist/models/capture-log.d.mts +1 -3
  435. package/dist/models/capture-log.mjs +5 -5
  436. package/dist/models/capture-log.mjs.map +1 -1
  437. package/dist/models/capture-shard.d.mts +60 -0
  438. package/dist/models/capture-shard.mjs +189 -0
  439. package/dist/models/capture-shard.mjs.map +1 -0
  440. package/dist/models/changeset.d.mts +46 -0
  441. package/dist/models/changeset.mjs +80 -0
  442. package/dist/models/changeset.mjs.map +1 -0
  443. package/dist/models/columns.mjs +18 -0
  444. package/dist/models/columns.mjs.map +1 -0
  445. package/dist/models/comment.d.mts +4 -3
  446. package/dist/models/comment.mjs +8 -6
  447. package/dist/models/comment.mjs.map +1 -1
  448. package/dist/models/component.d.mts +41 -0
  449. package/dist/models/component.mjs +59 -0
  450. package/dist/models/component.mjs.map +1 -0
  451. package/dist/models/connections.d.mts +39 -0
  452. package/dist/models/connections.mjs +111 -0
  453. package/dist/models/connections.mjs.map +1 -0
  454. package/dist/models/content-ref.d.mts +1 -3
  455. package/dist/models/content-ref.mjs +2 -3
  456. package/dist/models/content-ref.mjs.map +1 -1
  457. package/dist/models/credentials.d.mts +0 -2
  458. package/dist/models/credentials.mjs +13 -4
  459. package/dist/models/credentials.mjs.map +1 -1
  460. package/dist/models/design-credentials.d.mts +39 -0
  461. package/dist/models/design-credentials.mjs +85 -0
  462. package/dist/models/design-credentials.mjs.map +1 -0
  463. package/dist/models/design-health.d.mts +14 -0
  464. package/dist/models/design-health.mjs +24 -0
  465. package/dist/models/design-health.mjs.map +1 -0
  466. package/dist/models/design-nodes.d.mts +81 -0
  467. package/dist/models/design-nodes.mjs +221 -0
  468. package/dist/models/design-nodes.mjs.map +1 -0
  469. package/dist/models/design-renders.mjs +73 -0
  470. package/dist/models/design-renders.mjs.map +1 -0
  471. package/dist/models/design-resolve.d.mts +27 -0
  472. package/dist/models/design-resolve.mjs +40 -0
  473. package/dist/models/design-resolve.mjs.map +1 -0
  474. package/dist/models/design.d.mts +37 -0
  475. package/dist/models/design.mjs +89 -0
  476. package/dist/models/design.mjs.map +1 -0
  477. package/dist/models/inherited-ratio.d.mts +19 -0
  478. package/dist/models/inherited-ratio.mjs +21 -0
  479. package/dist/models/inherited-ratio.mjs.map +1 -0
  480. package/dist/models/insight.d.mts +68 -0
  481. package/dist/models/insight.mjs +161 -0
  482. package/dist/models/insight.mjs.map +1 -0
  483. package/dist/models/label.d.mts +4 -4
  484. package/dist/models/label.mjs +26 -12
  485. package/dist/models/label.mjs.map +1 -1
  486. package/dist/models/member.d.mts +1 -3
  487. package/dist/models/member.mjs +6 -6
  488. package/dist/models/member.mjs.map +1 -1
  489. package/dist/models/notification-channel.d.mts +37 -5
  490. package/dist/models/notification-channel.mjs +89 -11
  491. package/dist/models/notification-channel.mjs.map +1 -1
  492. package/dist/models/notification-subscription.d.mts +1 -4
  493. package/dist/models/notification-subscription.mjs +8 -11
  494. package/dist/models/notification-subscription.mjs.map +1 -1
  495. package/dist/models/project-group-mapping.d.mts +6 -3
  496. package/dist/models/project-group-mapping.mjs +15 -6
  497. package/dist/models/project-group-mapping.mjs.map +1 -1
  498. package/dist/models/project.d.mts +9 -3
  499. package/dist/models/project.mjs +10 -6
  500. package/dist/models/project.mjs.map +1 -1
  501. package/dist/models/public-origin.d.mts +61 -0
  502. package/dist/models/public-origin.mjs +113 -0
  503. package/dist/models/public-origin.mjs.map +1 -0
  504. package/dist/models/review-switch-off.d.mts +12 -0
  505. package/dist/models/review-switch-off.mjs +25 -0
  506. package/dist/models/review-switch-off.mjs.map +1 -0
  507. package/dist/models/site-settings.d.mts +21 -0
  508. package/dist/models/site-settings.mjs +47 -0
  509. package/dist/models/site-settings.mjs.map +1 -0
  510. package/dist/models/snapshot.d.mts +39 -3
  511. package/dist/models/snapshot.mjs +54 -5
  512. package/dist/models/snapshot.mjs.map +1 -1
  513. package/dist/models/token.d.mts +13 -3
  514. package/dist/models/token.mjs +24 -7
  515. package/dist/models/token.mjs.map +1 -1
  516. package/dist/models/usage.d.mts +74 -0
  517. package/dist/models/usage.mjs +148 -0
  518. package/dist/models/usage.mjs.map +1 -0
  519. package/dist/models/user.d.mts +1 -3
  520. package/dist/models/user.mjs +5 -5
  521. package/dist/models/user.mjs.map +1 -1
  522. package/dist/models/webhook.d.mts +15 -3
  523. package/dist/models/webhook.mjs +34 -6
  524. package/dist/models/webhook.mjs.map +1 -1
  525. package/dist/models.d.mts +30 -4
  526. package/dist/models.mjs +31 -6
  527. package/dist/options.d.mts +16 -0
  528. package/dist/options.mjs +88 -0
  529. package/dist/options.mjs.map +1 -0
  530. package/dist/paths.d.mts +21 -6
  531. package/dist/paths.mjs +57 -12
  532. package/dist/paths.mjs.map +1 -1
  533. package/dist/retention/ai.d.mts +16 -0
  534. package/dist/retention/ai.mjs +22 -0
  535. package/dist/retention/ai.mjs.map +1 -0
  536. package/dist/retention/pending.mjs +46 -0
  537. package/dist/retention/pending.mjs.map +1 -0
  538. package/dist/retention/published-gzip-sweep.mjs +28 -0
  539. package/dist/retention/published-gzip-sweep.mjs.map +1 -0
  540. package/dist/retention/screenshot-sweep.d.mts +49 -0
  541. package/dist/retention/screenshot-sweep.mjs +127 -0
  542. package/dist/retention/screenshot-sweep.mjs.map +1 -0
  543. package/dist/retention.d.mts +16 -4
  544. package/dist/retention.mjs +76 -16
  545. package/dist/retention.mjs.map +1 -1
  546. package/dist/schema/baseline.d.mts +8 -2
  547. package/dist/schema/build-component.d.mts +23 -0
  548. package/dist/schema/build-review.d.mts +15 -0
  549. package/dist/schema/build.d.mts +7 -2
  550. package/dist/schema/capture-attempt.d.mts +0 -2
  551. package/dist/schema/capture-job.d.mts +58 -0
  552. package/dist/schema/capture-shard.d.mts +33 -0
  553. package/dist/schema/comment.d.mts +2 -2
  554. package/dist/schema/connection.d.mts +22 -0
  555. package/dist/schema/content-ref.d.mts +0 -2
  556. package/dist/schema/design.d.mts +56 -0
  557. package/dist/schema/insight.d.mts +52 -0
  558. package/dist/schema/label.d.mts +0 -2
  559. package/dist/schema/member.d.mts +0 -2
  560. package/dist/schema/notification.d.mts +4 -2
  561. package/dist/schema/project-group-mapping.d.mts +0 -2
  562. package/dist/schema/project.d.mts +21 -2
  563. package/dist/schema/site-setting.d.mts +19 -0
  564. package/dist/schema/snapshot.d.mts +17 -2
  565. package/dist/schema/token.d.mts +0 -2
  566. package/dist/schema/usage.d.mts +28 -0
  567. package/dist/schema/user.d.mts +0 -2
  568. package/dist/schema/webhook.d.mts +0 -2
  569. package/dist/schema.d.mts +12 -6
  570. package/dist/serverless.d.mts +19 -0
  571. package/dist/serverless.mjs +36 -0
  572. package/dist/serverless.mjs.map +1 -0
  573. package/dist/test-helpers/build-reference-contract.d.mts +14 -0
  574. package/dist/test-helpers/build-reference-contract.mjs +66 -0
  575. package/dist/test-helpers/build-reference-contract.mjs.map +1 -0
  576. package/dist/test-helpers/create-project.d.mts +1 -3
  577. package/dist/test-helpers/create-project.mjs +1 -2
  578. package/dist/test-helpers/database-contract.d.mts +0 -2
  579. package/dist/test-helpers/database-contract.mjs +37 -2
  580. package/dist/test-helpers/database-contract.mjs.map +1 -1
  581. package/dist/test-helpers/deferred.d.mts +37 -0
  582. package/dist/test-helpers/deferred.mjs +60 -0
  583. package/dist/test-helpers/deferred.mjs.map +1 -0
  584. package/dist/test-helpers/design-contract.d.mts +19 -0
  585. package/dist/test-helpers/design-contract.mjs +39 -0
  586. package/dist/test-helpers/design-contract.mjs.map +1 -0
  587. package/dist/test-helpers/fake-adapters.d.mts +0 -2
  588. package/dist/test-helpers/fake-adapters.mjs +1 -2
  589. package/dist/test-helpers/fake-database.d.mts +0 -2
  590. package/dist/test-helpers/fake-database.mjs +21 -4
  591. package/dist/test-helpers/fake-database.mjs.map +1 -1
  592. package/dist/test-helpers/fake-design.d.mts +41 -0
  593. package/dist/test-helpers/fake-design.mjs +113 -0
  594. package/dist/test-helpers/fake-design.mjs.map +1 -0
  595. package/dist/test-helpers/fake-notifier.d.mts +19 -0
  596. package/dist/test-helpers/fake-notifier.mjs +43 -0
  597. package/dist/test-helpers/fake-notifier.mjs.map +1 -0
  598. package/dist/test-helpers/fake-storage.d.mts +0 -2
  599. package/dist/test-helpers/fake-storage.mjs +1 -2
  600. package/dist/test-helpers/fake-tables.mjs +260 -69
  601. package/dist/test-helpers/fake-tables.mjs.map +1 -1
  602. package/dist/test-helpers/manual-clock.d.mts +25 -0
  603. package/dist/test-helpers/manual-clock.mjs +55 -0
  604. package/dist/test-helpers/manual-clock.mjs.map +1 -0
  605. package/dist/test-helpers/notifier-contract.d.mts +7 -3
  606. package/dist/test-helpers/notifier-contract.mjs +33 -5
  607. package/dist/test-helpers/notifier-contract.mjs.map +1 -1
  608. package/dist/test-helpers/queue-contract.d.mts +16 -4
  609. package/dist/test-helpers/queue-contract.mjs +196 -3
  610. package/dist/test-helpers/queue-contract.mjs.map +1 -1
  611. package/dist/test-helpers/queue-multi-instance.d.mts +18 -0
  612. package/dist/test-helpers/queue-multi-instance.mjs +205 -0
  613. package/dist/test-helpers/queue-multi-instance.mjs.map +1 -0
  614. package/dist/test-helpers/runner-contract.d.mts +0 -2
  615. package/dist/test-helpers/runner-contract.mjs +12 -2
  616. package/dist/test-helpers/runner-contract.mjs.map +1 -1
  617. package/dist/test-helpers/sql-chunks.mjs +25 -2
  618. package/dist/test-helpers/sql-chunks.mjs.map +1 -1
  619. package/dist/test-helpers/storage-contract.d.mts +0 -2
  620. package/dist/test-helpers/storage-contract.mjs +2 -3
  621. package/dist/test-helpers.d.mts +10 -4
  622. package/dist/test-helpers.mjs +9 -3
  623. package/dist/tracing.mjs +36 -6
  624. package/dist/tracing.mjs.map +1 -1
  625. package/dist/types.d.mts +14 -5
  626. package/dist/types.mjs +22 -6
  627. package/dist/types.mjs.map +1 -1
  628. package/dist/urls.d.mts +4 -2
  629. package/dist/urls.mjs +12 -4
  630. package/dist/urls.mjs.map +1 -1
  631. package/dist/utils/adaptive-concurrency.d.mts +64 -0
  632. package/dist/utils/adaptive-concurrency.mjs +148 -0
  633. package/dist/utils/adaptive-concurrency.mjs.map +1 -0
  634. package/dist/utils/connect-retry.d.mts +26 -0
  635. package/dist/utils/connect-retry.mjs +42 -0
  636. package/dist/utils/connect-retry.mjs.map +1 -0
  637. package/dist/utils/encrypt.d.mts +0 -2
  638. package/dist/utils/encrypt.mjs +1 -2
  639. package/dist/utils/environment.d.mts +17 -0
  640. package/dist/utils/environment.mjs +58 -0
  641. package/dist/utils/environment.mjs.map +1 -0
  642. package/dist/utils/hash.d.mts +0 -2
  643. package/dist/utils/hash.mjs +1 -2
  644. package/dist/utils/http.d.mts +29 -3
  645. package/dist/utils/http.mjs +100 -19
  646. package/dist/utils/http.mjs.map +1 -1
  647. package/dist/utils/map-adaptive.d.mts +13 -0
  648. package/dist/utils/map-adaptive.mjs +71 -0
  649. package/dist/utils/map-adaptive.mjs.map +1 -0
  650. package/dist/utils/map-limit.d.mts +8 -0
  651. package/dist/utils/map-limit.mjs +31 -0
  652. package/dist/utils/map-limit.mjs.map +1 -0
  653. package/dist/utils/mime.d.mts +0 -2
  654. package/dist/utils/mime.mjs +1 -2
  655. package/dist/utils/page-limiter.d.mts +35 -0
  656. package/dist/utils/page-limiter.mjs +55 -0
  657. package/dist/utils/page-limiter.mjs.map +1 -0
  658. package/dist/utils/path-security.d.mts +0 -2
  659. package/dist/utils/path-security.mjs +2 -4
  660. package/dist/utils/path-security.mjs.map +1 -1
  661. package/dist/utils/public-origin.d.mts +18 -0
  662. package/dist/utils/public-origin.mjs +74 -0
  663. package/dist/utils/public-origin.mjs.map +1 -0
  664. package/dist/utils/redact.d.mts +0 -2
  665. package/dist/utils/redact.mjs +4 -2
  666. package/dist/utils/redact.mjs.map +1 -1
  667. package/dist/utils/remote-environment.d.mts +76 -0
  668. package/dist/utils/remote-environment.mjs +163 -0
  669. package/dist/utils/remote-environment.mjs.map +1 -0
  670. package/dist/utils/resources.d.mts +62 -0
  671. package/dist/utils/resources.mjs +121 -0
  672. package/dist/utils/resources.mjs.map +1 -0
  673. package/dist/utils/screenshot-store.d.mts +13 -0
  674. package/dist/utils/screenshot-store.mjs +40 -0
  675. package/dist/utils/screenshot-store.mjs.map +1 -0
  676. package/dist/utils/session-gate.d.mts +23 -0
  677. package/dist/utils/session-gate.mjs +69 -0
  678. package/dist/utils/session-gate.mjs.map +1 -0
  679. package/dist/utils/storybook-token.d.mts +89 -0
  680. package/dist/utils/storybook-token.mjs +135 -0
  681. package/dist/utils/storybook-token.mjs.map +1 -0
  682. package/dist/utils/storybook-url.d.mts +13 -0
  683. package/dist/utils/storybook-url.mjs +20 -0
  684. package/dist/utils/storybook-url.mjs.map +1 -0
  685. package/dist/utils/timing.d.mts +0 -2
  686. package/dist/utils/timing.mjs +2 -3
  687. package/dist/utils/timing.mjs.map +1 -1
  688. package/dist/utils/ulid.d.mts +0 -2
  689. package/dist/utils/ulid.mjs +1 -2
  690. package/dist/utils/zip-read.mjs +128 -0
  691. package/dist/utils/zip-read.mjs.map +1 -0
  692. package/dist/utils/zip-write.d.mts +16 -0
  693. package/dist/utils/zip-write.mjs +187 -0
  694. package/dist/utils/zip-write.mjs.map +1 -0
  695. package/dist/utils.d.mts +17 -3
  696. package/dist/utils.mjs +18 -4
  697. package/package.json +35 -26
  698. package/dist/adapter/capture-runner.mjs.map +0 -1
  699. package/dist/adapter/git-host/comments.d.mts +0 -41
  700. package/dist/adapter/git-host/comments.mjs +0 -54
  701. package/dist/adapter/git-host/comments.mjs.map +0 -1
  702. package/dist/adapter/git-host/helpers.d.mts +0 -13
  703. package/dist/adapter/git-host/helpers.mjs +0 -30
  704. package/dist/adapter/git-host/helpers.mjs.map +0 -1
  705. package/dist/adapter/git-host.d.mts +0 -42
  706. package/dist/capture/queue.d.mts +0 -38
  707. package/dist/capture/queue.mjs +0 -98
  708. package/dist/capture/queue.mjs.map +0 -1
  709. package/dist/capture/recovery.d.mts +0 -21
  710. package/dist/capture/recovery.mjs +0 -83
  711. package/dist/capture/recovery.mjs.map +0 -1
  712. package/dist/capture/status-fanout.mjs +0 -72
  713. package/dist/capture/status-fanout.mjs.map +0 -1
  714. package/dist/diff/engine.d.mts +0 -16
  715. package/dist/diff/engine.mjs +0 -87
  716. package/dist/diff/engine.mjs.map +0 -1
  717. package/dist/diff/options.d.mts +0 -42
  718. package/dist/diff/options.mjs +0 -15
  719. package/dist/diff/options.mjs.map +0 -1
  720. package/dist/models/status-config.d.mts +0 -38
  721. package/dist/models/status-config.mjs +0 -63
  722. package/dist/models/status-config.mjs.map +0 -1
  723. package/dist/schema/status-config.d.mts +0 -16
  724. package/dist/test-helpers/git-contract.d.mts +0 -11
  725. package/dist/test-helpers/git-contract.mjs +0 -34
  726. package/dist/test-helpers/git-contract.mjs.map +0 -1
  727. /package/dist/adapter/{git-host.mjs → oauth.mjs} +0 -0
@@ -0,0 +1,55 @@
1
+ import "node:path";
2
+ import "node:url";
3
+ import.meta.url;
4
+ import { mapLimit } from "./map-limit.mjs";
5
+ import { detectResources, maxPageConcurrency, recommendedPageConcurrency } from "./resources.mjs";
6
+ import { AdaptiveConcurrency } from "./adaptive-concurrency.mjs";
7
+ import { mapAdaptive } from "./map-adaptive.mjs";
8
+ // src/utils/page-limiter.ts
9
+ /**
10
+ * The session gate's size for a remote target; a fixed limit when `concurrency` is given; otherwise start at the CPU/memory/engine-sized
11
+ * recommendation and let latency, event-loop lag and timeouts move it up to the adaptive ceiling.
12
+ */
13
+ function createPageLimiter(options) {
14
+ const { gate } = options;
15
+ if (gate !== void 0) return {
16
+ each: async (items, fn) => {
17
+ await mapLimit(items, Math.min(gate.size, options.concurrency ?? gate.size), async (item) => {
18
+ await gate.run(async () => await fn(item));
19
+ });
20
+ },
21
+ dispose: noop
22
+ };
23
+ if (options.concurrency !== void 0) {
24
+ const limit = options.concurrency;
25
+ return {
26
+ each: async (items, fn) => {
27
+ await mapLimit(items, limit, async (item) => {
28
+ await fn(item);
29
+ });
30
+ },
31
+ dispose: noop
32
+ };
33
+ }
34
+ const resources = detectResources();
35
+ const controller = new AdaptiveConcurrency({
36
+ initial: recommendedPageConcurrency(resources, options.browser),
37
+ max: maxPageConcurrency(resources, options.browser),
38
+ logger: options.logger
39
+ });
40
+ return {
41
+ each: async (items, fn) => {
42
+ await mapAdaptive(items, controller, async (item) => ({
43
+ value: void 0,
44
+ timedOut: await fn(item)
45
+ }));
46
+ },
47
+ dispose: () => {
48
+ controller.dispose();
49
+ }
50
+ };
51
+ }
52
+ function noop() {}
53
+ export { createPageLimiter };
54
+
55
+ //# sourceMappingURL=page-limiter.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"page-limiter.mjs","names":[],"sources":["../../src/utils/page-limiter.ts"],"sourcesContent":["/** How many pages a capture run renders at once: fixed when configured, adaptive otherwise. */\nimport type { Logger } from \"../logger.ts\";\nimport { AdaptiveConcurrency } from \"./adaptive-concurrency.ts\";\nimport { mapAdaptive } from \"./map-adaptive.ts\";\nimport { mapLimit } from \"./map-limit.ts\";\nimport { detectResources, maxPageConcurrency, recommendedPageConcurrency } from \"./resources.ts\";\nimport type { SessionGate } from \"./session-gate.ts\";\n\n/** Options for {@link createPageLimiter}. */\nexport interface PageLimiterOptions {\n /** Explicit page count (config or run input). Fixed: the adaptive controller stays off. */\n concurrency?: number;\n /**\n * A remote target's session cap, shared by every render of that target in the process. It\n * replaces CPU and memory sizing: the plan's parallel-session limit is the budget, not this host.\n * An explicit `concurrency` can lower a run's share of it, never raise it.\n */\n gate?: SessionGate;\n /** Engine being rendered; heavier engines get a smaller budget. */\n browser?: string;\n logger?: Logger;\n}\n\n/** Runs capture jobs under a page limit. One limiter spans a whole run so what it learns carries across batches. */\nexport interface PageLimiter {\n /**\n * Run `fn` over `items`. `fn` resolves to whether the capture timed out (it handles its own\n * failures, so the limiter cannot see them otherwise).\n */\n each<T>(items: readonly T[], fn: (item: T) => Promise<boolean>): Promise<void>;\n /** Release the event-loop monitor. */\n dispose(): void;\n}\n\n/**\n * The session gate's size for a remote target; a fixed limit when `concurrency` is given; otherwise start at the CPU/memory/engine-sized\n * recommendation and let latency, event-loop lag and timeouts move it up to the adaptive ceiling.\n */\nexport function createPageLimiter(options: PageLimiterOptions): PageLimiter {\n const { gate } = options;\n if (gate !== undefined) {\n return {\n each: async (items, fn) => {\n await mapLimit(\n items,\n Math.min(gate.size, options.concurrency ?? gate.size),\n async (item) => {\n await gate.run(async () => await fn(item));\n },\n );\n },\n dispose: noop,\n };\n }\n if (options.concurrency !== undefined) {\n const limit = options.concurrency;\n return {\n each: async (items, fn) => {\n await mapLimit(items, limit, async (item) => {\n await fn(item);\n });\n },\n dispose: noop,\n };\n }\n const resources = detectResources();\n const controller = new AdaptiveConcurrency({\n initial: recommendedPageConcurrency(resources, options.browser),\n max: maxPageConcurrency(resources, options.browser),\n logger: options.logger,\n });\n return {\n each: async (items, fn) => {\n await mapAdaptive(items, controller, async (item) => ({\n value: undefined,\n timedOut: await fn(item),\n }));\n },\n dispose: () => {\n controller.dispose();\n },\n };\n}\n\nfunction noop(): void {}\n"],"mappings":";;;;;;;;;;;;AAsCA,SAAgB,kBAAkB,SAA0C;CAC1E,MAAM,EAAE,SAAS;CACjB,IAAI,SAAS,KAAA,GACX,OAAO;EACL,MAAM,OAAO,OAAO,OAAO;GACzB,MAAM,SACJ,OACA,KAAK,IAAI,KAAK,MAAM,QAAQ,eAAe,KAAK,IAAI,GACpD,OAAO,SAAS;IACd,MAAM,KAAK,IAAI,YAAY,MAAM,GAAG,IAAI,CAAC;GAC3C,CACF;EACF;EACA,SAAS;CACX;CAEF,IAAI,QAAQ,gBAAgB,KAAA,GAAW;EACrC,MAAM,QAAQ,QAAQ;EACtB,OAAO;GACL,MAAM,OAAO,OAAO,OAAO;IACzB,MAAM,SAAS,OAAO,OAAO,OAAO,SAAS;KAC3C,MAAM,GAAG,IAAI;IACf,CAAC;GACH;GACA,SAAS;EACX;CACF;CACA,MAAM,YAAY,gBAAgB;CAClC,MAAM,aAAa,IAAI,oBAAoB;EACzC,SAAS,2BAA2B,WAAW,QAAQ,OAAO;EAC9D,KAAK,mBAAmB,WAAW,QAAQ,OAAO;EAClD,QAAQ,QAAQ;CAClB,CAAC;CACD,OAAO;EACL,MAAM,OAAO,OAAO,OAAO;GACzB,MAAM,YAAY,OAAO,YAAY,OAAO,UAAU;IACpD,OAAO,KAAA;IACP,UAAU,MAAM,GAAG,IAAI;GACzB,EAAE;EACJ;EACA,eAAe;GACb,WAAW,QAAQ;EACrB;CACF;AACF;AAEA,SAAS,OAAa,CAAC"}
@@ -1,12 +1,10 @@
1
1
  import __tsdown_shims_path from 'node:path';
2
2
  import __tsdown_shims_url from 'node:url';
3
- //#region src/utils/path-security.d.ts
4
3
  /** Whether a path segment is safe (no traversal). */
5
4
  declare function isSafeSegment(segment: string): boolean;
6
5
  /** Whether joining root with candidate stays inside root (no traversal). */
7
6
  declare function isPathSafe(root: string, candidate: string): boolean;
8
7
  /** Check if a path built from root + entry would escape root (for zip extraction). */
9
8
  declare function isBlockedTarget(root: string, entryPath: string): boolean;
10
- //#endregion
11
9
  export { isBlockedTarget, isPathSafe, isSafeSegment };
12
10
  //# sourceMappingURL=path-security.d.mts.map
@@ -1,8 +1,7 @@
1
- import "node:path";
1
+ import { join, normalize, sep } from "node:path";
2
2
  import "node:url";
3
3
  import.meta.url;
4
- import { join, normalize, sep } from "node:path";
5
- //#region src/utils/path-security.ts
4
+ // src/utils/path-security.ts
6
5
  /** Whether a path segment is safe (no traversal). */
7
6
  function isSafeSegment(segment) {
8
7
  return segment !== ".." && !segment.startsWith("/") && !segment.includes("\\") && !segment.includes("..");
@@ -18,7 +17,6 @@ function isBlockedTarget(root, entryPath) {
18
17
  const target = normalize(join(root, entryPath));
19
18
  return target !== root && !target.startsWith(normalize(root) + sep);
20
19
  }
21
- //#endregion
22
20
  export { isBlockedTarget, isPathSafe, isSafeSegment };
23
21
 
24
22
  //# sourceMappingURL=path-security.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"path-security.mjs","names":[],"sources":["../../src/utils/path-security.ts"],"sourcesContent":["import { join, normalize, sep } from \"node:path\";\n\n/** Whether a path segment is safe (no traversal). */\nexport function isSafeSegment(segment: string): boolean {\n return (\n segment !== \"..\" &&\n !segment.startsWith(\"/\") &&\n !segment.includes(\"\\\\\") &&\n !segment.includes(\"..\")\n );\n}\n\n/** Whether joining root with candidate stays inside root (no traversal). */\nexport function isPathSafe(root: string, candidate: string): boolean {\n const normalizedRoot = normalize(root);\n const normalizedCandidate = normalize(candidate);\n return (\n normalizedCandidate === normalizedRoot ||\n normalizedCandidate.startsWith(normalizedRoot + sep) ||\n normalizedCandidate.startsWith(`${normalizedRoot}/`)\n );\n}\n\n/** Check if a path built from root + entry would escape root (for zip extraction). */\nexport function isBlockedTarget(root: string, entryPath: string): boolean {\n const target = normalize(join(root, entryPath));\n return target !== root && !target.startsWith(normalize(root) + sep);\n}\n"],"mappings":";;;;;;AAGA,SAAgB,cAAc,SAA0B;CACtD,OACE,YAAY,QACZ,CAAC,QAAQ,WAAW,GAAG,KACvB,CAAC,QAAQ,SAAS,IAAI,KACtB,CAAC,QAAQ,SAAS,IAAI;AAE1B;;AAGA,SAAgB,WAAW,MAAc,WAA4B;CACnE,MAAM,iBAAiB,UAAU,IAAI;CACrC,MAAM,sBAAsB,UAAU,SAAS;CAC/C,OACE,wBAAwB,kBACxB,oBAAoB,WAAW,iBAAiB,GAAG,KACnD,oBAAoB,WAAW,GAAG,eAAe,EAAE;AAEvD;;AAGA,SAAgB,gBAAgB,MAAc,WAA4B;CACxE,MAAM,SAAS,UAAU,KAAK,MAAM,SAAS,CAAC;CAC9C,OAAO,WAAW,QAAQ,CAAC,OAAO,WAAW,UAAU,IAAI,IAAI,GAAG;AACpE"}
1
+ {"version":3,"file":"path-security.mjs","names":[],"sources":["../../src/utils/path-security.ts"],"sourcesContent":["import { join, normalize, sep } from \"node:path\";\n\n/** Whether a path segment is safe (no traversal). */\nexport function isSafeSegment(segment: string): boolean {\n return (\n segment !== \"..\" &&\n !segment.startsWith(\"/\") &&\n !segment.includes(\"\\\\\") &&\n !segment.includes(\"..\")\n );\n}\n\n/** Whether joining root with candidate stays inside root (no traversal). */\nexport function isPathSafe(root: string, candidate: string): boolean {\n const normalizedRoot = normalize(root);\n const normalizedCandidate = normalize(candidate);\n return (\n normalizedCandidate === normalizedRoot ||\n normalizedCandidate.startsWith(normalizedRoot + sep) ||\n normalizedCandidate.startsWith(`${normalizedRoot}/`)\n );\n}\n\n/** Check if a path built from root + entry would escape root (for zip extraction). */\nexport function isBlockedTarget(root: string, entryPath: string): boolean {\n const target = normalize(join(root, entryPath));\n return target !== root && !target.startsWith(normalize(root) + sep);\n}\n"],"mappings":";;;;;AAGA,SAAgB,cAAc,SAA0B;CACtD,OACE,YAAY,QACZ,CAAC,QAAQ,WAAW,GAAG,KACvB,CAAC,QAAQ,SAAS,IAAI,KACtB,CAAC,QAAQ,SAAS,IAAI;AAE1B;;AAGA,SAAgB,WAAW,MAAc,WAA4B;CACnE,MAAM,iBAAiB,UAAU,IAAI;CACrC,MAAM,sBAAsB,UAAU,SAAS;CAC/C,OACE,wBAAwB,kBACxB,oBAAoB,WAAW,iBAAiB,GAAG,KACnD,oBAAoB,WAAW,GAAG,eAAe,EAAE;AAEvD;;AAGA,SAAgB,gBAAgB,MAAc,WAA4B;CACxE,MAAM,SAAS,UAAU,KAAK,MAAM,SAAS,CAAC;CAC9C,OAAO,WAAW,QAAQ,CAAC,OAAO,WAAW,UAAU,IAAI,IAAI,GAAG;AACpE"}
@@ -0,0 +1,18 @@
1
+ import __tsdown_shims_path from 'node:path';
2
+ import __tsdown_shims_url from 'node:url';
3
+ /** Finding the address a deployment is reached at without being told (ADR 0007, decision 6). */
4
+ /** Environment variables, as `process.env` has them. */
5
+ type Env = Readonly<Record<string, string | undefined>>;
6
+ /**
7
+ * The origin (`scheme://host[:port]`) of `value`, or `undefined` when it is not an http(s) URL
8
+ * without credentials. A bare host (`app.example.com`), as platforms often publish, reads as https.
9
+ */
10
+ declare function normalizeOrigin(value?: string): string | undefined;
11
+ /**
12
+ * The address the hosting platform publishes in `env`, as an origin, or `undefined` when none is
13
+ * set. It is the platform's own domain, a working fallback but the wrong link behind a custom
14
+ * domain. Cloud Run, AWS App Runner, Lambda function URLs and Cloudflare Workers publish nothing.
15
+ */
16
+ declare function detectPublicBaseUrl(env: Env): string | undefined;
17
+ export { Env, detectPublicBaseUrl, normalizeOrigin };
18
+ //# sourceMappingURL=public-origin.d.mts.map
@@ -0,0 +1,74 @@
1
+ import "node:path";
2
+ import "node:url";
3
+ import.meta.url;
4
+ // src/utils/public-origin.ts
5
+ /**
6
+ * The origin (`scheme://host[:port]`) of `value`, or `undefined` when it is not an http(s) URL
7
+ * without credentials. A bare host (`app.example.com`), as platforms often publish, reads as https.
8
+ */
9
+ function normalizeOrigin(value) {
10
+ const text = value?.trim();
11
+ if (!text) return;
12
+ if (/^[a-z][a-z\d+.-]*:(?!\/\/|\d+(?:\/|$))/iu.test(text)) return;
13
+ try {
14
+ const url = new URL(/^[a-z][a-z\d+.-]*:\/\//iu.test(text) ? text : `https://${text}`);
15
+ return (url.protocol === "https:" || url.protocol === "http:") && url.username === "" && url.password === "" && url.hostname !== "" ? url.origin : void 0;
16
+ } catch {
17
+ return;
18
+ }
19
+ }
20
+ const PLATFORMS = [
21
+ { address: ["HEROKU_APP_DEFAULT_DOMAIN_NAME"] },
22
+ { address: ["RAILWAY_PUBLIC_DOMAIN"] },
23
+ {
24
+ marker: ["VERCEL", "1"],
25
+ address: ["VERCEL_PROJECT_PRODUCTION_URL", "VERCEL_URL"]
26
+ },
27
+ {
28
+ marker: ["NETLIFY", "true"],
29
+ address: ["URL", "DEPLOY_PRIME_URL"]
30
+ },
31
+ { address: ["RENDER_EXTERNAL_URL", "RENDER_EXTERNAL_HOSTNAME"] },
32
+ { address: ["WEBSITE_HOSTNAME"] },
33
+ {
34
+ marker: ["DIGITALOCEAN_APP_ID"],
35
+ address: ["APP_URL"]
36
+ }
37
+ ];
38
+ /**
39
+ * The address the hosting platform publishes in `env`, as an origin, or `undefined` when none is
40
+ * set. It is the platform's own domain, a working fallback but the wrong link behind a custom
41
+ * domain. Cloud Run, AWS App Runner, Lambda function URLs and Cloudflare Workers publish nothing.
42
+ */
43
+ function detectPublicBaseUrl(env) {
44
+ for (const platform of PLATFORMS) {
45
+ const found = fromPlatform(platform, env);
46
+ if (found !== void 0) return found;
47
+ }
48
+ return fromFly(env) ?? fromContainerApps(env);
49
+ }
50
+ function fromPlatform(platform, env) {
51
+ if (platform.marker !== void 0) {
52
+ const [name, expected] = platform.marker;
53
+ const actual = env[name];
54
+ if (actual === void 0 || actual === "" || expected !== void 0 && actual !== expected) return;
55
+ }
56
+ for (const name of platform.address) {
57
+ const origin = normalizeOrigin(env[name]);
58
+ if (origin !== void 0) return origin;
59
+ }
60
+ }
61
+ /** Fly.io: `<app>.fly.dev`. */
62
+ function fromFly(env) {
63
+ const app = env["FLY_APP_NAME"];
64
+ return app ? normalizeOrigin(`${app}.fly.dev`) : void 0;
65
+ }
66
+ /** Azure Container Apps: `<app>.<environment DNS suffix>`. */
67
+ function fromContainerApps(env) {
68
+ const app = env["CONTAINER_APP_NAME"];
69
+ const suffix = env["CONTAINER_APP_ENV_DNS_SUFFIX"];
70
+ return app && suffix ? normalizeOrigin(`${app}.${suffix}`) : void 0;
71
+ }
72
+ export { detectPublicBaseUrl, normalizeOrigin };
73
+
74
+ //# sourceMappingURL=public-origin.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"public-origin.mjs","names":[],"sources":["../../src/utils/public-origin.ts"],"sourcesContent":["/** Finding the address a deployment is reached at without being told (ADR 0007, decision 6). */\n\n/** Environment variables, as `process.env` has them. */\nexport type Env = Readonly<Record<string, string | undefined>>;\n\n/**\n * The origin (`scheme://host[:port]`) of `value`, or `undefined` when it is not an http(s) URL\n * without credentials. A bare host (`app.example.com`), as platforms often publish, reads as https.\n */\nexport function normalizeOrigin(value?: string): string | undefined {\n const text = value?.trim();\n if (!text) {\n return undefined;\n }\n // `javascript:alert(1)`, `mailto:x`: a scheme with no `//` is no address (`host:8443` is).\n if (/^[a-z][a-z\\d+.-]*:(?!\\/\\/|\\d+(?:\\/|$))/iu.test(text)) {\n return undefined;\n }\n try {\n const url = new URL(/^[a-z][a-z\\d+.-]*:\\/\\//iu.test(text) ? text : `https://${text}`);\n const web = url.protocol === \"https:\" || url.protocol === \"http:\";\n return web && url.username === \"\" && url.password === \"\" && url.hostname !== \"\"\n ? url.origin\n : undefined;\n } catch {\n return undefined;\n }\n}\n\n/** One platform: the variables that say its address, tried in order. */\ninterface Platform {\n /** Variable whose presence says the app runs there; absent when the address variable alone says so. */\n marker?: readonly [string, string?];\n /** Variables holding a host or URL, first set one wins. */\n address: readonly string[];\n}\n\nconst PLATFORMS: readonly Platform[] = [\n // Heroku: needs the `runtime-dyno-metadata` Labs feature.\n { address: [\"HEROKU_APP_DEFAULT_DOMAIN_NAME\"] },\n // Railway: only when the service has a public domain.\n { address: [\"RAILWAY_PUBLIC_DOMAIN\"] },\n // Vercel: the production alias beats the per-deployment URL.\n { marker: [\"VERCEL\", \"1\"], address: [\"VERCEL_PROJECT_PRODUCTION_URL\", \"VERCEL_URL\"] },\n // Netlify: `URL` is the site's main URL (a generic name, so it needs the platform marker).\n { marker: [\"NETLIFY\", \"true\"], address: [\"URL\", \"DEPLOY_PRIME_URL\"] },\n // Render.\n { address: [\"RENDER_EXTERNAL_URL\", \"RENDER_EXTERNAL_HOSTNAME\"] },\n // Azure App Service.\n { address: [\"WEBSITE_HOSTNAME\"] },\n // DigitalOcean App Platform: `APP_URL` is a bindable variable the app spec must set.\n { marker: [\"DIGITALOCEAN_APP_ID\"], address: [\"APP_URL\"] },\n];\n\n/**\n * The address the hosting platform publishes in `env`, as an origin, or `undefined` when none is\n * set. It is the platform's own domain, a working fallback but the wrong link behind a custom\n * domain. Cloud Run, AWS App Runner, Lambda function URLs and Cloudflare Workers publish nothing.\n */\nexport function detectPublicBaseUrl(env: Env): string | undefined {\n for (const platform of PLATFORMS) {\n const found = fromPlatform(platform, env);\n if (found !== undefined) {\n return found;\n }\n }\n return fromFly(env) ?? fromContainerApps(env);\n}\n\nfunction fromPlatform(platform: Platform, env: Env): string | undefined {\n if (platform.marker !== undefined) {\n const [name, expected] = platform.marker;\n const actual = env[name];\n if (actual === undefined || actual === \"\" || (expected !== undefined && actual !== expected)) {\n return undefined;\n }\n }\n for (const name of platform.address) {\n const origin = normalizeOrigin(env[name]);\n if (origin !== undefined) {\n return origin;\n }\n }\n return undefined;\n}\n\n/** Fly.io: `<app>.fly.dev`. */\nfunction fromFly(env: Env): string | undefined {\n const app = env[\"FLY_APP_NAME\"];\n return app ? normalizeOrigin(`${app}.fly.dev`) : undefined;\n}\n\n/** Azure Container Apps: `<app>.<environment DNS suffix>`. */\nfunction fromContainerApps(env: Env): string | undefined {\n const app = env[\"CONTAINER_APP_NAME\"];\n const suffix = env[\"CONTAINER_APP_ENV_DNS_SUFFIX\"];\n return app && suffix ? normalizeOrigin(`${app}.${suffix}`) : undefined;\n}\n"],"mappings":";;;;;;;;AASA,SAAgB,gBAAgB,OAAoC;CAClE,MAAM,OAAO,OAAO,KAAK;CACzB,IAAI,CAAC,MACH;CAGF,IAAI,2CAA2C,KAAK,IAAI,GACtD;CAEF,IAAI;EACF,MAAM,MAAM,IAAI,IAAI,2BAA2B,KAAK,IAAI,IAAI,OAAO,WAAW,MAAM;EAEpF,QADY,IAAI,aAAa,YAAY,IAAI,aAAa,YAC5C,IAAI,aAAa,MAAM,IAAI,aAAa,MAAM,IAAI,aAAa,KACzE,IAAI,SACJ,KAAA;CACN,QAAQ;EACN;CACF;AACF;AAUA,MAAM,YAAiC;CAErC,EAAE,SAAS,CAAC,gCAAgC,EAAE;CAE9C,EAAE,SAAS,CAAC,uBAAuB,EAAE;CAErC;EAAE,QAAQ,CAAC,UAAU,GAAG;EAAG,SAAS,CAAC,iCAAiC,YAAY;CAAE;CAEpF;EAAE,QAAQ,CAAC,WAAW,MAAM;EAAG,SAAS,CAAC,OAAO,kBAAkB;CAAE;CAEpE,EAAE,SAAS,CAAC,uBAAuB,0BAA0B,EAAE;CAE/D,EAAE,SAAS,CAAC,kBAAkB,EAAE;CAEhC;EAAE,QAAQ,CAAC,qBAAqB;EAAG,SAAS,CAAC,SAAS;CAAE;AAC1D;;;;;;AAOA,SAAgB,oBAAoB,KAA8B;CAChE,KAAK,MAAM,YAAY,WAAW;EAChC,MAAM,QAAQ,aAAa,UAAU,GAAG;EACxC,IAAI,UAAU,KAAA,GACZ,OAAO;CAEX;CACA,OAAO,QAAQ,GAAG,KAAK,kBAAkB,GAAG;AAC9C;AAEA,SAAS,aAAa,UAAoB,KAA8B;CACtE,IAAI,SAAS,WAAW,KAAA,GAAW;EACjC,MAAM,CAAC,MAAM,YAAY,SAAS;EAClC,MAAM,SAAS,IAAI;EACnB,IAAI,WAAW,KAAA,KAAa,WAAW,MAAO,aAAa,KAAA,KAAa,WAAW,UACjF;CAEJ;CACA,KAAK,MAAM,QAAQ,SAAS,SAAS;EACnC,MAAM,SAAS,gBAAgB,IAAI,KAAK;EACxC,IAAI,WAAW,KAAA,GACb,OAAO;CAEX;AAEF;;AAGA,SAAS,QAAQ,KAA8B;CAC7C,MAAM,MAAM,IAAI;CAChB,OAAO,MAAM,gBAAgB,GAAG,IAAI,SAAS,IAAI,KAAA;AACnD;;AAGA,SAAS,kBAAkB,KAA8B;CACvD,MAAM,MAAM,IAAI;CAChB,MAAM,SAAS,IAAI;CACnB,OAAO,OAAO,SAAS,gBAAgB,GAAG,IAAI,GAAG,QAAQ,IAAI,KAAA;AAC/D"}
@@ -1,6 +1,5 @@
1
1
  import __tsdown_shims_path from 'node:path';
2
2
  import __tsdown_shims_url from 'node:url';
3
- //#region src/utils/redact.d.ts
4
3
  /**
5
4
  * Secret redaction for adapter errors, health details, and logs.
6
5
  *
@@ -12,6 +11,5 @@ import __tsdown_shims_url from 'node:url';
12
11
  declare function redactSecrets(text: string): string;
13
12
  /** Redact secrets, then truncate to `maxLength`. */
14
13
  declare function sanitizeErrorText(text: string, maxLength: number): string;
15
- //#endregion
16
14
  export { redactSecrets, sanitizeErrorText };
17
15
  //# sourceMappingURL=redact.d.mts.map
@@ -1,7 +1,8 @@
1
1
  import "node:path";
2
2
  import "node:url";
3
3
  import.meta.url;
4
- //#region src/utils/redact.ts
4
+ import { STORYBOOK_TOKEN_PREFIX, STORYBOOK_TOKEN_SOURCE } from "./storybook-token.mjs";
5
+ // src/utils/redact.ts
5
6
  /**
6
7
  * Secret redaction for adapter errors, health details, and logs.
7
8
  *
@@ -13,10 +14,12 @@ const SECRET_PATTERNS = [
13
14
  /(:\/\/)[^/\s:]+:[^/\s@]+(?=@)/u,
14
15
  /([?&#](?:token|secret|password|api[_-]?key|auth[_-]?token|access[_-]?key)=)[^&#\s]*/giu,
15
16
  /((?:password|passwd|secret|token|api[_-]?key|auth[_-]?token|client[_-]?secret|access[_-]?key|private[_-]?key)\s*[:=]\s*['"]?)[^\s'";,[\]&]+/giu,
17
+ new RegExp(`(${STORYBOOK_TOKEN_PREFIX})${STORYBOOK_TOKEN_SOURCE}`, "gu"),
16
18
  /AKIA[0-9A-Z]{16}/gu,
17
19
  /gh[pous]_[A-Za-z0-9_]+/gu,
18
20
  /github_pat_[A-Za-z0-9_]+/gu,
19
21
  /xox[bpasr]-[A-Za-z0-9-]+/gu,
22
+ /eyJ[\w-]{8,}\.eyJ[\w-]{8,}\.[\w-]+/gu,
20
23
  /-----BEGIN [A-Z ]*PRIVATE KEY-----[\s\S]*?-----END [A-Z ]*PRIVATE KEY-----/gu
21
24
  ];
22
25
  /** Replace embedded secrets with `[redacted]`. Never throws on weird input. */
@@ -36,7 +39,6 @@ function sanitizeErrorText(text, maxLength) {
36
39
  const redacted = redactSecrets(text);
37
40
  return redacted.length > maxLength ? redacted.slice(0, maxLength) : redacted;
38
41
  }
39
- //#endregion
40
42
  export { redactSecrets, sanitizeErrorText };
41
43
 
42
44
  //# sourceMappingURL=redact.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"redact.mjs","names":[],"sources":["../../src/utils/redact.ts"],"sourcesContent":["/**\n * Secret redaction for adapter errors, health details, and logs.\n *\n * Adapter-thrown messages routinely embed connection strings and tokens.\n * Every surface that exposes adapter text (503 gate, health report, error\n * logs) must pass through here before truncation or transport.\n */\n\nconst SECRET_PATTERNS: RegExp[] = [\n /(:\\/\\/)[^/\\s:]+:[^/\\s@]+(?=@)/u,\n /([?&#](?:token|secret|password|api[_-]?key|auth[_-]?token|access[_-]?key)=)[^&#\\s]*/giu,\n /((?:password|passwd|secret|token|api[_-]?key|auth[_-]?token|client[_-]?secret|access[_-]?key|private[_-]?key)\\s*[:=]\\s*['\"]?)[^\\s'\";,[\\]&]+/giu,\n /AKIA[0-9A-Z]{16}/gu,\n /gh[pous]_[A-Za-z0-9_]+/gu,\n /github_pat_[A-Za-z0-9_]+/gu,\n /xox[bpasr]-[A-Za-z0-9-]+/gu,\n /-----BEGIN [A-Z ]*PRIVATE KEY-----[\\s\\S]*?-----END [A-Z ]*PRIVATE KEY-----/gu,\n];\n\n/** Replace embedded secrets with `[redacted]`. Never throws on weird input. */\nexport function redactSecrets(text: string): string {\n let redacted = text;\n for (const pattern of SECRET_PATTERNS) {\n pattern.lastIndex = 0;\n redacted = redacted.replace(pattern, (...args: unknown[]) => {\n const group = args[1];\n return typeof group === \"string\" ? `${group}[redacted]` : \"[redacted]\";\n });\n }\n return redacted;\n}\n\n/** Redact secrets, then truncate to `maxLength`. */\nexport function sanitizeErrorText(text: string, maxLength: number): string {\n const redacted = redactSecrets(text);\n return redacted.length > maxLength ? redacted.slice(0, maxLength) : redacted;\n}\n"],"mappings":";;;;;;;;;;;AAQA,MAAM,kBAA4B;CAChC;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF;;AAGA,SAAgB,cAAc,MAAsB;CAClD,IAAI,WAAW;CACf,KAAK,MAAM,WAAW,iBAAiB;EACrC,QAAQ,YAAY;EACpB,WAAW,SAAS,QAAQ,UAAU,GAAG,SAAoB;GAC3D,MAAM,QAAQ,KAAK;GACnB,OAAO,OAAO,UAAU,WAAW,GAAG,MAAM,cAAc;EAC5D,CAAC;CACH;CACA,OAAO;AACT;;AAGA,SAAgB,kBAAkB,MAAc,WAA2B;CACzE,MAAM,WAAW,cAAc,IAAI;CACnC,OAAO,SAAS,SAAS,YAAY,SAAS,MAAM,GAAG,SAAS,IAAI;AACtE"}
1
+ {"version":3,"file":"redact.mjs","names":[],"sources":["../../src/utils/redact.ts"],"sourcesContent":["/**\n * Secret redaction for adapter errors, health details, and logs.\n *\n * Adapter-thrown messages routinely embed connection strings and tokens.\n * Every surface that exposes adapter text (503 gate, health report, error\n * logs) must pass through here before truncation or transport.\n */\n\nimport { STORYBOOK_TOKEN_PREFIX, STORYBOOK_TOKEN_SOURCE } from \"./storybook-token.ts\";\n\nconst SECRET_PATTERNS: RegExp[] = [\n /(:\\/\\/)[^/\\s:]+:[^/\\s@]+(?=@)/u,\n /([?&#](?:token|secret|password|api[_-]?key|auth[_-]?token|access[_-]?key)=)[^&#\\s]*/giu,\n /((?:password|passwd|secret|token|api[_-]?key|auth[_-]?token|client[_-]?secret|access[_-]?key|private[_-]?key)\\s*[:=]\\s*['\"]?)[^\\s'\";,[\\]&]+/giu,\n new RegExp(`(${STORYBOOK_TOKEN_PREFIX})${STORYBOOK_TOKEN_SOURCE}`, \"gu\"),\n /AKIA[0-9A-Z]{16}/gu,\n /gh[pous]_[A-Za-z0-9_]+/gu,\n /github_pat_[A-Za-z0-9_]+/gu,\n /xox[bpasr]-[A-Za-z0-9-]+/gu,\n /eyJ[\\w-]{8,}\\.eyJ[\\w-]{8,}\\.[\\w-]+/gu,\n /-----BEGIN [A-Z ]*PRIVATE KEY-----[\\s\\S]*?-----END [A-Z ]*PRIVATE KEY-----/gu,\n];\n\n/** Replace embedded secrets with `[redacted]`. Never throws on weird input. */\nexport function redactSecrets(text: string): string {\n let redacted = text;\n for (const pattern of SECRET_PATTERNS) {\n pattern.lastIndex = 0;\n redacted = redacted.replace(pattern, (...args: unknown[]) => {\n const group = args[1];\n return typeof group === \"string\" ? `${group}[redacted]` : \"[redacted]\";\n });\n }\n return redacted;\n}\n\n/** Redact secrets, then truncate to `maxLength`. */\nexport function sanitizeErrorText(text: string, maxLength: number): string {\n const redacted = redactSecrets(text);\n return redacted.length > maxLength ? redacted.slice(0, maxLength) : redacted;\n}\n"],"mappings":";;;;;;;;;;;;AAUA,MAAM,kBAA4B;CAChC;CACA;CACA;CACA,IAAI,OAAO,IAAI,uBAAuB,GAAG,0BAA0B,IAAI;CACvE;CACA;CACA;CACA;CACA;CACA;AACF;;AAGA,SAAgB,cAAc,MAAsB;CAClD,IAAI,WAAW;CACf,KAAK,MAAM,WAAW,iBAAiB;EACrC,QAAQ,YAAY;EACpB,WAAW,SAAS,QAAQ,UAAU,GAAG,SAAoB;GAC3D,MAAM,QAAQ,KAAK;GACnB,OAAO,OAAO,UAAU,WAAW,GAAG,MAAM,cAAc;EAC5D,CAAC;CACH;CACA,OAAO;AACT;;AAGA,SAAgB,kBAAkB,MAAc,WAA2B;CACzE,MAAM,WAAW,cAAc,IAAI;CACnC,OAAO,SAAS,SAAS,YAAY,SAAS,MAAM,GAAG,SAAS,IAAI;AACtE"}
@@ -0,0 +1,76 @@
1
+ import __tsdown_shims_path from 'node:path';
2
+ import __tsdown_shims_url from 'node:url';
3
+ import { CaptureEnvironment } from "../adapter/capture-runner.mjs";
4
+ /** What the probe page reports. */
5
+ interface BrowserProbe {
6
+ /** OS as the page sees it (`navigator.userAgentData.platform`, else `navigator.platform`). */
7
+ platform?: string;
8
+ deviceScaleFactor?: number;
9
+ /** Which of {@link FONT_PROBE_FAMILIES} are installed. */
10
+ fonts?: string[];
11
+ }
12
+ /**
13
+ * Families probed for the fonts digest: system fonts that differ between operating systems and
14
+ * image builds, so a provider-side change moves the hash. A fixed list; changing it re-baselines
15
+ * every remote target's fingerprint.
16
+ */
17
+ declare const FONT_PROBE_FAMILIES: readonly string[];
18
+ /**
19
+ * Read the OS, the device pixel ratio and the installed probe fonts. Runs inside the page, so it
20
+ * must stay one self-contained function (no imports, no closures): the runners pass it to
21
+ * `page.evaluate`, which sends its source. A font counts as installed when text in it measures
22
+ * differently from the generic family it would fall back to; `document.fonts.check` answers `true`
23
+ * for a family that does not exist, so it cannot tell.
24
+ */
25
+ declare function inPageProbe(families: string[]): BrowserProbe;
26
+ /** How a {@link boundedProbe} ended. */
27
+ type ProbeOutcome<T> = {
28
+ status: "done";
29
+ value: T;
30
+ } |
31
+ /** Still running after `timeoutMs`: the environment is unknown, the run goes on. */
32
+ {
33
+ status: "timeout";
34
+ } |
35
+ /** The run was cancelled: the run stops, it is never read as "unknown environment". */
36
+ {
37
+ status: "cancelled";
38
+ } |
39
+ /** The probe threw (a service outage, a page that would not open): unknown, with a warning. */
40
+ {
41
+ status: "failed";
42
+ error: unknown;
43
+ };
44
+ /** What a probe's work can ask about its own fate. */
45
+ interface ProbeControl {
46
+ /**
47
+ * True once the probe timed out or was cancelled. Work that opens a page must check it after
48
+ * every await and release what it opened, because nothing waits for it any more.
49
+ */
50
+ stopped: () => boolean;
51
+ }
52
+ /**
53
+ * Run probe work under a time limit and a cancel signal (ADR 0007, decision 2). A probe that hangs
54
+ * on an unresponsive service must not hold a render, and a cancel must interrupt it instead of
55
+ * waiting for the service. The work is never awaited past the limit and never leaves an unhandled
56
+ * rejection; releasing the page it opened is the caller's job (`ProbeControl.stopped`, or closing
57
+ * what it holds once this returns). A failure after the signal fired reads as cancelled, since
58
+ * closing the browser is how a cancel interrupts it.
59
+ */
60
+ declare function boundedProbe<T>(options: {
61
+ run: (control: ProbeControl) => Promise<T>;
62
+ timeoutMs: number;
63
+ signal?: AbortSignal | undefined;
64
+ }): Promise<ProbeOutcome<T>>;
65
+ /**
66
+ * The environment of a remote render: the driver's browser version and what the page reported. A
67
+ * field the page could not give is left out, except the OS, which falls back to what the service
68
+ * was configured to render on; an unknown fingerprint component is never a change (ADR 0005).
69
+ */
70
+ declare function remoteEnvironment(options: {
71
+ browserVersion?: string | undefined;
72
+ probe?: BrowserProbe | undefined;
73
+ declaredPlatform?: string | undefined;
74
+ }): CaptureEnvironment;
75
+ export { BrowserProbe, FONT_PROBE_FAMILIES, ProbeControl, ProbeOutcome, boundedProbe, inPageProbe, remoteEnvironment };
76
+ //# sourceMappingURL=remote-environment.d.mts.map
@@ -0,0 +1,163 @@
1
+ import "node:path";
2
+ import "node:url";
3
+ import.meta.url;
4
+ import { sha256 } from "./hash.mjs";
5
+ // src/utils/remote-environment.ts
6
+ /**
7
+ * Families probed for the fonts digest: system fonts that differ between operating systems and
8
+ * image builds, so a provider-side change moves the hash. A fixed list; changing it re-baselines
9
+ * every remote target's fingerprint.
10
+ */
11
+ const FONT_PROBE_FAMILIES = [
12
+ "Arial",
13
+ "Helvetica",
14
+ "Helvetica Neue",
15
+ "Times New Roman",
16
+ "Georgia",
17
+ "Verdana",
18
+ "Tahoma",
19
+ "Trebuchet MS",
20
+ "Courier New",
21
+ "Consolas",
22
+ "Menlo",
23
+ "Monaco",
24
+ "Segoe UI",
25
+ "Calibri",
26
+ "Cambria",
27
+ "San Francisco",
28
+ "SF Pro Text",
29
+ "Lucida Grande",
30
+ "Roboto",
31
+ "Open Sans",
32
+ "Noto Sans",
33
+ "Noto Serif",
34
+ "Noto Sans Mono",
35
+ "Noto Color Emoji",
36
+ "Apple Color Emoji",
37
+ "Segoe UI Emoji",
38
+ "DejaVu Sans",
39
+ "DejaVu Serif",
40
+ "DejaVu Sans Mono",
41
+ "Liberation Sans",
42
+ "Liberation Serif",
43
+ "Liberation Mono",
44
+ "Ubuntu",
45
+ "Cantarell",
46
+ "Droid Sans",
47
+ "Source Sans Pro",
48
+ "Fira Sans",
49
+ "Inter",
50
+ "Arial Unicode MS",
51
+ "MS Gothic",
52
+ "Hiragino Sans",
53
+ "PingFang SC",
54
+ "Microsoft YaHei",
55
+ "Malgun Gothic"
56
+ ];
57
+ /**
58
+ * Read the OS, the device pixel ratio and the installed probe fonts. Runs inside the page, so it
59
+ * must stay one self-contained function (no imports, no closures): the runners pass it to
60
+ * `page.evaluate`, which sends its source. A font counts as installed when text in it measures
61
+ * differently from the generic family it would fall back to; `document.fonts.check` answers `true`
62
+ * for a family that does not exist, so it cannot tell.
63
+ */
64
+ function inPageProbe(families) {
65
+ const win = globalThis;
66
+ const probe = {};
67
+ const reported = win.navigator.userAgentData?.platform;
68
+ const platform = reported === void 0 || reported === "" ? win.navigator.platform : reported;
69
+ if (platform) probe.platform = platform;
70
+ if (typeof win.devicePixelRatio === "number") probe.deviceScaleFactor = win.devicePixelRatio;
71
+ const context = win.document.createElement("canvas").getContext("2d");
72
+ if (!context) return probe;
73
+ const text = "mmmmmmmmmmlli1WwQqÅgy 漢字";
74
+ const generics = [
75
+ "monospace",
76
+ "sans-serif",
77
+ "serif"
78
+ ];
79
+ const widthOf = (font) => {
80
+ context.font = `72px ${font}`;
81
+ return context.measureText(text).width;
82
+ };
83
+ const baseline = generics.map((generic) => widthOf(generic));
84
+ probe.fonts = families.filter((family) => generics.some((generic, index) => widthOf(`"${family}", ${generic}`) !== baseline[index]));
85
+ return probe;
86
+ }
87
+ /**
88
+ * Run probe work under a time limit and a cancel signal (ADR 0007, decision 2). A probe that hangs
89
+ * on an unresponsive service must not hold a render, and a cancel must interrupt it instead of
90
+ * waiting for the service. The work is never awaited past the limit and never leaves an unhandled
91
+ * rejection; releasing the page it opened is the caller's job (`ProbeControl.stopped`, or closing
92
+ * what it holds once this returns). A failure after the signal fired reads as cancelled, since
93
+ * closing the browser is how a cancel interrupts it.
94
+ */
95
+ async function boundedProbe(options) {
96
+ const { signal, timeoutMs } = options;
97
+ if (signal?.aborted) return { status: "cancelled" };
98
+ const halt = { halted: false };
99
+ return await settle(options.run({ stopped: () => halt.halted }).then((value) => ({
100
+ status: "done",
101
+ value
102
+ }), (error) => ({
103
+ status: "failed",
104
+ error
105
+ })), limitOf(timeoutMs, signal), signal, halt);
106
+ }
107
+ /** Wait for the work or the limit, mark the work stopped if it lost, and drop the timer and listener. */
108
+ async function settle(work, limit, signal, halt) {
109
+ try {
110
+ const outcome = await Promise.race([work, limit.reached]);
111
+ halt.halted = outcome.status === "timeout" || outcome.status === "cancelled";
112
+ return outcome.status === "failed" && signal?.aborted ? { status: "cancelled" } : outcome;
113
+ } finally {
114
+ limit.clear();
115
+ }
116
+ }
117
+ /** A promise that settles on the timeout or the abort, and a way to drop both. */
118
+ function limitOf(timeoutMs, signal) {
119
+ let timer;
120
+ let onAbort;
121
+ return {
122
+ reached: new Promise((resolve) => {
123
+ timer = setTimeout(() => {
124
+ resolve({ status: "timeout" });
125
+ }, timeoutMs);
126
+ onAbort = () => {
127
+ resolve({ status: "cancelled" });
128
+ };
129
+ signal?.addEventListener("abort", onAbort, { once: true });
130
+ }),
131
+ clear: () => {
132
+ clearTimeout(timer);
133
+ if (onAbort) signal?.removeEventListener("abort", onAbort);
134
+ }
135
+ };
136
+ }
137
+ /**
138
+ * The environment of a remote render: the driver's browser version and what the page reported. A
139
+ * field the page could not give is left out, except the OS, which falls back to what the service
140
+ * was configured to render on; an unknown fingerprint component is never a change (ADR 0005).
141
+ */
142
+ function remoteEnvironment(options) {
143
+ const { probe, browserVersion } = options;
144
+ const platform = normalizePlatform(probe?.platform) ?? options.declaredPlatform;
145
+ const fonts = probe?.fonts;
146
+ return {
147
+ ...browserVersion ? { browserVersion } : {},
148
+ ...platform ? { platform } : {},
149
+ ...probe?.deviceScaleFactor ? { deviceScaleFactor: probe.deviceScaleFactor } : {},
150
+ ...fonts && fonts.length > 0 ? { fontsHash: sha256(fonts.toSorted().join("\n")).slice(0, 16) } : {}
151
+ };
152
+ }
153
+ /** `Win32`, `Windows` and `Linux x86_64` read as the OS, in one spelling per OS. */
154
+ function normalizePlatform(value) {
155
+ const text = value?.trim().toLowerCase();
156
+ if (!text) return;
157
+ if (text.startsWith("win")) return "windows";
158
+ if (text.startsWith("mac") || text === "iphone" || text === "ipad") return "macos";
159
+ return text.startsWith("linux") ? "linux" : text;
160
+ }
161
+ export { FONT_PROBE_FAMILIES, boundedProbe, inPageProbe, remoteEnvironment };
162
+
163
+ //# sourceMappingURL=remote-environment.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"remote-environment.mjs","names":[],"sources":["../../src/utils/remote-environment.ts"],"sourcesContent":["/**\n * The environment of a remote browser, measured inside it (ADR 0007, decision 2). `fc-list` and\n * `process.platform` describe the machine running the runner, not the one that rendered.\n */\nimport type { CaptureEnvironment } from \"../adapters/capture-runner.ts\";\nimport { sha256 } from \"./hash.ts\";\n\n/** What the probe page reports. */\nexport interface BrowserProbe {\n /** OS as the page sees it (`navigator.userAgentData.platform`, else `navigator.platform`). */\n platform?: string;\n deviceScaleFactor?: number;\n /** Which of {@link FONT_PROBE_FAMILIES} are installed. */\n fonts?: string[];\n}\n\n/**\n * Families probed for the fonts digest: system fonts that differ between operating systems and\n * image builds, so a provider-side change moves the hash. A fixed list; changing it re-baselines\n * every remote target's fingerprint.\n */\nexport const FONT_PROBE_FAMILIES: readonly string[] = [\n \"Arial\",\n \"Helvetica\",\n \"Helvetica Neue\",\n \"Times New Roman\",\n \"Georgia\",\n \"Verdana\",\n \"Tahoma\",\n \"Trebuchet MS\",\n \"Courier New\",\n \"Consolas\",\n \"Menlo\",\n \"Monaco\",\n \"Segoe UI\",\n \"Calibri\",\n \"Cambria\",\n \"San Francisco\",\n \"SF Pro Text\",\n \"Lucida Grande\",\n \"Roboto\",\n \"Open Sans\",\n \"Noto Sans\",\n \"Noto Serif\",\n \"Noto Sans Mono\",\n \"Noto Color Emoji\",\n \"Apple Color Emoji\",\n \"Segoe UI Emoji\",\n \"DejaVu Sans\",\n \"DejaVu Serif\",\n \"DejaVu Sans Mono\",\n \"Liberation Sans\",\n \"Liberation Serif\",\n \"Liberation Mono\",\n \"Ubuntu\",\n \"Cantarell\",\n \"Droid Sans\",\n \"Source Sans Pro\",\n \"Fira Sans\",\n \"Inter\",\n \"Arial Unicode MS\",\n \"MS Gothic\",\n \"Hiragino Sans\",\n \"PingFang SC\",\n \"Microsoft YaHei\",\n \"Malgun Gothic\",\n];\n\n/**\n * Read the OS, the device pixel ratio and the installed probe fonts. Runs inside the page, so it\n * must stay one self-contained function (no imports, no closures): the runners pass it to\n * `page.evaluate`, which sends its source. A font counts as installed when text in it measures\n * differently from the generic family it would fall back to; `document.fonts.check` answers `true`\n * for a family that does not exist, so it cannot tell.\n */\n// oxlint-disable-next-line eslint/max-statements, eslint/max-lines-per-function -- must stay one self-contained function (see above)\nexport function inPageProbe(families: string[]): BrowserProbe {\n const win = globalThis as unknown as {\n devicePixelRatio?: number;\n navigator: { userAgentData?: { platform?: string }; platform?: string };\n document: {\n createElement: (tag: string) => {\n getContext: (kind: string) => {\n font: string;\n measureText: (text: string) => { width: number };\n } | null;\n };\n };\n };\n const probe: BrowserProbe = {};\n const reported = win.navigator.userAgentData?.platform;\n const platform = reported === undefined || reported === \"\" ? win.navigator.platform : reported;\n if (platform) probe.platform = platform;\n if (typeof win.devicePixelRatio === \"number\") probe.deviceScaleFactor = win.devicePixelRatio;\n const context = win.document.createElement(\"canvas\").getContext(\"2d\");\n if (!context) return probe;\n const text = \"mmmmmmmmmmlli1WwQqÅgy 漢字\";\n const generics = [\"monospace\", \"sans-serif\", \"serif\"];\n const widthOf = (font: string): number => {\n context.font = `72px ${font}`;\n return context.measureText(text).width;\n };\n const baseline = generics.map((generic) => widthOf(generic));\n probe.fonts = families.filter((family) =>\n generics.some((generic, index) => widthOf(`\"${family}\", ${generic}`) !== baseline[index]),\n );\n return probe;\n}\n\n/** How a {@link boundedProbe} ended. */\nexport type ProbeOutcome<T> =\n | { status: \"done\"; value: T }\n /** Still running after `timeoutMs`: the environment is unknown, the run goes on. */\n | { status: \"timeout\" }\n /** The run was cancelled: the run stops, it is never read as \"unknown environment\". */\n | { status: \"cancelled\" }\n /** The probe threw (a service outage, a page that would not open): unknown, with a warning. */\n | { status: \"failed\"; error: unknown };\n\n/** What a probe's work can ask about its own fate. */\nexport interface ProbeControl {\n /**\n * True once the probe timed out or was cancelled. Work that opens a page must check it after\n * every await and release what it opened, because nothing waits for it any more.\n */\n stopped: () => boolean;\n}\n\n/**\n * Run probe work under a time limit and a cancel signal (ADR 0007, decision 2). A probe that hangs\n * on an unresponsive service must not hold a render, and a cancel must interrupt it instead of\n * waiting for the service. The work is never awaited past the limit and never leaves an unhandled\n * rejection; releasing the page it opened is the caller's job (`ProbeControl.stopped`, or closing\n * what it holds once this returns). A failure after the signal fired reads as cancelled, since\n * closing the browser is how a cancel interrupts it.\n */\nexport async function boundedProbe<T>(options: {\n run: (control: ProbeControl) => Promise<T>;\n timeoutMs: number;\n signal?: AbortSignal | undefined;\n}): Promise<ProbeOutcome<T>> {\n const { signal, timeoutMs } = options;\n if (signal?.aborted) {\n return { status: \"cancelled\" };\n }\n const halt = { halted: false };\n const work = options.run({ stopped: () => halt.halted }).then(\n (value): ProbeOutcome<T> => ({ status: \"done\", value }),\n (error: unknown): ProbeOutcome<T> => ({ status: \"failed\", error }),\n );\n return await settle(work, limitOf<T>(timeoutMs, signal), signal, halt);\n}\n\n/** Wait for the work or the limit, mark the work stopped if it lost, and drop the timer and listener. */\nasync function settle<T>(\n work: Promise<ProbeOutcome<T>>,\n limit: { reached: Promise<ProbeOutcome<T>>; clear: () => void },\n signal: AbortSignal | undefined,\n halt: { halted: boolean },\n): Promise<ProbeOutcome<T>> {\n try {\n const outcome = await Promise.race([work, limit.reached]);\n halt.halted = outcome.status === \"timeout\" || outcome.status === \"cancelled\";\n return outcome.status === \"failed\" && signal?.aborted ? { status: \"cancelled\" } : outcome;\n } finally {\n limit.clear();\n }\n}\n\n/** A promise that settles on the timeout or the abort, and a way to drop both. */\nfunction limitOf<T>(\n timeoutMs: number,\n signal: AbortSignal | undefined,\n): { reached: Promise<ProbeOutcome<T>>; clear: () => void } {\n let timer: ReturnType<typeof setTimeout> | undefined;\n let onAbort: (() => void) | undefined;\n const reached = new Promise<ProbeOutcome<T>>((resolve) => {\n timer = setTimeout(() => {\n resolve({ status: \"timeout\" });\n }, timeoutMs);\n onAbort = (): void => {\n resolve({ status: \"cancelled\" });\n };\n signal?.addEventListener(\"abort\", onAbort, { once: true });\n });\n return {\n reached,\n clear: (): void => {\n clearTimeout(timer);\n if (onAbort) signal?.removeEventListener(\"abort\", onAbort);\n },\n };\n}\n\n/**\n * The environment of a remote render: the driver's browser version and what the page reported. A\n * field the page could not give is left out, except the OS, which falls back to what the service\n * was configured to render on; an unknown fingerprint component is never a change (ADR 0005).\n */\nexport function remoteEnvironment(options: {\n browserVersion?: string | undefined;\n probe?: BrowserProbe | undefined;\n declaredPlatform?: string | undefined;\n}): CaptureEnvironment {\n const { probe, browserVersion } = options;\n const platform = normalizePlatform(probe?.platform) ?? options.declaredPlatform;\n const fonts = probe?.fonts;\n return {\n ...(browserVersion ? { browserVersion } : {}),\n ...(platform ? { platform } : {}),\n ...(probe?.deviceScaleFactor ? { deviceScaleFactor: probe.deviceScaleFactor } : {}),\n ...(fonts && fonts.length > 0\n ? { fontsHash: sha256(fonts.toSorted().join(\"\\n\")).slice(0, 16) }\n : {}),\n };\n}\n\n/** `Win32`, `Windows` and `Linux x86_64` read as the OS, in one spelling per OS. */\nfunction normalizePlatform(value: string | undefined): string | undefined {\n const text = value?.trim().toLowerCase();\n if (!text) {\n return undefined;\n }\n if (text.startsWith(\"win\")) return \"windows\";\n if (text.startsWith(\"mac\") || text === \"iphone\" || text === \"ipad\") return \"macos\";\n return text.startsWith(\"linux\") ? \"linux\" : text;\n}\n"],"mappings":";;;;;;;;;;AAqBA,MAAa,sBAAyC;CACpD;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF;;;;;;;;AAUA,SAAgB,YAAY,UAAkC;CAC5D,MAAM,MAAM;CAYZ,MAAM,QAAsB,CAAC;CAC7B,MAAM,WAAW,IAAI,UAAU,eAAe;CAC9C,MAAM,WAAW,aAAa,KAAA,KAAa,aAAa,KAAK,IAAI,UAAU,WAAW;CACtF,IAAI,UAAU,MAAM,WAAW;CAC/B,IAAI,OAAO,IAAI,qBAAqB,UAAU,MAAM,oBAAoB,IAAI;CAC5E,MAAM,UAAU,IAAI,SAAS,cAAc,QAAQ,CAAC,CAAC,WAAW,IAAI;CACpE,IAAI,CAAC,SAAS,OAAO;CACrB,MAAM,OAAO;CACb,MAAM,WAAW;EAAC;EAAa;EAAc;CAAO;CACpD,MAAM,WAAW,SAAyB;EACxC,QAAQ,OAAO,QAAQ;EACvB,OAAO,QAAQ,YAAY,IAAI,CAAC,CAAC;CACnC;CACA,MAAM,WAAW,SAAS,KAAK,YAAY,QAAQ,OAAO,CAAC;CAC3D,MAAM,QAAQ,SAAS,QAAQ,WAC7B,SAAS,MAAM,SAAS,UAAU,QAAQ,IAAI,OAAO,KAAK,SAAS,MAAM,SAAS,MAAM,CAC1F;CACA,OAAO;AACT;;;;;;;;;AA6BA,eAAsB,aAAgB,SAIT;CAC3B,MAAM,EAAE,QAAQ,cAAc;CAC9B,IAAI,QAAQ,SACV,OAAO,EAAE,QAAQ,YAAY;CAE/B,MAAM,OAAO,EAAE,QAAQ,MAAM;CAK7B,OAAO,MAAM,OAJA,QAAQ,IAAI,EAAE,eAAe,KAAK,OAAO,CAAC,CAAC,CAAC,MACtD,WAA4B;EAAE,QAAQ;EAAQ;CAAM,KACpD,WAAqC;EAAE,QAAQ;EAAU;CAAM,EAE3C,GAAG,QAAW,WAAW,MAAM,GAAG,QAAQ,IAAI;AACvE;;AAGA,eAAe,OACb,MACA,OACA,QACA,MAC0B;CAC1B,IAAI;EACF,MAAM,UAAU,MAAM,QAAQ,KAAK,CAAC,MAAM,MAAM,OAAO,CAAC;EACxD,KAAK,SAAS,QAAQ,WAAW,aAAa,QAAQ,WAAW;EACjE,OAAO,QAAQ,WAAW,YAAY,QAAQ,UAAU,EAAE,QAAQ,YAAY,IAAI;CACpF,UAAU;EACR,MAAM,MAAM;CACd;AACF;;AAGA,SAAS,QACP,WACA,QAC0D;CAC1D,IAAI;CACJ,IAAI;CAUJ,OAAO;EACL,SAAA,IAVkB,SAA0B,YAAY;GACxD,QAAQ,iBAAiB;IACvB,QAAQ,EAAE,QAAQ,UAAU,CAAC;GAC/B,GAAG,SAAS;GACZ,gBAAsB;IACpB,QAAQ,EAAE,QAAQ,YAAY,CAAC;GACjC;GACA,QAAQ,iBAAiB,SAAS,SAAS,EAAE,MAAM,KAAK,CAAC;EAC3D,CAEQ;EACN,aAAmB;GACjB,aAAa,KAAK;GAClB,IAAI,SAAS,QAAQ,oBAAoB,SAAS,OAAO;EAC3D;CACF;AACF;;;;;;AAOA,SAAgB,kBAAkB,SAIX;CACrB,MAAM,EAAE,OAAO,mBAAmB;CAClC,MAAM,WAAW,kBAAkB,OAAO,QAAQ,KAAK,QAAQ;CAC/D,MAAM,QAAQ,OAAO;CACrB,OAAO;EACL,GAAI,iBAAiB,EAAE,eAAe,IAAI,CAAC;EAC3C,GAAI,WAAW,EAAE,SAAS,IAAI,CAAC;EAC/B,GAAI,OAAO,oBAAoB,EAAE,mBAAmB,MAAM,kBAAkB,IAAI,CAAC;EACjF,GAAI,SAAS,MAAM,SAAS,IACxB,EAAE,WAAW,OAAO,MAAM,SAAS,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC,MAAM,GAAG,EAAE,EAAE,IAC9D,CAAC;CACP;AACF;;AAGA,SAAS,kBAAkB,OAA+C;CACxE,MAAM,OAAO,OAAO,KAAK,CAAC,CAAC,YAAY;CACvC,IAAI,CAAC,MACH;CAEF,IAAI,KAAK,WAAW,KAAK,GAAG,OAAO;CACnC,IAAI,KAAK,WAAW,KAAK,KAAK,SAAS,YAAY,SAAS,QAAQ,OAAO;CAC3E,OAAO,KAAK,WAAW,OAAO,IAAI,UAAU;AAC9C"}
@@ -0,0 +1,62 @@
1
+ import __tsdown_shims_path from 'node:path';
2
+ import __tsdown_shims_url from 'node:url';
3
+ /** CPU and memory actually available to this process (container limits included). */
4
+ interface HostResources {
5
+ /** Fractional vCPUs: a cgroup quota of 0.5 CPU reports `0.5`. */
6
+ cpus: number;
7
+ memoryBytes: number;
8
+ }
9
+ /**
10
+ * Detect the CPU and memory budget. Container limits win over the host's: a
11
+ * 0.5 vCPU / 1 GB container on a large machine must be sized as 0.5 / 1 GB.
12
+ */
13
+ declare function detectResources(): HostResources;
14
+ /**
15
+ * Cost of one page in Chromium-page slots. Firefox and WebKit pages cost about twice a Chromium
16
+ * page in CPU time (ray.run cross-browser benchmarks: Firefox +71%, WebKit +60%; some Playwright
17
+ * reports show WebKit worse), so they get half the page budget. Takes a capture target too.
18
+ */
19
+ declare function engineWeight(browser?: string): number;
20
+ /**
21
+ * Pages to render at once: no more than the CPUs (extra pages only slow each
22
+ * other down and trip timeouts) and no more than memory allows. A heavier engine
23
+ * (see {@link engineWeight}) spends the same budget on fewer pages.
24
+ */
25
+ declare function recommendedPageConcurrency(resources?: HostResources, browser?: string): number;
26
+ /**
27
+ * Most pages the adaptive controller may reach: memory is a hard limit, but CPU is only a
28
+ * starting point (latency tells us when it is saturated), so allow up to twice the CPUs.
29
+ */
30
+ declare function maxPageConcurrency(resources?: HostResources, browser?: string): number;
31
+ /** Builds to capture at once: each launches its own browser, so only on roomy hosts. */
32
+ declare function recommendedBuildConcurrency(resources?: HostResources): number;
33
+ /** Playwright's 30 s default assumes a full CPU; starved containers parse the Storybook bundle slower. */
34
+ declare function recommendedNavigationTimeoutMs(resources?: HostResources): number;
35
+ /** Captures between browser restarts: Chromium grows slowly over a long run, so recycle it. */
36
+ declare const DEFAULT_RECYCLE_BROWSER_EVERY = 150;
37
+ /** Loggable summary of the host budget and the capture settings derived from it. */
38
+ declare function describeSizing(settings: {
39
+ browser?: string;
40
+ concurrency?: number;
41
+ navigationTimeoutMs?: number;
42
+ recycleBrowserEvery?: number;
43
+ }): Record<string, number>;
44
+ /** What capture will use on this host: detected resources and the effective concurrency. */
45
+ interface CaptureHostSummary {
46
+ cpus: number;
47
+ memoryMb: number;
48
+ /** Builds captured at once, and whether that was sized from the hardware or configured. */
49
+ builds: {
50
+ value: number;
51
+ auto: boolean;
52
+ };
53
+ /** Pages per build when the runner is not pinned: where it starts and the most it may reach (Chromium). */
54
+ pages: {
55
+ start: number;
56
+ max: number;
57
+ };
58
+ }
59
+ /** Summarise the host budget and effective capture concurrency, for the System page. */
60
+ declare function describeCaptureHost(configuredBuilds?: number, resources?: HostResources): CaptureHostSummary;
61
+ export { CaptureHostSummary, DEFAULT_RECYCLE_BROWSER_EVERY, HostResources, describeCaptureHost, describeSizing, detectResources, engineWeight, maxPageConcurrency, recommendedBuildConcurrency, recommendedNavigationTimeoutMs, recommendedPageConcurrency };
62
+ //# sourceMappingURL=resources.d.mts.map