@storyshelf/core 0.6.1 → 0.7.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 (631) hide show
  1. package/README.md +49 -32
  2. package/dist/adapter/capture-queue.d.mts +44 -2
  3. package/dist/adapter/capture-runner.d.mts +127 -10
  4. package/dist/adapter/capture-runner.mjs +5 -12
  5. package/dist/adapter/database.d.mts +27 -8
  6. package/dist/adapter/database.mjs.map +1 -1
  7. package/dist/adapter/design.d.mts +85 -0
  8. package/dist/adapter/design.mjs +28 -0
  9. package/dist/adapter/design.mjs.map +1 -0
  10. package/dist/adapter/metadata.d.mts +3 -10
  11. package/dist/adapter/notifier.d.mts +6 -3
  12. package/dist/adapter/notifier.mjs +5 -1
  13. package/dist/adapter/oauth.d.mts +52 -0
  14. package/dist/adapter/setup.d.mts +4 -5
  15. package/dist/adapter/setup.mjs +2 -1
  16. package/dist/adapter/setup.mjs.map +1 -1
  17. package/dist/adapter/webhook-events.mjs +1 -1
  18. package/dist/adapters/capture-target-offers.d.mts +28 -0
  19. package/dist/adapters/capture-target-offers.mjs +58 -0
  20. package/dist/adapters/capture-target-offers.mjs.map +1 -0
  21. package/dist/adapters/capture-target.d.mts +71 -0
  22. package/dist/adapters/capture-target.mjs +76 -0
  23. package/dist/adapters/capture-target.mjs.map +1 -0
  24. package/dist/adapters/notifier/build-comment.d.mts +24 -0
  25. package/dist/adapters/notifier/build-comment.mjs +24 -0
  26. package/dist/adapters/notifier/build-comment.mjs.map +1 -0
  27. package/dist/adapters/notifier/build-state.d.mts +99 -0
  28. package/dist/adapters/notifier/build-state.mjs +218 -0
  29. package/dist/adapters/notifier/build-state.mjs.map +1 -0
  30. package/dist/adapters/notifier/events.d.mts +4 -2
  31. package/dist/adapters/notifier/events.mjs +31 -18
  32. package/dist/adapters/notifier/events.mjs.map +1 -1
  33. package/dist/adapters/notifier/provider.d.mts +53 -7
  34. package/dist/adapters/notifier/provider.mjs +12 -0
  35. package/dist/adapters/notifier/provider.mjs.map +1 -0
  36. package/dist/adapters/notifier/state.d.mts +24 -0
  37. package/dist/adapters/notifier/state.mjs +66 -0
  38. package/dist/adapters/notifier/state.mjs.map +1 -0
  39. package/dist/adapters/notifier/types.d.mts +51 -2
  40. package/dist/adapters/remote-browser.d.mts +87 -0
  41. package/dist/adapters/remote-browser.mjs +103 -0
  42. package/dist/adapters/remote-browser.mjs.map +1 -0
  43. package/dist/adapters/render-runs.d.mts +25 -0
  44. package/dist/adapters/render-runs.mjs +41 -0
  45. package/dist/adapters/render-runs.mjs.map +1 -0
  46. package/dist/adapters/setup-runner.mjs +2 -4
  47. package/dist/adapters/setup-runner.mjs.map +1 -1
  48. package/dist/adapters/sources.d.mts +12 -0
  49. package/dist/adapters/sources.mjs +20 -0
  50. package/dist/adapters/sources.mjs.map +1 -0
  51. package/dist/adapters/validate.mjs +25 -18
  52. package/dist/adapters/validate.mjs.map +1 -1
  53. package/dist/ai.d.mts +105 -0
  54. package/dist/ai.mjs +19 -0
  55. package/dist/ai.mjs.map +1 -0
  56. package/dist/auth.d.mts +8 -1
  57. package/dist/auth.mjs +14 -1
  58. package/dist/auth.mjs.map +1 -0
  59. package/dist/capture/a11y/axe-source.d.mts +18 -0
  60. package/dist/capture/a11y/axe-source.mjs +37 -0
  61. package/dist/capture/a11y/axe-source.mjs.map +1 -0
  62. package/dist/capture/a11y/in-page.d.mts +27 -0
  63. package/dist/capture/a11y/in-page.mjs +60 -0
  64. package/dist/capture/a11y/in-page.mjs.map +1 -0
  65. package/dist/capture/a11y/map.d.mts +24 -0
  66. package/dist/capture/a11y/map.mjs +48 -0
  67. package/dist/capture/a11y/map.mjs.map +1 -0
  68. package/dist/capture/a11y/options.d.mts +23 -0
  69. package/dist/capture/a11y/options.mjs +75 -0
  70. package/dist/capture/a11y/options.mjs.map +1 -0
  71. package/dist/capture/adapter.d.mts +41 -3
  72. package/dist/capture/adapter.mjs.map +1 -1
  73. package/dist/capture/affected.d.mts +2 -0
  74. package/dist/capture/affected.mjs +13 -4
  75. package/dist/capture/affected.mjs.map +1 -1
  76. package/dist/capture/attempt-logger.mjs +84 -0
  77. package/dist/capture/attempt-logger.mjs.map +1 -0
  78. package/dist/capture/browsers.d.mts +35 -0
  79. package/dist/capture/browsers.mjs +67 -0
  80. package/dist/capture/browsers.mjs.map +1 -0
  81. package/dist/capture/build-state/deliver.d.mts +32 -0
  82. package/dist/capture/build-state/deliver.mjs +118 -0
  83. package/dist/capture/build-state/deliver.mjs.map +1 -0
  84. package/dist/capture/build-state/index.d.mts +8 -0
  85. package/dist/capture/build-state/notify-job.d.mts +56 -0
  86. package/dist/capture/build-state/notify-job.mjs +133 -0
  87. package/dist/capture/build-state/notify-job.mjs.map +1 -0
  88. package/dist/capture/build-state/publisher.d.mts +23 -0
  89. package/dist/capture/build-state/publisher.mjs +107 -0
  90. package/dist/capture/build-state/publisher.mjs.map +1 -0
  91. package/dist/capture/build-state/resume.d.mts +9 -0
  92. package/dist/capture/build-state/resume.mjs +47 -0
  93. package/dist/capture/build-state/resume.mjs.map +1 -0
  94. package/dist/capture/build-state/types.d.mts +49 -0
  95. package/dist/capture/catalog/catalogue.d.mts +22 -0
  96. package/dist/capture/catalog/catalogue.mjs +53 -0
  97. package/dist/capture/catalog/catalogue.mjs.map +1 -0
  98. package/dist/capture/catalog/components.d.mts +23 -0
  99. package/dist/capture/catalog/components.mjs +55 -0
  100. package/dist/capture/catalog/components.mjs.map +1 -0
  101. package/dist/capture/catalog/history.d.mts +30 -0
  102. package/dist/capture/catalog/history.mjs +51 -0
  103. package/dist/capture/catalog/history.mjs.map +1 -0
  104. package/dist/capture/catalog/hook.d.mts +14 -0
  105. package/dist/capture/catalog/hook.mjs +19 -0
  106. package/dist/capture/catalog/hook.mjs.map +1 -0
  107. package/dist/capture/catalog/index.d.mts +11 -0
  108. package/dist/capture/catalog/load.d.mts +26 -0
  109. package/dist/capture/catalog/load.mjs +49 -0
  110. package/dist/capture/catalog/load.mjs.map +1 -0
  111. package/dist/capture/catalog/parse.d.mts +15 -0
  112. package/dist/capture/catalog/parse.mjs +56 -0
  113. package/dist/capture/catalog/parse.mjs.map +1 -0
  114. package/dist/capture/catalog/read.d.mts +12 -0
  115. package/dist/capture/catalog/read.mjs +33 -0
  116. package/dist/capture/catalog/read.mjs.map +1 -0
  117. package/dist/capture/catalog/types.d.mts +33 -0
  118. package/dist/capture/consumer/capture-handler.d.mts +58 -0
  119. package/dist/capture/consumer/capture-handler.mjs +118 -0
  120. package/dist/capture/consumer/capture-handler.mjs.map +1 -0
  121. package/dist/capture/consumer/idle.d.mts +17 -0
  122. package/dist/capture/consumer/idle.mjs +25 -0
  123. package/dist/capture/consumer/idle.mjs.map +1 -0
  124. package/dist/capture/consumer/index.d.mts +13 -0
  125. package/dist/capture/consumer/index.mjs +139 -0
  126. package/dist/capture/consumer/index.mjs.map +1 -0
  127. package/dist/capture/consumer/loop.mjs +110 -0
  128. package/dist/capture/consumer/loop.mjs.map +1 -0
  129. package/dist/capture/consumer/metrics.d.mts +41 -0
  130. package/dist/capture/consumer/metrics.mjs +38 -0
  131. package/dist/capture/consumer/metrics.mjs.map +1 -0
  132. package/dist/capture/consumer/retry.d.mts +33 -0
  133. package/dist/capture/consumer/retry.mjs +34 -0
  134. package/dist/capture/consumer/retry.mjs.map +1 -0
  135. package/dist/capture/consumer/run-job.mjs +195 -0
  136. package/dist/capture/consumer/run-job.mjs.map +1 -0
  137. package/dist/capture/consumer/startup.mjs +38 -0
  138. package/dist/capture/consumer/startup.mjs.map +1 -0
  139. package/dist/capture/consumer/types.d.mts +97 -0
  140. package/dist/capture/crash-failure.d.mts +25 -0
  141. package/dist/capture/crash-failure.mjs +70 -0
  142. package/dist/capture/crash-failure.mjs.map +1 -0
  143. package/dist/capture/db-queue/cadence.d.mts +32 -0
  144. package/dist/capture/db-queue/cadence.mjs +38 -0
  145. package/dist/capture/db-queue/cadence.mjs.map +1 -0
  146. package/dist/capture/db-queue/claim.d.mts +9 -0
  147. package/dist/capture/db-queue/claim.mjs +132 -0
  148. package/dist/capture/db-queue/claim.mjs.map +1 -0
  149. package/dist/capture/db-queue/clock.mjs +12 -0
  150. package/dist/capture/db-queue/clock.mjs.map +1 -0
  151. package/dist/capture/db-queue/codec.mjs +76 -0
  152. package/dist/capture/db-queue/codec.mjs.map +1 -0
  153. package/dist/capture/db-queue/index.d.mts +20 -0
  154. package/dist/capture/db-queue/index.mjs +89 -0
  155. package/dist/capture/db-queue/index.mjs.map +1 -0
  156. package/dist/capture/db-queue/keeper.d.mts +36 -0
  157. package/dist/capture/db-queue/keeper.mjs +92 -0
  158. package/dist/capture/db-queue/keeper.mjs.map +1 -0
  159. package/dist/capture/db-queue/lease.mjs +46 -0
  160. package/dist/capture/db-queue/lease.mjs.map +1 -0
  161. package/dist/capture/db-queue/lifecycle.mjs +36 -0
  162. package/dist/capture/db-queue/lifecycle.mjs.map +1 -0
  163. package/dist/capture/db-queue/operations.mjs +94 -0
  164. package/dist/capture/db-queue/operations.mjs.map +1 -0
  165. package/dist/capture/db-queue/poll-loop.d.mts +30 -0
  166. package/dist/capture/db-queue/poll-loop.mjs +89 -0
  167. package/dist/capture/db-queue/poll-loop.mjs.map +1 -0
  168. package/dist/capture/db-queue/poll.d.mts +10 -0
  169. package/dist/capture/db-queue/poll.mjs +69 -0
  170. package/dist/capture/db-queue/poll.mjs.map +1 -0
  171. package/dist/capture/db-queue/timers.d.mts +12 -0
  172. package/dist/capture/db-queue/timers.mjs +37 -0
  173. package/dist/capture/db-queue/timers.mjs.map +1 -0
  174. package/dist/capture/db-queue/types.d.mts +83 -0
  175. package/dist/capture/db-queue/types.mjs +12 -0
  176. package/dist/capture/db-queue/types.mjs.map +1 -0
  177. package/dist/capture/db-queue/wake.mjs +48 -0
  178. package/dist/capture/db-queue/wake.mjs.map +1 -0
  179. package/dist/capture/design.mjs +39 -0
  180. package/dist/capture/design.mjs.map +1 -0
  181. package/dist/capture/diff-record.mjs +23 -3
  182. package/dist/capture/diff-record.mjs.map +1 -1
  183. package/dist/capture/dispatch.d.mts +12 -7
  184. package/dist/capture/dispatch.mjs +86 -107
  185. package/dist/capture/dispatch.mjs.map +1 -1
  186. package/dist/capture/enrich.mjs +60 -0
  187. package/dist/capture/enrich.mjs.map +1 -0
  188. package/dist/capture/failure-sets.mjs +22 -0
  189. package/dist/capture/failure-sets.mjs.map +1 -0
  190. package/dist/capture/fingerprint.d.mts +42 -0
  191. package/dist/capture/fingerprint.mjs +83 -0
  192. package/dist/capture/fingerprint.mjs.map +1 -0
  193. package/dist/capture/forked/channel.d.mts +25 -0
  194. package/dist/capture/forked/child.d.mts +34 -0
  195. package/dist/capture/forked/child.mjs +202 -0
  196. package/dist/capture/forked/child.mjs.map +1 -0
  197. package/dist/capture/forked/crash-tracker.mjs +23 -0
  198. package/dist/capture/forked/crash-tracker.mjs.map +1 -0
  199. package/dist/capture/forked/decision.d.mts +26 -0
  200. package/dist/capture/forked/decision.mjs +27 -0
  201. package/dist/capture/forked/decision.mjs.map +1 -0
  202. package/dist/capture/forked/exit.mjs +12 -0
  203. package/dist/capture/forked/exit.mjs.map +1 -0
  204. package/dist/capture/forked/fork.d.mts +31 -0
  205. package/dist/capture/forked/fork.mjs +93 -0
  206. package/dist/capture/forked/fork.mjs.map +1 -0
  207. package/dist/capture/forked/forked-capture.d.mts +40 -0
  208. package/dist/capture/forked/forked-capture.mjs +240 -0
  209. package/dist/capture/forked/forked-capture.mjs.map +1 -0
  210. package/dist/capture/forked/lease-book.mjs +46 -0
  211. package/dist/capture/forked/lease-book.mjs.map +1 -0
  212. package/dist/capture/forked/protocol.d.mts +38 -0
  213. package/dist/capture/forked/protocol.mjs +25 -0
  214. package/dist/capture/forked/protocol.mjs.map +1 -0
  215. package/dist/capture/forked/runs.mjs +75 -0
  216. package/dist/capture/forked/runs.mjs.map +1 -0
  217. package/dist/capture/isolate.mjs +141 -0
  218. package/dist/capture/isolate.mjs.map +1 -0
  219. package/dist/capture/job-lease.d.mts +28 -0
  220. package/dist/capture/job-lease.mjs +57 -0
  221. package/dist/capture/job-lease.mjs.map +1 -0
  222. package/dist/capture/matrix.mjs +298 -0
  223. package/dist/capture/matrix.mjs.map +1 -0
  224. package/dist/capture/modes.d.mts +25 -0
  225. package/dist/capture/modes.mjs +107 -0
  226. package/dist/capture/modes.mjs.map +1 -0
  227. package/dist/capture/orchestrator.d.mts +37 -5
  228. package/dist/capture/orchestrator.mjs +118 -107
  229. package/dist/capture/orchestrator.mjs.map +1 -1
  230. package/dist/capture/pipeline.d.mts +9 -2
  231. package/dist/capture/pipeline.mjs +250 -45
  232. package/dist/capture/pipeline.mjs.map +1 -1
  233. package/dist/capture/progress.d.mts +11 -0
  234. package/dist/capture/progress.mjs +28 -0
  235. package/dist/capture/progress.mjs.map +1 -0
  236. package/dist/capture/publish/accept.d.mts +39 -0
  237. package/dist/capture/publish/accept.mjs +28 -0
  238. package/dist/capture/publish/accept.mjs.map +1 -0
  239. package/dist/capture/publish/complete.d.mts +46 -0
  240. package/dist/capture/publish/complete.mjs +64 -0
  241. package/dist/capture/publish/complete.mjs.map +1 -0
  242. package/dist/capture/publish/extract.d.mts +20 -0
  243. package/dist/capture/publish/extract.mjs +119 -0
  244. package/dist/capture/publish/extract.mjs.map +1 -0
  245. package/dist/capture/publish/handler.d.mts +28 -0
  246. package/dist/capture/publish/handler.mjs +62 -0
  247. package/dist/capture/publish/handler.mjs.map +1 -0
  248. package/dist/capture/publish/index.d.mts +10 -0
  249. package/dist/capture/publish/limits.d.mts +37 -0
  250. package/dist/capture/publish/limits.mjs +39 -0
  251. package/dist/capture/publish/limits.mjs.map +1 -0
  252. package/dist/capture/publish/published.d.mts +15 -0
  253. package/dist/capture/publish/published.mjs +18 -0
  254. package/dist/capture/publish/published.mjs.map +1 -0
  255. package/dist/capture/publish/run.d.mts +33 -0
  256. package/dist/capture/publish/run.mjs +30 -0
  257. package/dist/capture/publish/run.mjs.map +1 -0
  258. package/dist/capture/rediff.d.mts +1 -1
  259. package/dist/capture/rediff.mjs +4 -3
  260. package/dist/capture/rediff.mjs.map +1 -1
  261. package/dist/capture/render.mjs +53 -0
  262. package/dist/capture/render.mjs.map +1 -0
  263. package/dist/capture/scratch.d.mts +44 -0
  264. package/dist/capture/scratch.mjs +138 -0
  265. package/dist/capture/scratch.mjs.map +1 -0
  266. package/dist/capture/shard-plan.mjs +128 -0
  267. package/dist/capture/shard-plan.mjs.map +1 -0
  268. package/dist/capture/shards/context.mjs +51 -0
  269. package/dist/capture/shards/context.mjs.map +1 -0
  270. package/dist/capture/shards/execute.mjs +174 -0
  271. package/dist/capture/shards/execute.mjs.map +1 -0
  272. package/dist/capture/shards/fan-out.mjs +126 -0
  273. package/dist/capture/shards/fan-out.mjs.map +1 -0
  274. package/dist/capture/shards/history.mjs +35 -0
  275. package/dist/capture/shards/history.mjs.map +1 -0
  276. package/dist/capture/shards/reduce.mjs +97 -0
  277. package/dist/capture/shards/reduce.mjs.map +1 -0
  278. package/dist/capture/sizing.mjs +1 -11
  279. package/dist/capture/sizing.mjs.map +1 -1
  280. package/dist/capture/skip-checks.mjs +2 -65
  281. package/dist/capture/skip-checks.mjs.map +1 -1
  282. package/dist/capture/statics.d.mts +7 -8
  283. package/dist/capture/statics.mjs +25 -71
  284. package/dist/capture/statics.mjs.map +1 -1
  285. package/dist/capture/storybook-urls.d.mts +40 -0
  286. package/dist/capture/storybook-urls.mjs +41 -0
  287. package/dist/capture/storybook-urls.mjs.map +1 -0
  288. package/dist/capture/storybook.d.mts +12 -4
  289. package/dist/capture/storybook.mjs +56 -16
  290. package/dist/capture/storybook.mjs.map +1 -1
  291. package/dist/capture/target.mjs +21 -0
  292. package/dist/capture/target.mjs.map +1 -0
  293. package/dist/capture/targets.d.mts +25 -0
  294. package/dist/capture/targets.mjs +32 -0
  295. package/dist/capture/targets.mjs.map +1 -0
  296. package/dist/capture/tests.d.mts +37 -0
  297. package/dist/capture/tests.mjs +126 -0
  298. package/dist/capture/tests.mjs.map +1 -0
  299. package/dist/capture/token-chunks.mjs +74 -0
  300. package/dist/capture/token-chunks.mjs.map +1 -0
  301. package/dist/capture.d.mts +60 -7
  302. package/dist/capture.mjs +48 -3
  303. package/dist/config.d.mts +121 -12
  304. package/dist/config.mjs +9 -6
  305. package/dist/config.mjs.map +1 -1
  306. package/dist/diff.d.mts +9 -3
  307. package/dist/diff.mjs +16 -3
  308. package/dist/diff.mjs.map +1 -0
  309. package/dist/index.d.mts +1 -1
  310. package/dist/insights/budget.d.mts +20 -0
  311. package/dist/insights/budget.mjs +33 -0
  312. package/dist/insights/budget.mjs.map +1 -0
  313. package/dist/insights/envelope.d.mts +59 -0
  314. package/dist/insights/envelope.mjs +60 -0
  315. package/dist/insights/envelope.mjs.map +1 -0
  316. package/dist/insights/evidence-health.d.mts +32 -0
  317. package/dist/insights/evidence-health.mjs +28 -0
  318. package/dist/insights/evidence-health.mjs.map +1 -0
  319. package/dist/insights/evidence.d.mts +55 -0
  320. package/dist/insights/evidence.mjs +64 -0
  321. package/dist/insights/evidence.mjs.map +1 -0
  322. package/dist/insights/hash.d.mts +18 -0
  323. package/dist/insights/hash.mjs +21 -0
  324. package/dist/insights/hash.mjs.map +1 -0
  325. package/dist/insights/limits.d.mts +24 -0
  326. package/dist/insights/limits.mjs +24 -0
  327. package/dist/insights/limits.mjs.map +1 -0
  328. package/dist/insights/prompts/v1.d.mts +13 -0
  329. package/dist/insights/prompts/v1.mjs +34 -0
  330. package/dist/insights/prompts/v1.mjs.map +1 -0
  331. package/dist/insights/redact.d.mts +9 -0
  332. package/dist/insights/redact.mjs +24 -0
  333. package/dist/insights/redact.mjs.map +1 -0
  334. package/dist/insights/text.mjs +44 -0
  335. package/dist/insights/text.mjs.map +1 -0
  336. package/dist/insights.d.mts +11 -0
  337. package/dist/insights.mjs +12 -0
  338. package/dist/logger.mjs +17 -1
  339. package/dist/logger.mjs.map +1 -1
  340. package/dist/models/ai-budget-alert.d.mts +23 -0
  341. package/dist/models/ai-budget-alert.mjs +38 -0
  342. package/dist/models/ai-budget-alert.mjs.map +1 -0
  343. package/dist/models/ai-usage.d.mts +40 -0
  344. package/dist/models/ai-usage.mjs +61 -0
  345. package/dist/models/ai-usage.mjs.map +1 -0
  346. package/dist/models/baseline-archive.d.mts +84 -0
  347. package/dist/models/baseline-archive.mjs +106 -0
  348. package/dist/models/baseline-archive.mjs.map +1 -0
  349. package/dist/models/baseline-export.d.mts +19 -0
  350. package/dist/models/baseline-export.mjs +136 -0
  351. package/dist/models/baseline-export.mjs.map +1 -0
  352. package/dist/models/baseline-import.mjs +118 -0
  353. package/dist/models/baseline-import.mjs.map +1 -0
  354. package/dist/models/baseline-transfer.d.mts +49 -0
  355. package/dist/models/baseline-transfer.mjs +121 -0
  356. package/dist/models/baseline-transfer.mjs.map +1 -0
  357. package/dist/models/baseline.d.mts +32 -5
  358. package/dist/models/baseline.mjs +65 -20
  359. package/dist/models/baseline.mjs.map +1 -1
  360. package/dist/models/build-component.d.mts +28 -0
  361. package/dist/models/build-component.mjs +55 -0
  362. package/dist/models/build-component.mjs.map +1 -0
  363. package/dist/models/build-review-status.d.mts +29 -0
  364. package/dist/models/build-review-status.mjs +37 -0
  365. package/dist/models/build-review-status.mjs.map +1 -0
  366. package/dist/models/build-review.d.mts +28 -0
  367. package/dist/models/build-review.mjs +54 -0
  368. package/dist/models/build-review.mjs.map +1 -0
  369. package/dist/models/build.d.mts +25 -3
  370. package/dist/models/build.mjs +50 -11
  371. package/dist/models/build.mjs.map +1 -1
  372. package/dist/models/capture-attempt.d.mts +7 -1
  373. package/dist/models/capture-attempt.mjs +29 -4
  374. package/dist/models/capture-attempt.mjs.map +1 -1
  375. package/dist/models/capture-job.d.mts +106 -0
  376. package/dist/models/capture-job.mjs +288 -0
  377. package/dist/models/capture-job.mjs.map +1 -0
  378. package/dist/models/capture-log.d.mts +1 -1
  379. package/dist/models/capture-log.mjs +4 -3
  380. package/dist/models/capture-log.mjs.map +1 -1
  381. package/dist/models/capture-shard.d.mts +62 -0
  382. package/dist/models/capture-shard.mjs +190 -0
  383. package/dist/models/capture-shard.mjs.map +1 -0
  384. package/dist/models/changeset.d.mts +48 -0
  385. package/dist/models/changeset.mjs +81 -0
  386. package/dist/models/changeset.mjs.map +1 -0
  387. package/dist/models/columns.mjs +19 -0
  388. package/dist/models/columns.mjs.map +1 -0
  389. package/dist/models/comment.d.mts +4 -1
  390. package/dist/models/comment.mjs +7 -4
  391. package/dist/models/comment.mjs.map +1 -1
  392. package/dist/models/component.d.mts +43 -0
  393. package/dist/models/component.mjs +60 -0
  394. package/dist/models/component.mjs.map +1 -0
  395. package/dist/models/connections.d.mts +41 -0
  396. package/dist/models/connections.mjs +112 -0
  397. package/dist/models/connections.mjs.map +1 -0
  398. package/dist/models/content-ref.d.mts +1 -1
  399. package/dist/models/content-ref.mjs +1 -1
  400. package/dist/models/content-ref.mjs.map +1 -1
  401. package/dist/models/credentials.mjs +12 -2
  402. package/dist/models/credentials.mjs.map +1 -1
  403. package/dist/models/design-credentials.d.mts +41 -0
  404. package/dist/models/design-credentials.mjs +86 -0
  405. package/dist/models/design-credentials.mjs.map +1 -0
  406. package/dist/models/design-health.d.mts +16 -0
  407. package/dist/models/design-health.mjs +25 -0
  408. package/dist/models/design-health.mjs.map +1 -0
  409. package/dist/models/design-nodes.d.mts +83 -0
  410. package/dist/models/design-nodes.mjs +222 -0
  411. package/dist/models/design-nodes.mjs.map +1 -0
  412. package/dist/models/design-renders.mjs +74 -0
  413. package/dist/models/design-renders.mjs.map +1 -0
  414. package/dist/models/design-resolve.d.mts +29 -0
  415. package/dist/models/design-resolve.mjs +41 -0
  416. package/dist/models/design-resolve.mjs.map +1 -0
  417. package/dist/models/design.d.mts +39 -0
  418. package/dist/models/design.mjs +90 -0
  419. package/dist/models/design.mjs.map +1 -0
  420. package/dist/models/inherited-ratio.d.mts +21 -0
  421. package/dist/models/inherited-ratio.mjs +22 -0
  422. package/dist/models/inherited-ratio.mjs.map +1 -0
  423. package/dist/models/insight.d.mts +70 -0
  424. package/dist/models/insight.mjs +162 -0
  425. package/dist/models/insight.mjs.map +1 -0
  426. package/dist/models/label.d.mts +4 -2
  427. package/dist/models/label.mjs +25 -10
  428. package/dist/models/label.mjs.map +1 -1
  429. package/dist/models/member.d.mts +1 -1
  430. package/dist/models/member.mjs +5 -4
  431. package/dist/models/member.mjs.map +1 -1
  432. package/dist/models/notification-channel.d.mts +37 -3
  433. package/dist/models/notification-channel.mjs +88 -9
  434. package/dist/models/notification-channel.mjs.map +1 -1
  435. package/dist/models/notification-subscription.d.mts +1 -2
  436. package/dist/models/notification-subscription.mjs +7 -9
  437. package/dist/models/notification-subscription.mjs.map +1 -1
  438. package/dist/models/project-group-mapping.d.mts +6 -1
  439. package/dist/models/project-group-mapping.mjs +14 -4
  440. package/dist/models/project-group-mapping.mjs.map +1 -1
  441. package/dist/models/project.d.mts +9 -1
  442. package/dist/models/project.mjs +9 -4
  443. package/dist/models/project.mjs.map +1 -1
  444. package/dist/models/public-origin.d.mts +63 -0
  445. package/dist/models/public-origin.mjs +114 -0
  446. package/dist/models/public-origin.mjs.map +1 -0
  447. package/dist/models/review-switch-off.d.mts +14 -0
  448. package/dist/models/review-switch-off.mjs +26 -0
  449. package/dist/models/review-switch-off.mjs.map +1 -0
  450. package/dist/models/site-settings.d.mts +23 -0
  451. package/dist/models/site-settings.mjs +48 -0
  452. package/dist/models/site-settings.mjs.map +1 -0
  453. package/dist/models/snapshot.d.mts +36 -1
  454. package/dist/models/snapshot.mjs +50 -3
  455. package/dist/models/snapshot.mjs.map +1 -1
  456. package/dist/models/token.d.mts +13 -1
  457. package/dist/models/token.mjs +23 -5
  458. package/dist/models/token.mjs.map +1 -1
  459. package/dist/models/usage.d.mts +76 -0
  460. package/dist/models/usage.mjs +149 -0
  461. package/dist/models/usage.mjs.map +1 -0
  462. package/dist/models/user.d.mts +1 -1
  463. package/dist/models/user.mjs +4 -3
  464. package/dist/models/user.mjs.map +1 -1
  465. package/dist/models/webhook.d.mts +15 -1
  466. package/dist/models/webhook.mjs +33 -4
  467. package/dist/models/webhook.mjs.map +1 -1
  468. package/dist/models.d.mts +26 -3
  469. package/dist/models.mjs +27 -5
  470. package/dist/options.d.mts +18 -0
  471. package/dist/options.mjs +90 -0
  472. package/dist/options.mjs.map +1 -0
  473. package/dist/paths.d.mts +19 -4
  474. package/dist/paths.mjs +51 -10
  475. package/dist/paths.mjs.map +1 -1
  476. package/dist/retention/ai.d.mts +18 -0
  477. package/dist/retention/ai.mjs +23 -0
  478. package/dist/retention/ai.mjs.map +1 -0
  479. package/dist/retention/pending.mjs +47 -0
  480. package/dist/retention/pending.mjs.map +1 -0
  481. package/dist/retention/screenshot-sweep.d.mts +51 -0
  482. package/dist/retention/screenshot-sweep.mjs +128 -0
  483. package/dist/retention/screenshot-sweep.mjs.map +1 -0
  484. package/dist/retention.d.mts +16 -2
  485. package/dist/retention.mjs +71 -14
  486. package/dist/retention.mjs.map +1 -1
  487. package/dist/schema/baseline.d.mts +6 -0
  488. package/dist/schema/build-component.d.mts +25 -0
  489. package/dist/schema/build-review.d.mts +17 -0
  490. package/dist/schema/build.d.mts +7 -0
  491. package/dist/schema/capture-job.d.mts +60 -0
  492. package/dist/schema/capture-shard.d.mts +35 -0
  493. package/dist/schema/comment.d.mts +2 -0
  494. package/dist/schema/connection.d.mts +24 -0
  495. package/dist/schema/design.d.mts +58 -0
  496. package/dist/schema/insight.d.mts +54 -0
  497. package/dist/schema/notification.d.mts +4 -0
  498. package/dist/schema/project.d.mts +21 -0
  499. package/dist/schema/site-setting.d.mts +21 -0
  500. package/dist/schema/snapshot.d.mts +12 -0
  501. package/dist/schema/usage.d.mts +30 -0
  502. package/dist/schema.d.mts +11 -3
  503. package/dist/serverless.d.mts +21 -0
  504. package/dist/serverless.mjs +37 -0
  505. package/dist/serverless.mjs.map +1 -0
  506. package/dist/test-helpers/create-project.d.mts +1 -1
  507. package/dist/test-helpers/deferred.d.mts +39 -0
  508. package/dist/test-helpers/deferred.mjs +61 -0
  509. package/dist/test-helpers/deferred.mjs.map +1 -0
  510. package/dist/test-helpers/design-contract.d.mts +21 -0
  511. package/dist/test-helpers/design-contract.mjs +40 -0
  512. package/dist/test-helpers/design-contract.mjs.map +1 -0
  513. package/dist/test-helpers/fake-database.mjs +14 -2
  514. package/dist/test-helpers/fake-database.mjs.map +1 -1
  515. package/dist/test-helpers/fake-design.d.mts +43 -0
  516. package/dist/test-helpers/fake-design.mjs +114 -0
  517. package/dist/test-helpers/fake-design.mjs.map +1 -0
  518. package/dist/test-helpers/fake-notifier.d.mts +21 -0
  519. package/dist/test-helpers/fake-notifier.mjs +44 -0
  520. package/dist/test-helpers/fake-notifier.mjs.map +1 -0
  521. package/dist/test-helpers/fake-tables.mjs +255 -67
  522. package/dist/test-helpers/fake-tables.mjs.map +1 -1
  523. package/dist/test-helpers/manual-clock.d.mts +27 -0
  524. package/dist/test-helpers/manual-clock.mjs +56 -0
  525. package/dist/test-helpers/manual-clock.mjs.map +1 -0
  526. package/dist/test-helpers/notifier-contract.d.mts +7 -1
  527. package/dist/test-helpers/notifier-contract.mjs +32 -3
  528. package/dist/test-helpers/notifier-contract.mjs.map +1 -1
  529. package/dist/test-helpers/queue-contract.d.mts +16 -2
  530. package/dist/test-helpers/queue-contract.mjs +195 -1
  531. package/dist/test-helpers/queue-contract.mjs.map +1 -1
  532. package/dist/test-helpers/queue-multi-instance.d.mts +20 -0
  533. package/dist/test-helpers/queue-multi-instance.mjs +206 -0
  534. package/dist/test-helpers/queue-multi-instance.mjs.map +1 -0
  535. package/dist/test-helpers/runner-contract.mjs +11 -0
  536. package/dist/test-helpers/runner-contract.mjs.map +1 -1
  537. package/dist/test-helpers/sql-chunks.mjs +23 -0
  538. package/dist/test-helpers/sql-chunks.mjs.map +1 -1
  539. package/dist/test-helpers/storage-contract.mjs +1 -1
  540. package/dist/test-helpers.d.mts +9 -4
  541. package/dist/test-helpers.mjs +8 -3
  542. package/dist/types.d.mts +14 -3
  543. package/dist/types.mjs +21 -4
  544. package/dist/types.mjs.map +1 -1
  545. package/dist/urls.d.mts +4 -0
  546. package/dist/urls.mjs +11 -2
  547. package/dist/urls.mjs.map +1 -1
  548. package/dist/utils/adaptive-concurrency.d.mts +66 -0
  549. package/dist/utils/adaptive-concurrency.mjs +149 -0
  550. package/dist/utils/adaptive-concurrency.mjs.map +1 -0
  551. package/dist/utils/connect-retry.d.mts +26 -0
  552. package/dist/utils/connect-retry.mjs +43 -0
  553. package/dist/utils/connect-retry.mjs.map +1 -0
  554. package/dist/utils/environment.d.mts +19 -0
  555. package/dist/utils/environment.mjs +59 -0
  556. package/dist/utils/environment.mjs.map +1 -0
  557. package/dist/utils/http.d.mts +17 -1
  558. package/dist/utils/http.mjs +22 -3
  559. package/dist/utils/http.mjs.map +1 -1
  560. package/dist/utils/map-adaptive.d.mts +15 -0
  561. package/dist/utils/map-adaptive.mjs +72 -0
  562. package/dist/utils/map-adaptive.mjs.map +1 -0
  563. package/dist/utils/map-limit.d.mts +10 -0
  564. package/dist/utils/map-limit.mjs +32 -0
  565. package/dist/utils/map-limit.mjs.map +1 -0
  566. package/dist/utils/page-limiter.d.mts +37 -0
  567. package/dist/utils/page-limiter.mjs +56 -0
  568. package/dist/utils/page-limiter.mjs.map +1 -0
  569. package/dist/utils/public-origin.d.mts +20 -0
  570. package/dist/utils/public-origin.mjs +75 -0
  571. package/dist/utils/public-origin.mjs.map +1 -0
  572. package/dist/utils/redact.mjs +3 -0
  573. package/dist/utils/redact.mjs.map +1 -1
  574. package/dist/utils/remote-environment.d.mts +39 -0
  575. package/dist/utils/remote-environment.mjs +114 -0
  576. package/dist/utils/remote-environment.mjs.map +1 -0
  577. package/dist/utils/resources.d.mts +64 -0
  578. package/dist/utils/resources.mjs +122 -0
  579. package/dist/utils/resources.mjs.map +1 -0
  580. package/dist/utils/screenshot-store.d.mts +15 -0
  581. package/dist/utils/screenshot-store.mjs +41 -0
  582. package/dist/utils/screenshot-store.mjs.map +1 -0
  583. package/dist/utils/session-gate.d.mts +22 -0
  584. package/dist/utils/session-gate.mjs +53 -0
  585. package/dist/utils/session-gate.mjs.map +1 -0
  586. package/dist/utils/storybook-token.d.mts +81 -0
  587. package/dist/utils/storybook-token.mjs +134 -0
  588. package/dist/utils/storybook-token.mjs.map +1 -0
  589. package/dist/utils/storybook-url.d.mts +15 -0
  590. package/dist/utils/storybook-url.mjs +21 -0
  591. package/dist/utils/storybook-url.mjs.map +1 -0
  592. package/dist/utils/timing.mjs +1 -1
  593. package/dist/utils/timing.mjs.map +1 -1
  594. package/dist/utils/zip-read.mjs +129 -0
  595. package/dist/utils/zip-read.mjs.map +1 -0
  596. package/dist/utils/zip-write.d.mts +18 -0
  597. package/dist/utils/zip-write.mjs +188 -0
  598. package/dist/utils/zip-write.mjs.map +1 -0
  599. package/dist/utils.d.mts +17 -3
  600. package/dist/utils.mjs +18 -4
  601. package/package.json +32 -20
  602. package/dist/adapter/capture-runner.mjs.map +0 -1
  603. package/dist/adapter/git-host/comments.d.mts +0 -41
  604. package/dist/adapter/git-host/comments.mjs +0 -54
  605. package/dist/adapter/git-host/comments.mjs.map +0 -1
  606. package/dist/adapter/git-host/helpers.d.mts +0 -13
  607. package/dist/adapter/git-host/helpers.mjs +0 -30
  608. package/dist/adapter/git-host/helpers.mjs.map +0 -1
  609. package/dist/adapter/git-host.d.mts +0 -42
  610. package/dist/capture/queue.d.mts +0 -38
  611. package/dist/capture/queue.mjs +0 -98
  612. package/dist/capture/queue.mjs.map +0 -1
  613. package/dist/capture/recovery.d.mts +0 -21
  614. package/dist/capture/recovery.mjs +0 -83
  615. package/dist/capture/recovery.mjs.map +0 -1
  616. package/dist/capture/status-fanout.mjs +0 -72
  617. package/dist/capture/status-fanout.mjs.map +0 -1
  618. package/dist/diff/engine.d.mts +0 -16
  619. package/dist/diff/engine.mjs +0 -87
  620. package/dist/diff/engine.mjs.map +0 -1
  621. package/dist/diff/options.d.mts +0 -42
  622. package/dist/diff/options.mjs +0 -15
  623. package/dist/diff/options.mjs.map +0 -1
  624. package/dist/models/status-config.d.mts +0 -38
  625. package/dist/models/status-config.mjs +0 -63
  626. package/dist/models/status-config.mjs.map +0 -1
  627. package/dist/schema/status-config.d.mts +0 -16
  628. package/dist/test-helpers/git-contract.d.mts +0 -11
  629. package/dist/test-helpers/git-contract.mjs +0 -34
  630. package/dist/test-helpers/git-contract.mjs.map +0 -1
  631. /package/dist/adapter/{git-host.mjs → oauth.mjs} +0 -0
@@ -0,0 +1,37 @@
1
+ import __tsdown_shims_path from 'node:path';
2
+ import __tsdown_shims_url from 'node:url';
3
+ import "./adapter.mjs";
4
+ import "../adapter/capture-runner.mjs";
5
+ import "./storybook-urls.mjs";
6
+ import "../models/build.mjs";
7
+ import "../models/capture-attempt.mjs";
8
+ import { Logger } from "pino";
9
+ //#region src/capture/tests.d.ts
10
+ /** What a build keeps of one `.test()` entry (JSON in `builds.test_results`). */
11
+ interface TestResult {
12
+ /** The test entry's id (`<story id>:<test name slug>`). */
13
+ id: string;
14
+ /** Story file title (the component path), as on its index entry. */
15
+ title: string;
16
+ /** The test's own name, as written in `story.test("...")`. */
17
+ name: string;
18
+ /** The story the test is written under. */
19
+ parentId: string | null;
20
+ status: "passed" | "failed";
21
+ /** The failure message of a failed test. */
22
+ error?: string;
23
+ durationMs: number;
24
+ }
25
+ /** Pass and fail counts of a build's tests. */
26
+ interface TestSummary {
27
+ total: number;
28
+ passed: number;
29
+ failed: number;
30
+ }
31
+ /** The results a build holds; empty for none or an unreadable value. */
32
+ declare function parseTestResults(json: string | null | undefined): TestResult[];
33
+ /** Counts of a build's results. */
34
+ declare function summarizeTests(results: readonly TestResult[]): TestSummary;
35
+ //#endregion
36
+ export { TestResult, TestSummary, parseTestResults, summarizeTests };
37
+ //# sourceMappingURL=tests.d.mts.map
@@ -0,0 +1,126 @@
1
+ import "node:path";
2
+ import "node:url";
3
+ import.meta.url;
4
+ import { redactSecrets } from "../utils/redact.mjs";
5
+ import { isDisabledStory } from "./adapter.mjs";
6
+ import { emitAttemptLog } from "../models/capture-attempt.mjs";
7
+ import { classifyFailures } from "./failure-sets.mjs";
8
+ import { renderBudgetMs } from "./render.mjs";
9
+ import { StorybookAdapter } from "./storybook.mjs";
10
+ //#region src/capture/tests.ts
11
+ /** Longest failure message kept (rows and logs stay bounded). */
12
+ const ERROR_MAX = 1e3;
13
+ /**
14
+ * Run the build's `.test()` entries when the project turned tests on, and store the results on the
15
+ * build. A failing test is a blocking failure of its own id, exactly like a `play` that throws; it
16
+ * takes no screenshot, writes no snapshot and sets no status of its own. Without the setting (or
17
+ * without test entries) nothing runs and nothing is written, except that results left by an
18
+ * earlier run of the same build are cleared.
19
+ */
20
+ async function runProjectTests(input) {
21
+ const tests = input.project.runTests ? await testsToRun(input) : [];
22
+ const run = input.runner.runTests?.bind(input.runner);
23
+ if (tests.length === 0 || !run) return await skipTests(input, tests.length);
24
+ const results = resultsOf(tests, await execute(input, run, tests));
25
+ await keepResults(input, results);
26
+ return await reportFailures(input, results, tests);
27
+ }
28
+ /** Nothing to run: warn when tests were wanted but the runner cannot, and clear stale results. */
29
+ async function skipTests(input, wanted) {
30
+ if (wanted > 0) input.logger?.warn({ tests: wanted }, "project runs tests but the capture runner cannot run them; skipped");
31
+ await keepResults(input, null);
32
+ return {
33
+ blocking: /* @__PURE__ */ new Set(),
34
+ flaky: /* @__PURE__ */ new Set()
35
+ };
36
+ }
37
+ /** The test entries to run: those of stories that are not skipped. */
38
+ async function testsToRun(input) {
39
+ const skipped = new Set(input.stories.filter((story) => isDisabledStory(story)).map((s) => s.id));
40
+ return (await new StorybookAdapter().discoverTests(input.storybookDir)).filter((entry) => !isDisabledStory(entry) && !(entry.parentId !== void 0 && skipped.has(entry.parentId)));
41
+ }
42
+ async function execute(input, run, tests) {
43
+ const storybookUrl = await input.storybookUrl?.(input.target, { budgetMs: renderBudgetMs(tests.length) });
44
+ await emitAttemptLog(input.recordLog, input.logger, "info", "running storybook tests", { tests: tests.length });
45
+ return await run({
46
+ buildId: input.build.id,
47
+ storybookDir: input.storybookDir,
48
+ tests,
49
+ playTimeoutMs: input.project.playTimeoutMs,
50
+ target: input.target,
51
+ ...storybookUrl === void 0 ? {} : { storybookUrl },
52
+ ...input.logger ? { logger: input.logger } : {}
53
+ });
54
+ }
55
+ /** One result per test entry; a test the runner reported nothing for counts as failed. */
56
+ function resultsOf(tests, outcomes) {
57
+ const byId = new Map(outcomes.map((outcome) => [outcome.storyId, outcome]));
58
+ return tests.map((test) => {
59
+ const outcome = byId.get(test.id);
60
+ const error = outcome === void 0 ? "the runner reported no result for this test" : outcome.error;
61
+ const failed = outcome === void 0 || outcome.status === "failed";
62
+ return {
63
+ id: test.id,
64
+ title: test.title,
65
+ name: test.name,
66
+ parentId: test.parentId ?? null,
67
+ status: failed ? "failed" : "passed",
68
+ ...failed ? { error: redactSecrets(error ?? "test failed").slice(0, ERROR_MAX) } : {},
69
+ durationMs: outcome?.durationMs ?? 0
70
+ };
71
+ });
72
+ }
73
+ /** Write the results; a build that has none and never had any is left untouched. */
74
+ async function keepResults(input, results) {
75
+ if (results === null && !input.build.testResults) return;
76
+ await input.builds.setTestResults(input.build.id, results);
77
+ }
78
+ async function reportFailures(input, results, tests) {
79
+ const failed = results.filter((result) => result.status === "failed");
80
+ const classified = classifyFailures(tests, failed.map((result) => ({
81
+ storyId: result.id,
82
+ viewportName: "test",
83
+ error: result.error ?? ""
84
+ })));
85
+ const sets = {
86
+ blocking: classified.blocking,
87
+ flaky: classified.flaky
88
+ };
89
+ const fields = {
90
+ tests: results.length,
91
+ failed: failed.length,
92
+ flaky: sets.flaky.size
93
+ };
94
+ const level = sets.blocking.size > 0 ? "error" : "info";
95
+ input.logger?.[level](fields, "storybook tests finished");
96
+ await emitAttemptLog(input.recordLog, input.logger, level, "storybook tests finished", fields);
97
+ return sets;
98
+ }
99
+ /** The results a build holds; empty for none or an unreadable value. */
100
+ function parseTestResults(json) {
101
+ if (!json) return [];
102
+ try {
103
+ const parsed = JSON.parse(json);
104
+ return Array.isArray(parsed) ? parsed.filter((item) => isTestResult(item)) : [];
105
+ } catch {
106
+ return [];
107
+ }
108
+ }
109
+ /** Counts of a build's results. */
110
+ function summarizeTests(results) {
111
+ const failed = results.filter((result) => result.status === "failed").length;
112
+ return {
113
+ total: results.length,
114
+ passed: results.length - failed,
115
+ failed
116
+ };
117
+ }
118
+ function isTestResult(value) {
119
+ if (typeof value !== "object" || value === null) return false;
120
+ const record = value;
121
+ return typeof record["id"] === "string" && typeof record["name"] === "string" && (record["status"] === "passed" || record["status"] === "failed");
122
+ }
123
+ //#endregion
124
+ export { parseTestResults, runProjectTests, summarizeTests };
125
+
126
+ //# sourceMappingURL=tests.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tests.mjs","names":[],"sources":["../../src/capture/tests.ts"],"sourcesContent":["/** Running a project's Storybook 10 `.test()` entries and keeping what they reported (ADR 0004, decision 10). */\nimport type { Logger } from \"pino\";\nimport type { CaptureRunner, CaptureTarget, TestOutcome } from \"../adapters/capture-runner.ts\";\nimport type { BuildModel } from \"../models/build.ts\";\nimport { emitAttemptLog, type AttemptLogRecorder } from \"../models/capture-attempt.ts\";\nimport type { Build } from \"../schema/build.ts\";\nimport type { Project } from \"../schema/project.ts\";\nimport { redactSecrets } from \"../utils/redact.ts\";\nimport { isDisabledStory, type StoryEntry } from \"./adapter.ts\";\nimport { classifyFailures } from \"./failure-sets.ts\";\nimport { renderBudgetMs } from \"./render.ts\";\nimport type { StorybookUrlSource } from \"./storybook-urls.ts\";\nimport { StorybookAdapter } from \"./storybook.ts\";\n\n/** What a build keeps of one `.test()` entry (JSON in `builds.test_results`). */\nexport interface TestResult {\n /** The test entry's id (`<story id>:<test name slug>`). */\n id: string;\n /** Story file title (the component path), as on its index entry. */\n title: string;\n /** The test's own name, as written in `story.test(\"...\")`. */\n name: string;\n /** The story the test is written under. */\n parentId: string | null;\n status: \"passed\" | \"failed\";\n /** The failure message of a failed test. */\n error?: string;\n durationMs: number;\n}\n\n/** Pass and fail counts of a build's tests. */\nexport interface TestSummary {\n total: number;\n passed: number;\n failed: number;\n}\n\n/** Longest failure message kept (rows and logs stay bounded). */\nconst ERROR_MAX = 1000;\n\n/** Test ids by how their failure counts, as {@link runProjectTests} classifies them. */\nexport interface TestRunSets {\n /** Fail the build, like a failing `play` function. */\n blocking: Set<string>;\n /** Tests of a story marked flaky: logged, never blocking. */\n flaky: Set<string>;\n}\n\n/** Inputs for {@link runProjectTests}. */\nexport interface RunTestsInput {\n runner: CaptureRunner;\n builds: BuildModel;\n build: Build;\n project: Project;\n storybookDir: string;\n /** Every discovered story, so the tests of a skipped story are skipped too. */\n stories: readonly StoryEntry[];\n target: CaptureTarget;\n storybookUrl?: StorybookUrlSource | undefined;\n logger: Logger | undefined;\n recordLog?: AttemptLogRecorder | undefined;\n}\n\n/**\n * Run the build's `.test()` entries when the project turned tests on, and store the results on the\n * build. A failing test is a blocking failure of its own id, exactly like a `play` that throws; it\n * takes no screenshot, writes no snapshot and sets no status of its own. Without the setting (or\n * without test entries) nothing runs and nothing is written, except that results left by an\n * earlier run of the same build are cleared.\n */\nexport async function runProjectTests(input: RunTestsInput): Promise<TestRunSets> {\n const tests = input.project.runTests ? await testsToRun(input) : [];\n const run = input.runner.runTests?.bind(input.runner);\n if (tests.length === 0 || !run) return await skipTests(input, tests.length);\n const results = resultsOf(tests, await execute(input, run, tests));\n await keepResults(input, results);\n return await reportFailures(input, results, tests);\n}\n\n/** Nothing to run: warn when tests were wanted but the runner cannot, and clear stale results. */\nasync function skipTests(input: RunTestsInput, wanted: number): Promise<TestRunSets> {\n if (wanted > 0) {\n input.logger?.warn(\n { tests: wanted },\n \"project runs tests but the capture runner cannot run them; skipped\",\n );\n }\n await keepResults(input, null);\n return { blocking: new Set(), flaky: new Set() };\n}\n\n/** The test entries to run: those of stories that are not skipped. */\nasync function testsToRun(input: RunTestsInput): Promise<StoryEntry[]> {\n const skipped = new Set(input.stories.filter((story) => isDisabledStory(story)).map((s) => s.id));\n const found = await new StorybookAdapter().discoverTests(input.storybookDir);\n return found.filter(\n (entry) =>\n !isDisabledStory(entry) && !(entry.parentId !== undefined && skipped.has(entry.parentId)),\n );\n}\n\nasync function execute(\n input: RunTestsInput,\n run: NonNullable<CaptureRunner[\"runTests\"]>,\n tests: StoryEntry[],\n): Promise<TestOutcome[]> {\n const storybookUrl = await input.storybookUrl?.(input.target, {\n budgetMs: renderBudgetMs(tests.length),\n });\n await emitAttemptLog(input.recordLog, input.logger, \"info\", \"running storybook tests\", {\n tests: tests.length,\n });\n return await run({\n buildId: input.build.id,\n storybookDir: input.storybookDir,\n tests,\n playTimeoutMs: input.project.playTimeoutMs,\n target: input.target,\n ...(storybookUrl === undefined ? {} : { storybookUrl }),\n ...(input.logger ? { logger: input.logger } : {}),\n });\n}\n\n/** One result per test entry; a test the runner reported nothing for counts as failed. */\nfunction resultsOf(tests: readonly StoryEntry[], outcomes: readonly TestOutcome[]): TestResult[] {\n const byId = new Map(outcomes.map((outcome) => [outcome.storyId, outcome]));\n return tests.map((test) => {\n const outcome = byId.get(test.id);\n const error =\n outcome === undefined ? \"the runner reported no result for this test\" : outcome.error;\n const failed = outcome === undefined || outcome.status === \"failed\";\n return {\n id: test.id,\n title: test.title,\n name: test.name,\n parentId: test.parentId ?? null,\n status: failed ? \"failed\" : \"passed\",\n ...(failed ? { error: redactSecrets(error ?? \"test failed\").slice(0, ERROR_MAX) } : {}),\n durationMs: outcome?.durationMs ?? 0,\n };\n });\n}\n\n/** Write the results; a build that has none and never had any is left untouched. */\nasync function keepResults(input: RunTestsInput, results: TestResult[] | null): Promise<void> {\n if (results === null && !input.build.testResults) return;\n await input.builds.setTestResults(input.build.id, results);\n}\n\nasync function reportFailures(\n input: RunTestsInput,\n results: readonly TestResult[],\n tests: readonly StoryEntry[],\n): Promise<TestRunSets> {\n const failed = results.filter((result) => result.status === \"failed\");\n const classified = classifyFailures(\n tests,\n failed.map((result) => ({\n storyId: result.id,\n viewportName: \"test\",\n error: result.error ?? \"\",\n })),\n );\n const sets = { blocking: classified.blocking, flaky: classified.flaky };\n const fields = { tests: results.length, failed: failed.length, flaky: sets.flaky.size };\n const level = sets.blocking.size > 0 ? \"error\" : \"info\";\n input.logger?.[level](fields, \"storybook tests finished\");\n await emitAttemptLog(input.recordLog, input.logger, level, \"storybook tests finished\", fields);\n return sets;\n}\n\n/** The results a build holds; empty for none or an unreadable value. */\nexport function parseTestResults(json: string | null | undefined): TestResult[] {\n if (!json) return [];\n try {\n const parsed: unknown = JSON.parse(json);\n return Array.isArray(parsed) ? parsed.filter((item) => isTestResult(item)) : [];\n } catch {\n return [];\n }\n}\n\n/** Counts of a build's results. */\nexport function summarizeTests(results: readonly TestResult[]): TestSummary {\n const failed = results.filter((result) => result.status === \"failed\").length;\n return { total: results.length, passed: results.length - failed, failed };\n}\n\nfunction isTestResult(value: unknown): value is TestResult {\n if (typeof value !== \"object\" || value === null) return false;\n const record = value as Record<string, unknown>;\n return (\n typeof record[\"id\"] === \"string\" &&\n typeof record[\"name\"] === \"string\" &&\n (record[\"status\"] === \"passed\" || record[\"status\"] === \"failed\")\n );\n}\n"],"mappings":";;;;;;;;;;;AAsCA,MAAM,YAAY;;;;;;;;AAgClB,eAAsB,gBAAgB,OAA4C;CAChF,MAAM,QAAQ,MAAM,QAAQ,WAAW,MAAM,WAAW,KAAK,IAAI,CAAC;CAClE,MAAM,MAAM,MAAM,OAAO,UAAU,KAAK,MAAM,MAAM;CACpD,IAAI,MAAM,WAAW,KAAK,CAAC,KAAK,OAAO,MAAM,UAAU,OAAO,MAAM,MAAM;CAC1E,MAAM,UAAU,UAAU,OAAO,MAAM,QAAQ,OAAO,KAAK,KAAK,CAAC;CACjE,MAAM,YAAY,OAAO,OAAO;CAChC,OAAO,MAAM,eAAe,OAAO,SAAS,KAAK;AACnD;;AAGA,eAAe,UAAU,OAAsB,QAAsC;CACnF,IAAI,SAAS,GACX,MAAM,QAAQ,KACZ,EAAE,OAAO,OAAO,GAChB,oEACF;CAEF,MAAM,YAAY,OAAO,IAAI;CAC7B,OAAO;EAAE,0BAAU,IAAI,IAAI;EAAG,uBAAO,IAAI,IAAI;CAAE;AACjD;;AAGA,eAAe,WAAW,OAA6C;CACrE,MAAM,UAAU,IAAI,IAAI,MAAM,QAAQ,QAAQ,UAAU,gBAAgB,KAAK,CAAC,CAAC,CAAC,KAAK,MAAM,EAAE,EAAE,CAAC;CAEhG,QAAO,MADa,IAAI,iBAAiB,CAAC,CAAC,cAAc,MAAM,YAAY,EAAA,CAC9D,QACV,UACC,CAAC,gBAAgB,KAAK,KAAK,EAAE,MAAM,aAAa,KAAA,KAAa,QAAQ,IAAI,MAAM,QAAQ,EAC3F;AACF;AAEA,eAAe,QACb,OACA,KACA,OACwB;CACxB,MAAM,eAAe,MAAM,MAAM,eAAe,MAAM,QAAQ,EAC5D,UAAU,eAAe,MAAM,MAAM,EACvC,CAAC;CACD,MAAM,eAAe,MAAM,WAAW,MAAM,QAAQ,QAAQ,2BAA2B,EACrF,OAAO,MAAM,OACf,CAAC;CACD,OAAO,MAAM,IAAI;EACf,SAAS,MAAM,MAAM;EACrB,cAAc,MAAM;EACpB;EACA,eAAe,MAAM,QAAQ;EAC7B,QAAQ,MAAM;EACd,GAAI,iBAAiB,KAAA,IAAY,CAAC,IAAI,EAAE,aAAa;EACrD,GAAI,MAAM,SAAS,EAAE,QAAQ,MAAM,OAAO,IAAI,CAAC;CACjD,CAAC;AACH;;AAGA,SAAS,UAAU,OAA8B,UAAgD;CAC/F,MAAM,OAAO,IAAI,IAAI,SAAS,KAAK,YAAY,CAAC,QAAQ,SAAS,OAAO,CAAC,CAAC;CAC1E,OAAO,MAAM,KAAK,SAAS;EACzB,MAAM,UAAU,KAAK,IAAI,KAAK,EAAE;EAChC,MAAM,QACJ,YAAY,KAAA,IAAY,gDAAgD,QAAQ;EAClF,MAAM,SAAS,YAAY,KAAA,KAAa,QAAQ,WAAW;EAC3D,OAAO;GACL,IAAI,KAAK;GACT,OAAO,KAAK;GACZ,MAAM,KAAK;GACX,UAAU,KAAK,YAAY;GAC3B,QAAQ,SAAS,WAAW;GAC5B,GAAI,SAAS,EAAE,OAAO,cAAc,SAAS,aAAa,CAAC,CAAC,MAAM,GAAG,SAAS,EAAE,IAAI,CAAC;GACrF,YAAY,SAAS,cAAc;EACrC;CACF,CAAC;AACH;;AAGA,eAAe,YAAY,OAAsB,SAA6C;CAC5F,IAAI,YAAY,QAAQ,CAAC,MAAM,MAAM,aAAa;CAClD,MAAM,MAAM,OAAO,eAAe,MAAM,MAAM,IAAI,OAAO;AAC3D;AAEA,eAAe,eACb,OACA,SACA,OACsB;CACtB,MAAM,SAAS,QAAQ,QAAQ,WAAW,OAAO,WAAW,QAAQ;CACpE,MAAM,aAAa,iBACjB,OACA,OAAO,KAAK,YAAY;EACtB,SAAS,OAAO;EAChB,cAAc;EACd,OAAO,OAAO,SAAS;CACzB,EAAE,CACJ;CACA,MAAM,OAAO;EAAE,UAAU,WAAW;EAAU,OAAO,WAAW;CAAM;CACtE,MAAM,SAAS;EAAE,OAAO,QAAQ;EAAQ,QAAQ,OAAO;EAAQ,OAAO,KAAK,MAAM;CAAK;CACtF,MAAM,QAAQ,KAAK,SAAS,OAAO,IAAI,UAAU;CACjD,MAAM,SAAS,MAAM,CAAC,QAAQ,0BAA0B;CACxD,MAAM,eAAe,MAAM,WAAW,MAAM,QAAQ,OAAO,4BAA4B,MAAM;CAC7F,OAAO;AACT;;AAGA,SAAgB,iBAAiB,MAA+C;CAC9E,IAAI,CAAC,MAAM,OAAO,CAAC;CACnB,IAAI;EACF,MAAM,SAAkB,KAAK,MAAM,IAAI;EACvC,OAAO,MAAM,QAAQ,MAAM,IAAI,OAAO,QAAQ,SAAS,aAAa,IAAI,CAAC,IAAI,CAAC;CAChF,QAAQ;EACN,OAAO,CAAC;CACV;AACF;;AAGA,SAAgB,eAAe,SAA6C;CAC1E,MAAM,SAAS,QAAQ,QAAQ,WAAW,OAAO,WAAW,QAAQ,CAAC,CAAC;CACtE,OAAO;EAAE,OAAO,QAAQ;EAAQ,QAAQ,QAAQ,SAAS;EAAQ;CAAO;AAC1E;AAEA,SAAS,aAAa,OAAqC;CACzD,IAAI,OAAO,UAAU,YAAY,UAAU,MAAM,OAAO;CACxD,MAAM,SAAS;CACf,OACE,OAAO,OAAO,UAAU,YACxB,OAAO,OAAO,YAAY,aACzB,OAAO,cAAc,YAAY,OAAO,cAAc;AAE3D"}
@@ -0,0 +1,74 @@
1
+ import "node:path";
2
+ import "node:url";
3
+ import.meta.url;
4
+ import { PER_CAPTURE_BUDGET_MS } from "../utils/storybook-token.mjs";
5
+ import { renderBudgetMs, renderWithTimeout } from "./render.mjs";
6
+ //#region src/capture/token-chunks.ts
7
+ /** Render the pass, minting a fresh signed URL for each slice; results are concatenated. */
8
+ async function renderInSlices(input) {
9
+ const slices = slicesOf(input);
10
+ const results = [];
11
+ for (const slice of slices) {
12
+ const budgetMs = renderBudgetMs(slice.expected, input.renderTimeoutMs);
13
+ const storybookUrl = await input.storybookUrl?.(input.browser, { budgetMs });
14
+ results.push(await renderWithTimeout(input.runner, {
15
+ ...input.request,
16
+ stories: slice.stories,
17
+ ...storybookUrl === void 0 ? {} : { storybookUrl }
18
+ }, budgetMs));
19
+ }
20
+ return mergeResults(results);
21
+ }
22
+ /** One slice with every story, unless the pass outlasts the lifetime a token can have. */
23
+ function slicesOf(input) {
24
+ const { stories } = input.request;
25
+ const counts = stories.map((story) => input.captureCount(story));
26
+ const expected = counts.reduce((sum, count) => sum + count, 0);
27
+ const whole = [{
28
+ stories,
29
+ expected
30
+ }];
31
+ const ttl = input.storybookUrl?.ttlSeconds?.(input.browser, renderBudgetMs(expected, input.renderTimeoutMs));
32
+ const budgetSeconds = renderBudgetMs(expected, input.renderTimeoutMs) / 1e3;
33
+ if (ttl === void 0 || input.renderTimeoutMs !== void 0 || budgetSeconds + 300 <= ttl) return whole;
34
+ return cut(stories, counts, Math.max(50, Math.floor((ttl - 300) * 1e3 / PER_CAPTURE_BUDGET_MS)));
35
+ }
36
+ function cut(stories, counts, limit) {
37
+ const slices = [];
38
+ let current = {
39
+ stories: [],
40
+ expected: 0
41
+ };
42
+ for (const [index, story] of stories.entries()) {
43
+ const count = counts[index] ?? 0;
44
+ if (current.stories.length > 0 && current.expected + count > limit) {
45
+ slices.push(current);
46
+ current = {
47
+ stories: [],
48
+ expected: 0
49
+ };
50
+ }
51
+ current.stories.push(story);
52
+ current.expected += count;
53
+ }
54
+ return [...slices, current];
55
+ }
56
+ function mergeResults(results) {
57
+ const [only] = results;
58
+ if (results.length === 1 && only) return only;
59
+ const environment = results.find((result) => result.environment)?.environment;
60
+ return {
61
+ captures: results.flatMap((result) => tagged(result)),
62
+ failures: results.flatMap((result) => result.failures),
63
+ ...environment ? { environment } : {}
64
+ };
65
+ }
66
+ /** A slice's captures with the environment that slice reported (a reconnect may differ). */
67
+ function tagged(result) {
68
+ for (const capture of result.captures) if (result.environment) capture.environment ??= result.environment;
69
+ return result.captures;
70
+ }
71
+ //#endregion
72
+ export { renderInSlices };
73
+
74
+ //# sourceMappingURL=token-chunks.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"token-chunks.mjs","names":[],"sources":["../../src/capture/token-chunks.ts"],"sourcesContent":["/**\n * Renders a pass in slices that each fit one signed Storybook URL (ADR 0007, decision 5). A token\n * never lives longer than `MAX_STORYBOOK_URL_TTL` (and a project may set it lower), so a pass whose\n * budget outlasts that is cut into slices of stories and every slice asks the source for a fresh\n * token just before it starts: the render never dies when its token does. A pass that fits one\n * token (the usual case, and every target without a signed URL) is one render call, as before.\n */\nimport type { CaptureTarget, CaptureRunner, RenderResult } from \"../adapters/capture-runner.ts\";\nimport {\n MIN_CAPTURES_PER_SLICE,\n PER_CAPTURE_BUDGET_MS,\n STORYBOOK_URL_TTL_GRACE,\n} from \"../utils/storybook-token.ts\";\nimport type { StoryEntry } from \"./adapter.ts\";\nimport { renderBudgetMs, renderWithTimeout } from \"./render.ts\";\nimport type { RenderRequest } from \"./render.ts\";\nimport type { StorybookUrlSource } from \"./storybook-urls.ts\";\n\n/** What cutting a pass into slices needs of its caller. */\nexport interface SliceInput {\n runner: CaptureRunner;\n /** The render call without its `storybookUrl`; its `stories` are the whole pass. */\n request: RenderRequest;\n browser: CaptureTarget;\n storybookUrl: StorybookUrlSource | undefined;\n /** Captures one story expands to (its viewports and modes). */\n captureCount: (story: StoryEntry) => number;\n /** An explicit budget fixes one call's timeout; slices then are not budgeted separately. */\n renderTimeoutMs: number | undefined;\n}\n\n/** Render the pass, minting a fresh signed URL for each slice; results are concatenated. */\nexport async function renderInSlices(input: SliceInput): Promise<RenderResult> {\n const slices = slicesOf(input);\n const results: RenderResult[] = [];\n for (const slice of slices) {\n const budgetMs = renderBudgetMs(slice.expected, input.renderTimeoutMs);\n // oxlint-disable-next-line no-await-in-loop -- each slice needs a token minted just before it\n const storybookUrl = await input.storybookUrl?.(input.browser, { budgetMs });\n results.push(\n // oxlint-disable-next-line no-await-in-loop -- slices render one after another\n await renderWithTimeout(\n input.runner,\n {\n ...input.request,\n stories: slice.stories,\n ...(storybookUrl === undefined ? {} : { storybookUrl }),\n },\n budgetMs,\n ),\n );\n }\n return mergeResults(results);\n}\n\ninterface Slice {\n stories: StoryEntry[];\n expected: number;\n}\n\n/** One slice with every story, unless the pass outlasts the lifetime a token can have. */\nfunction slicesOf(input: SliceInput): Slice[] {\n const { stories } = input.request;\n const counts = stories.map((story) => input.captureCount(story));\n const expected = counts.reduce((sum, count) => sum + count, 0);\n const whole: Slice[] = [{ stories, expected }];\n const ttl = input.storybookUrl?.ttlSeconds?.(\n input.browser,\n renderBudgetMs(expected, input.renderTimeoutMs),\n );\n const budgetSeconds = renderBudgetMs(expected, input.renderTimeoutMs) / 1000;\n if (\n ttl === undefined ||\n input.renderTimeoutMs !== undefined ||\n budgetSeconds + STORYBOOK_URL_TTL_GRACE <= ttl\n ) {\n return whole;\n }\n const limit = Math.max(\n MIN_CAPTURES_PER_SLICE,\n Math.floor(((ttl - STORYBOOK_URL_TTL_GRACE) * 1000) / PER_CAPTURE_BUDGET_MS),\n );\n return cut(stories, counts, limit);\n}\n\nfunction cut(stories: StoryEntry[], counts: number[], limit: number): Slice[] {\n const slices: Slice[] = [];\n let current: Slice = { stories: [], expected: 0 };\n for (const [index, story] of stories.entries()) {\n const count = counts[index] ?? 0;\n if (current.stories.length > 0 && current.expected + count > limit) {\n slices.push(current);\n current = { stories: [], expected: 0 };\n }\n current.stories.push(story);\n current.expected += count;\n }\n return [...slices, current];\n}\n\nfunction mergeResults(results: RenderResult[]): RenderResult {\n const [only] = results;\n if (results.length === 1 && only) {\n return only;\n }\n const environment = results.find((result) => result.environment)?.environment;\n return {\n captures: results.flatMap((result) => tagged(result)),\n failures: results.flatMap((result) => result.failures),\n ...(environment ? { environment } : {}),\n };\n}\n\n/** A slice's captures with the environment that slice reported (a reconnect may differ). */\nfunction tagged(result: RenderResult): RenderResult[\"captures\"] {\n for (const capture of result.captures) {\n if (result.environment) {\n capture.environment ??= result.environment;\n }\n }\n return result.captures;\n}\n"],"mappings":";;;;;;;AAgCA,eAAsB,eAAe,OAA0C;CAC7E,MAAM,SAAS,SAAS,KAAK;CAC7B,MAAM,UAA0B,CAAC;CACjC,KAAK,MAAM,SAAS,QAAQ;EAC1B,MAAM,WAAW,eAAe,MAAM,UAAU,MAAM,eAAe;EAErE,MAAM,eAAe,MAAM,MAAM,eAAe,MAAM,SAAS,EAAE,SAAS,CAAC;EAC3E,QAAQ,KAEN,MAAM,kBACJ,MAAM,QACN;GACE,GAAG,MAAM;GACT,SAAS,MAAM;GACf,GAAI,iBAAiB,KAAA,IAAY,CAAC,IAAI,EAAE,aAAa;EACvD,GACA,QACF,CACF;CACF;CACA,OAAO,aAAa,OAAO;AAC7B;;AAQA,SAAS,SAAS,OAA4B;CAC5C,MAAM,EAAE,YAAY,MAAM;CAC1B,MAAM,SAAS,QAAQ,KAAK,UAAU,MAAM,aAAa,KAAK,CAAC;CAC/D,MAAM,WAAW,OAAO,QAAQ,KAAK,UAAU,MAAM,OAAO,CAAC;CAC7D,MAAM,QAAiB,CAAC;EAAE;EAAS;CAAS,CAAC;CAC7C,MAAM,MAAM,MAAM,cAAc,aAC9B,MAAM,SACN,eAAe,UAAU,MAAM,eAAe,CAChD;CACA,MAAM,gBAAgB,eAAe,UAAU,MAAM,eAAe,IAAI;CACxE,IACE,QAAQ,KAAA,KACR,MAAM,oBAAoB,KAAA,KAC1B,gBAAA,OAA2C,KAE3C,OAAO;CAMT,OAAO,IAAI,SAAS,QAJN,KAAK,IAAA,IAEjB,KAAK,OAAQ,MAAA,OAAiC,MAAQ,qBAAqB,CAE7C,CAAC;AACnC;AAEA,SAAS,IAAI,SAAuB,QAAkB,OAAwB;CAC5E,MAAM,SAAkB,CAAC;CACzB,IAAI,UAAiB;EAAE,SAAS,CAAC;EAAG,UAAU;CAAE;CAChD,KAAK,MAAM,CAAC,OAAO,UAAU,QAAQ,QAAQ,GAAG;EAC9C,MAAM,QAAQ,OAAO,UAAU;EAC/B,IAAI,QAAQ,QAAQ,SAAS,KAAK,QAAQ,WAAW,QAAQ,OAAO;GAClE,OAAO,KAAK,OAAO;GACnB,UAAU;IAAE,SAAS,CAAC;IAAG,UAAU;GAAE;EACvC;EACA,QAAQ,QAAQ,KAAK,KAAK;EAC1B,QAAQ,YAAY;CACtB;CACA,OAAO,CAAC,GAAG,QAAQ,OAAO;AAC5B;AAEA,SAAS,aAAa,SAAuC;CAC3D,MAAM,CAAC,QAAQ;CACf,IAAI,QAAQ,WAAW,KAAK,MAC1B,OAAO;CAET,MAAM,cAAc,QAAQ,MAAM,WAAW,OAAO,WAAW,CAAC,EAAE;CAClE,OAAO;EACL,UAAU,QAAQ,SAAS,WAAW,OAAO,MAAM,CAAC;EACpD,UAAU,QAAQ,SAAS,WAAW,OAAO,QAAQ;EACrD,GAAI,cAAc,EAAE,YAAY,IAAI,CAAC;CACvC;AACF;;AAGA,SAAS,OAAO,QAAgD;CAC9D,KAAK,MAAM,WAAW,OAAO,UAC3B,IAAI,OAAO,aACT,QAAQ,gBAAgB,OAAO;CAGnC,OAAO,OAAO;AAChB"}
@@ -1,14 +1,67 @@
1
1
  import __tsdown_shims_path from 'node:path';
2
2
  import __tsdown_shims_url from 'node:url';
3
- import { DEFAULT_VIEWPORTS, StoryEntry, StoryParameters, StorySourceAdapter, StoryViewportConfig, StoryViewportDefinition, Viewport, isDisabledStory, isFlakyStory } from "./capture/adapter.mjs";
4
- import { PollableCaptureQueue, PollableJob } from "./adapter/capture-queue.mjs";
3
+ import { DEFAULT_VIEWPORTS, ModeDefinition, ModeMap, ModeViewportValue, StoryEntry, StoryParameters, StorySourceAdapter, StoryViewportConfig, StoryViewportDefinition, Viewport, isDisabledStory, isFlakyStory } from "./capture/adapter.mjs";
4
+ import { LeaseRenewal, PollableCaptureQueue, PollableJob } from "./adapter/capture-queue.mjs";
5
+ import { MAX_BROWSERS, assertBrowserCount, assertSupportedBrowsers, listTargets, parseBrowsers, primaryTargetOf, refusalFor, resolveBrowsers } from "./capture/browsers.mjs";
6
+ import { NO_ORIGIN_REASON, NO_SECRET_REASON, TargetPrerequisites, offeredTargets } from "./capture/targets.mjs";
7
+ import { StorybookUrlSource, storybookUrlSource } from "./capture/storybook-urls.mjs";
8
+ import { MAX_MODES_PER_STORY, buildGlobalsParam, filterModes, modeSlug, parseModesAllowlist } from "./capture/modes.mjs";
9
+ import { TestResult, TestSummary, parseTestResults, summarizeTests } from "./capture/tests.mjs";
10
+ import { JobLease, ProgressLease } from "./capture/job-lease.mjs";
5
11
  import { CaptureContext, persistCapture } from "./capture/pipeline.mjs";
12
+ import { DEFAULT_MAX_INLINE_UNZIP_SIZE, DEFAULT_MAX_UNZIPPED_BYTES, DEFAULT_MAX_ZIP_ENTRIES, ExtractionLimits, FILE_BY_FILE_HINT, PublishLimits, ZipLimitError, extractionLimitsOf, publishRoute, resolvePublishLimits } from "./capture/publish/limits.mjs";
6
13
  import { CaptureAttemptRef, CaptureJobInput, CaptureJobOptions, executeCaptureJob } from "./capture/orchestrator.mjs";
7
- import { REDIFFABLE_BUILD_STATUSES, RediffDeps, RediffResult, rediffBuild } from "./capture/rediff.mjs";
14
+ import { SCRATCH_DIRNAME, SCRATCH_MAX_AGE_MS, ScratchSweepOptions, buildScratchDir, removeBuildScratch, removeJobScratch, sweepOrphanedScratch } from "./capture/scratch.mjs";
15
+ import { BoundingBox, SIZING_DEFAULTS, ScreenshotPlan, SizingOptions, getScreenshotPlan, resolveViewports } from "./capture/sizing.mjs";
16
+ import { EnvironmentChange, Fingerprint, buildFingerprint, changedFields, fingerprintHash, parseFingerprint } from "./capture/fingerprint.mjs";
17
+ import { axeInjectionScript, loadAxeSource } from "./capture/a11y/axe-source.mjs";
18
+ import { MAX_REPORTED_VIOLATIONS, SlimViolation, mapAxeViolations } from "./capture/a11y/map.mjs";
19
+ import { A11Y_ROOT_SELECTOR, A11yRunPlan, resolveA11yRun } from "./capture/a11y/options.mjs";
20
+ import { inPageReadA11yParameters, inPageRunAxe } from "./capture/a11y/in-page.mjs";
21
+ import { BuildStateDeps, BuildStatePublisher, SkipReason, StateTarget } from "./capture/build-state/types.mjs";
22
+ import { deliverBuildState, loadBuild, stateTargets, writeTo } from "./capture/build-state/deliver.mjs";
23
+ import { ACTIVE_POLL_MS, ACTIVE_WINDOW_MS, CANCEL_CHECK_MS, DEFAULT_CADENCE, IDLE_POLL_MS, POLL_JITTER, PollCadence, nextPollDelay } from "./capture/db-queue/cadence.mjs";
8
24
  import { CaptureDispatchJob, DispatchDeps, createDispatchJob } from "./capture/dispatch.mjs";
9
- import { INTERRUPTED_ERROR, RecoveryDeps, RecoveryResult, recoverStuckCaptures } from "./capture/recovery.mjs";
10
- import { InMemoryCaptureQueue, InMemoryCaptureQueueOptions } from "./capture/queue.mjs";
25
+ import { CaptureHandlerOptions, captureDispatchDeps, createCaptureHandler } from "./capture/consumer/capture-handler.mjs";
26
+ import { ConsumerMetrics, DEFAULT_SAMPLE_MS, JobFinishedEvent, JobOutcome, QueueSample, sampleQueue } from "./capture/consumer/metrics.mjs";
27
+ import { DEFAULT_BACKOFF_MS, DEFAULT_MAX_RETRIES, DEFAULT_WAIT_TIME_SECONDS, MAX_BACKOFF_MS, RetryConfig, backoffDelayMs, isFinalAttempt } from "./capture/consumer/retry.mjs";
28
+ import { CaptureConsumer, CaptureConsumerOptions, ConsumerConfig, ConsumerJob, JobHandlers, JobRunContext, KindHandler } from "./capture/consumer/types.mjs";
29
+ import { DEFAULT_LEASE_MS, DEFAULT_RETRIES, DatabaseCaptureQueue, DatabaseCaptureQueueOptions, DatabaseJob, QueueJobInput } from "./capture/db-queue/types.mjs";
30
+ import { NOTIFY_BACKOFF, NOTIFY_MAX_ATTEMPTS, NotifyFailure, NotifyHandlerOptions, NotifyJobQueue, createNotifyEnqueuer, createNotifyHandler, notifyExhausted } from "./capture/build-state/notify-job.mjs";
31
+ import { BuildStatePublisherOptions, PAUSED_MESSAGE, createBuildStatePublisher } from "./capture/build-state/publisher.mjs";
32
+ import { requestOpenBuildStates } from "./capture/build-state/resume.mjs";
33
+ import "./capture/build-state/index.mjs";
34
+ import { REDIFFABLE_BUILD_STATUSES, RediffDeps, RediffResult, rediffBuild } from "./capture/rediff.mjs";
35
+ import { CrashFailureOutcome, failCrashedCapture } from "./capture/crash-failure.mjs";
36
+ import { LEASE_EXHAUSTED_ERROR } from "./capture/db-queue/claim.mjs";
37
+ import { MAX_NACK_DELAY_MS } from "./capture/db-queue/poll.mjs";
38
+ import { DATABASE_QUEUE_METADATA, createDatabaseCaptureQueue } from "./capture/db-queue/index.mjs";
39
+ import { JobLeaseKeeper, LeaseEnd, LeaseKeeperOptions, RENEW_THROTTLE_MS, keepJobLease } from "./capture/db-queue/keeper.mjs";
40
+ import { PollLoop, PollLoopOptions, startPollLoop } from "./capture/db-queue/poll-loop.mjs";
41
+ import { MIN_BLOCKING_POLL_MS, idleDelayMs, isFastEmptyPoll } from "./capture/consumer/idle.mjs";
42
+ import { createCaptureConsumer } from "./capture/consumer/index.mjs";
43
+ import { ChildMessage, ParentMessage } from "./capture/forked/protocol.mjs";
44
+ import { CaptureChildOptions, ChildHost, runCaptureChild } from "./capture/forked/child.mjs";
11
45
  import { STORYBOOK_BUILTIN_VIEWPORTS, StorybookAdapter, mergeParameters, resolveStoryViewports } from "./capture/storybook.mjs";
12
46
  import { extractStorybookToScratch, persistStorybookStatics } from "./capture/statics.mjs";
13
- import { BoundingBox, SIZING_DEFAULTS, ScreenshotPlan, SizingOptions, getScreenshotPlan, resolveViewports } from "./capture/sizing.mjs";
14
- export { type BoundingBox, type CaptureAttemptRef, type CaptureContext, type CaptureDispatchJob, type CaptureJobInput, type CaptureJobOptions, DEFAULT_VIEWPORTS, type DispatchDeps, INTERRUPTED_ERROR, InMemoryCaptureQueue, type InMemoryCaptureQueueOptions, type PollableCaptureQueue, type PollableJob, REDIFFABLE_BUILD_STATUSES, type RecoveryDeps, type RecoveryResult, type RediffDeps, type RediffResult, SIZING_DEFAULTS, STORYBOOK_BUILTIN_VIEWPORTS, type ScreenshotPlan, type SizingOptions, type StoryEntry, type StoryParameters, type StorySourceAdapter, type StoryViewportConfig, type StoryViewportDefinition, StorybookAdapter, type Viewport, createDispatchJob, executeCaptureJob, extractStorybookToScratch, getScreenshotPlan, isDisabledStory, isFlakyStory, mergeParameters, persistCapture, persistStorybookStatics, recoverStuckCaptures, rediffBuild, resolveViewports as resolveCaptureViewports, resolveStoryViewports };
47
+ import { AfterPublishContext, AfterPublishHook, PublishCompleter, PublishCompleterOptions, PublishOutcome, createPublishCompleter } from "./capture/publish/complete.mjs";
48
+ import { PublishHandlerOptions, createPublishHandler } from "./capture/publish/handler.mjs";
49
+ import { PublishFacts, publishVerdict } from "./capture/publish/accept.mjs";
50
+ import { publishingOf } from "./capture/publish/published.mjs";
51
+ import { ExtractionResult, extractZipStream } from "./capture/publish/extract.mjs";
52
+ import { PUBLISH_SCRATCH_ID, PublishZipOptions, publishStoredZip } from "./capture/publish/run.mjs";
53
+ import "./capture/publish/index.mjs";
54
+ import { Catalog, CatalogComponent, CatalogEntry } from "./capture/catalog/types.mjs";
55
+ import { CatalogDeps, catalogueBuild, readCatalog } from "./capture/catalog/catalogue.mjs";
56
+ import { CatalogLoader, CatalogLoaderOptions, DEFAULT_CATALOG_CACHE_SIZE, createCatalogLoader } from "./capture/catalog/load.mjs";
57
+ import { createCatalogHook } from "./capture/catalog/hook.mjs";
58
+ import { EntryChanges, diffEntries, groupComponents, hashEntries, toBuildComponent } from "./capture/catalog/components.mjs";
59
+ import { parseStorybookIndex, parseStorybookIndexText } from "./capture/catalog/parse.mjs";
60
+ import { readPublishedFile } from "./capture/catalog/read.mjs";
61
+ import { ComponentBuildRow, ComponentChange, catalogPresence, componentBuildHistory } from "./capture/catalog/history.mjs";
62
+ import "./capture/catalog/index.mjs";
63
+ import { ChildProcessHandle, ParentPort } from "./capture/forked/channel.mjs";
64
+ import { ForkedCaptureHandler, ForkedCaptureOptions, createForkedCaptureHandler } from "./capture/forked/forked-capture.mjs";
65
+ import { CAPTURE_RETRIES_ENV, CAPTURE_SHARD_SIZE_ENV, CAPTURE_WORKER_ROLE, ForkOptions, canForkCaptureChild, forkCaptureChild } from "./capture/forked/fork.mjs";
66
+ import { FORK_MIN_CPUS, FORK_MIN_MEMORY_BYTES, ForkDecision, ForkHost, decideCaptureProcess } from "./capture/forked/decision.mjs";
67
+ export { A11Y_ROOT_SELECTOR, type A11yRunPlan, ACTIVE_POLL_MS, ACTIVE_WINDOW_MS, type AfterPublishContext, type AfterPublishHook, type BoundingBox, type BuildStateDeps, type BuildStatePublisher, type BuildStatePublisherOptions, CANCEL_CHECK_MS, CAPTURE_RETRIES_ENV, CAPTURE_SHARD_SIZE_ENV, CAPTURE_WORKER_ROLE, type CaptureAttemptRef, type CaptureChildOptions, type CaptureConsumer, type CaptureConsumerOptions, type CaptureContext, type CaptureDispatchJob, type CaptureHandlerOptions, type CaptureJobInput, type CaptureJobOptions, type Catalog, type CatalogComponent, type CatalogDeps, type CatalogEntry, type CatalogLoader, type CatalogLoaderOptions, type ChildHost, type ChildMessage, type ChildProcessHandle, type ComponentBuildRow, type ComponentChange, type ConsumerConfig, type ConsumerJob, type ConsumerMetrics, type CrashFailureOutcome, DATABASE_QUEUE_METADATA, DEFAULT_BACKOFF_MS, DEFAULT_CADENCE, DEFAULT_CATALOG_CACHE_SIZE, DEFAULT_LEASE_MS, DEFAULT_MAX_INLINE_UNZIP_SIZE, DEFAULT_MAX_RETRIES, DEFAULT_MAX_UNZIPPED_BYTES, DEFAULT_MAX_ZIP_ENTRIES, DEFAULT_RETRIES, DEFAULT_SAMPLE_MS, DEFAULT_VIEWPORTS, DEFAULT_WAIT_TIME_SECONDS, type DatabaseCaptureQueue, type DatabaseCaptureQueueOptions, type DatabaseJob, type DispatchDeps, type EntryChanges, type EnvironmentChange, type ExtractionLimits, type ExtractionResult, FILE_BY_FILE_HINT, FORK_MIN_CPUS, FORK_MIN_MEMORY_BYTES, type Fingerprint, type ForkDecision, type ForkHost, type ForkOptions, type ForkedCaptureHandler, type ForkedCaptureOptions, IDLE_POLL_MS, type JobFinishedEvent, type JobHandlers, type JobLease, type JobLeaseKeeper, type JobOutcome, type JobRunContext, type KindHandler, LEASE_EXHAUSTED_ERROR, type LeaseEnd, type LeaseKeeperOptions, type LeaseRenewal, MAX_BACKOFF_MS, MAX_BROWSERS, MAX_MODES_PER_STORY, MAX_NACK_DELAY_MS, MAX_REPORTED_VIOLATIONS, MIN_BLOCKING_POLL_MS, type ModeDefinition, type ModeMap, type ModeViewportValue, NOTIFY_BACKOFF, NOTIFY_MAX_ATTEMPTS, NO_ORIGIN_REASON, NO_SECRET_REASON, type NotifyFailure, type NotifyHandlerOptions, type NotifyJobQueue, PAUSED_MESSAGE, POLL_JITTER, PUBLISH_SCRATCH_ID, type ParentMessage, type ParentPort, type PollCadence, type PollLoop, type PollLoopOptions, type PollableCaptureQueue, type PollableJob, ProgressLease, type PublishCompleter, type PublishCompleterOptions, type PublishFacts, type PublishHandlerOptions, type PublishLimits, type PublishOutcome, type PublishZipOptions, type QueueJobInput, type QueueSample, REDIFFABLE_BUILD_STATUSES, RENEW_THROTTLE_MS, type RediffDeps, type RediffResult, type RetryConfig, SCRATCH_DIRNAME, SCRATCH_MAX_AGE_MS, SIZING_DEFAULTS, STORYBOOK_BUILTIN_VIEWPORTS, type ScratchSweepOptions, type ScreenshotPlan, type SizingOptions, type SkipReason, type SlimViolation, type StateTarget, type StoryEntry, type StoryParameters, type StorySourceAdapter, type StoryViewportConfig, type StoryViewportDefinition, StorybookAdapter, type StorybookUrlSource, type TargetPrerequisites, type TestResult, type TestSummary, type Viewport, ZipLimitError, assertBrowserCount, assertSupportedBrowsers, axeInjectionScript, backoffDelayMs, buildFingerprint, buildGlobalsParam, buildScratchDir, canForkCaptureChild, captureDispatchDeps, catalogPresence, catalogueBuild, changedFields, componentBuildHistory, createBuildStatePublisher, createCaptureConsumer, createCaptureHandler, createCatalogHook, createCatalogLoader, createDatabaseCaptureQueue, createDispatchJob, createForkedCaptureHandler, createNotifyEnqueuer, createNotifyHandler, createPublishCompleter, createPublishHandler, decideCaptureProcess, deliverBuildState, diffEntries, executeCaptureJob, extractStorybookToScratch, extractZipStream, extractionLimitsOf, failCrashedCapture, filterModes, fingerprintHash, forkCaptureChild, getScreenshotPlan, groupComponents, hashEntries, idleDelayMs, inPageReadA11yParameters, inPageRunAxe, isDisabledStory, isFastEmptyPoll, isFinalAttempt, isFlakyStory, keepJobLease, listTargets, loadAxeSource, loadBuild, mapAxeViolations, mergeParameters, modeSlug, nextPollDelay, notifyExhausted, offeredTargets, parseBrowsers, parseFingerprint, parseModesAllowlist, parseStorybookIndex, parseStorybookIndexText, parseTestResults, persistCapture, persistStorybookStatics, primaryTargetOf, publishRoute, publishStoredZip, publishVerdict, publishingOf, readCatalog, readPublishedFile, rediffBuild, refusalFor, removeBuildScratch, removeJobScratch, requestOpenBuildStates, resolveA11yRun, resolveBrowsers, resolveViewports as resolveCaptureViewports, resolvePublishLimits, resolveStoryViewports, runCaptureChild, sampleQueue, startPollLoop, stateTargets, storybookUrlSource, summarizeTests, sweepOrphanedScratch, toBuildComponent, writeTo };
package/dist/capture.mjs CHANGED
@@ -1,14 +1,59 @@
1
1
  import "node:path";
2
2
  import "node:url";
3
3
  import.meta.url;
4
+ import { MAX_BROWSERS, assertBrowserCount, assertSupportedBrowsers, listTargets, parseBrowsers, primaryTargetOf, refusalFor, resolveBrowsers } from "./capture/browsers.mjs";
5
+ import { NO_ORIGIN_REASON, NO_SECRET_REASON, offeredTargets } from "./capture/targets.mjs";
6
+ import { storybookUrlSource } from "./capture/storybook-urls.mjs";
7
+ import { MAX_MODES_PER_STORY, buildGlobalsParam, filterModes, modeSlug, parseModesAllowlist } from "./capture/modes.mjs";
4
8
  import { DEFAULT_VIEWPORTS, isDisabledStory, isFlakyStory } from "./capture/adapter.mjs";
5
9
  import { STORYBOOK_BUILTIN_VIEWPORTS, StorybookAdapter, mergeParameters, resolveStoryViewports } from "./capture/storybook.mjs";
10
+ import { parseTestResults, summarizeTests } from "./capture/tests.mjs";
6
11
  import { SIZING_DEFAULTS, getScreenshotPlan, resolveViewports } from "./capture/sizing.mjs";
12
+ import { buildFingerprint, changedFields, fingerprintHash, parseFingerprint } from "./capture/fingerprint.mjs";
7
13
  import { persistCapture } from "./capture/pipeline.mjs";
14
+ import { SCRATCH_DIRNAME, SCRATCH_MAX_AGE_MS, buildScratchDir, removeBuildScratch, removeJobScratch, sweepOrphanedScratch } from "./capture/scratch.mjs";
15
+ import { DEFAULT_MAX_INLINE_UNZIP_SIZE, DEFAULT_MAX_UNZIPPED_BYTES, DEFAULT_MAX_ZIP_ENTRIES, FILE_BY_FILE_HINT, ZipLimitError, extractionLimitsOf, publishRoute, resolvePublishLimits } from "./capture/publish/limits.mjs";
16
+ import { extractZipStream } from "./capture/publish/extract.mjs";
8
17
  import { extractStorybookToScratch, persistStorybookStatics } from "./capture/statics.mjs";
9
18
  import { executeCaptureJob } from "./capture/orchestrator.mjs";
19
+ import { axeInjectionScript, loadAxeSource } from "./capture/a11y/axe-source.mjs";
20
+ import { inPageReadA11yParameters, inPageRunAxe } from "./capture/a11y/in-page.mjs";
21
+ import { MAX_REPORTED_VIOLATIONS, mapAxeViolations } from "./capture/a11y/map.mjs";
22
+ import { A11Y_ROOT_SELECTOR, resolveA11yRun } from "./capture/a11y/options.mjs";
23
+ import { publishingOf } from "./capture/publish/published.mjs";
24
+ import { deliverBuildState, loadBuild, stateTargets, writeTo } from "./capture/build-state/deliver.mjs";
25
+ import { DEFAULT_BACKOFF_MS, DEFAULT_MAX_RETRIES, DEFAULT_WAIT_TIME_SECONDS, MAX_BACKOFF_MS, backoffDelayMs, isFinalAttempt } from "./capture/consumer/retry.mjs";
26
+ import { NOTIFY_BACKOFF, NOTIFY_MAX_ATTEMPTS, createNotifyEnqueuer, createNotifyHandler, notifyExhausted } from "./capture/build-state/notify-job.mjs";
27
+ import { PAUSED_MESSAGE, createBuildStatePublisher } from "./capture/build-state/publisher.mjs";
28
+ import { requestOpenBuildStates } from "./capture/build-state/resume.mjs";
10
29
  import { REDIFFABLE_BUILD_STATUSES, rediffBuild } from "./capture/rediff.mjs";
11
- import { INTERRUPTED_ERROR, recoverStuckCaptures } from "./capture/recovery.mjs";
12
- import { InMemoryCaptureQueue } from "./capture/queue.mjs";
30
+ import { failCrashedCapture } from "./capture/crash-failure.mjs";
31
+ import { ProgressLease } from "./capture/job-lease.mjs";
32
+ import { LEASE_EXHAUSTED_ERROR } from "./capture/db-queue/claim.mjs";
33
+ import { MAX_NACK_DELAY_MS } from "./capture/db-queue/poll.mjs";
34
+ import { DEFAULT_LEASE_MS, DEFAULT_RETRIES } from "./capture/db-queue/types.mjs";
35
+ import { DATABASE_QUEUE_METADATA, createDatabaseCaptureQueue } from "./capture/db-queue/index.mjs";
36
+ import { ACTIVE_POLL_MS, ACTIVE_WINDOW_MS, CANCEL_CHECK_MS, DEFAULT_CADENCE, IDLE_POLL_MS, POLL_JITTER, nextPollDelay } from "./capture/db-queue/cadence.mjs";
37
+ import { RENEW_THROTTLE_MS, keepJobLease } from "./capture/db-queue/keeper.mjs";
38
+ import { startPollLoop } from "./capture/db-queue/poll-loop.mjs";
13
39
  import { createDispatchJob } from "./capture/dispatch.mjs";
14
- export { DEFAULT_VIEWPORTS, INTERRUPTED_ERROR, InMemoryCaptureQueue, REDIFFABLE_BUILD_STATUSES, SIZING_DEFAULTS, STORYBOOK_BUILTIN_VIEWPORTS, StorybookAdapter, createDispatchJob, executeCaptureJob, extractStorybookToScratch, getScreenshotPlan, isDisabledStory, isFlakyStory, mergeParameters, persistCapture, persistStorybookStatics, recoverStuckCaptures, rediffBuild, resolveViewports as resolveCaptureViewports, resolveStoryViewports };
40
+ import { captureDispatchDeps, createCaptureHandler } from "./capture/consumer/capture-handler.mjs";
41
+ import { MIN_BLOCKING_POLL_MS, idleDelayMs, isFastEmptyPoll } from "./capture/consumer/idle.mjs";
42
+ import { DEFAULT_SAMPLE_MS, sampleQueue } from "./capture/consumer/metrics.mjs";
43
+ import { createCaptureConsumer } from "./capture/consumer/index.mjs";
44
+ import { CAPTURE_RETRIES_ENV, CAPTURE_SHARD_SIZE_ENV, CAPTURE_WORKER_ROLE, canForkCaptureChild, forkCaptureChild } from "./capture/forked/fork.mjs";
45
+ import { runCaptureChild } from "./capture/forked/child.mjs";
46
+ import { PUBLISH_SCRATCH_ID, publishStoredZip } from "./capture/publish/run.mjs";
47
+ import { createPublishHandler } from "./capture/publish/handler.mjs";
48
+ import { publishVerdict } from "./capture/publish/accept.mjs";
49
+ import { createPublishCompleter } from "./capture/publish/complete.mjs";
50
+ import { createCatalogHook } from "./capture/catalog/hook.mjs";
51
+ import { diffEntries, groupComponents, hashEntries, toBuildComponent } from "./capture/catalog/components.mjs";
52
+ import { parseStorybookIndex, parseStorybookIndexText } from "./capture/catalog/parse.mjs";
53
+ import { readPublishedFile } from "./capture/catalog/read.mjs";
54
+ import { catalogueBuild, readCatalog } from "./capture/catalog/catalogue.mjs";
55
+ import { DEFAULT_CATALOG_CACHE_SIZE, createCatalogLoader } from "./capture/catalog/load.mjs";
56
+ import { catalogPresence, componentBuildHistory } from "./capture/catalog/history.mjs";
57
+ import { createForkedCaptureHandler } from "./capture/forked/forked-capture.mjs";
58
+ import { FORK_MIN_CPUS, FORK_MIN_MEMORY_BYTES, decideCaptureProcess } from "./capture/forked/decision.mjs";
59
+ export { A11Y_ROOT_SELECTOR, ACTIVE_POLL_MS, ACTIVE_WINDOW_MS, CANCEL_CHECK_MS, CAPTURE_RETRIES_ENV, CAPTURE_SHARD_SIZE_ENV, CAPTURE_WORKER_ROLE, DATABASE_QUEUE_METADATA, DEFAULT_BACKOFF_MS, DEFAULT_CADENCE, DEFAULT_CATALOG_CACHE_SIZE, DEFAULT_LEASE_MS, DEFAULT_MAX_INLINE_UNZIP_SIZE, DEFAULT_MAX_RETRIES, DEFAULT_MAX_UNZIPPED_BYTES, DEFAULT_MAX_ZIP_ENTRIES, DEFAULT_RETRIES, DEFAULT_SAMPLE_MS, DEFAULT_VIEWPORTS, DEFAULT_WAIT_TIME_SECONDS, FILE_BY_FILE_HINT, FORK_MIN_CPUS, FORK_MIN_MEMORY_BYTES, IDLE_POLL_MS, LEASE_EXHAUSTED_ERROR, MAX_BACKOFF_MS, MAX_BROWSERS, MAX_MODES_PER_STORY, MAX_NACK_DELAY_MS, MAX_REPORTED_VIOLATIONS, MIN_BLOCKING_POLL_MS, NOTIFY_BACKOFF, NOTIFY_MAX_ATTEMPTS, NO_ORIGIN_REASON, NO_SECRET_REASON, PAUSED_MESSAGE, POLL_JITTER, PUBLISH_SCRATCH_ID, ProgressLease, REDIFFABLE_BUILD_STATUSES, RENEW_THROTTLE_MS, SCRATCH_DIRNAME, SCRATCH_MAX_AGE_MS, SIZING_DEFAULTS, STORYBOOK_BUILTIN_VIEWPORTS, StorybookAdapter, ZipLimitError, assertBrowserCount, assertSupportedBrowsers, axeInjectionScript, backoffDelayMs, buildFingerprint, buildGlobalsParam, buildScratchDir, canForkCaptureChild, captureDispatchDeps, catalogPresence, catalogueBuild, changedFields, componentBuildHistory, createBuildStatePublisher, createCaptureConsumer, createCaptureHandler, createCatalogHook, createCatalogLoader, createDatabaseCaptureQueue, createDispatchJob, createForkedCaptureHandler, createNotifyEnqueuer, createNotifyHandler, createPublishCompleter, createPublishHandler, decideCaptureProcess, deliverBuildState, diffEntries, executeCaptureJob, extractStorybookToScratch, extractZipStream, extractionLimitsOf, failCrashedCapture, filterModes, fingerprintHash, forkCaptureChild, getScreenshotPlan, groupComponents, hashEntries, idleDelayMs, inPageReadA11yParameters, inPageRunAxe, isDisabledStory, isFastEmptyPoll, isFinalAttempt, isFlakyStory, keepJobLease, listTargets, loadAxeSource, loadBuild, mapAxeViolations, mergeParameters, modeSlug, nextPollDelay, notifyExhausted, offeredTargets, parseBrowsers, parseFingerprint, parseModesAllowlist, parseStorybookIndex, parseStorybookIndexText, parseTestResults, persistCapture, persistStorybookStatics, primaryTargetOf, publishRoute, publishStoredZip, publishVerdict, publishingOf, readCatalog, readPublishedFile, rediffBuild, refusalFor, removeBuildScratch, removeJobScratch, requestOpenBuildStates, resolveA11yRun, resolveBrowsers, resolveViewports as resolveCaptureViewports, resolvePublishLimits, resolveStoryViewports, runCaptureChild, sampleQueue, startPollLoop, stateTargets, storybookUrlSource, summarizeTests, sweepOrphanedScratch, toBuildComponent, writeTo };
package/dist/config.d.mts CHANGED
@@ -2,13 +2,15 @@ import __tsdown_shims_path from 'node:path';
2
2
  import __tsdown_shims_url from 'node:url';
3
3
  import { CaptureRunner } from "./adapter/capture-runner.mjs";
4
4
  import { DatabaseAdapter } from "./adapter/database.mjs";
5
+ import { DesignProvider } from "./adapter/design.mjs";
5
6
  import { EmailSender } from "./adapter/email-sender.mjs";
6
- import { GitHostProvider } from "./adapter/git-host.mjs";
7
7
  import { NotifierProvider } from "./adapters/notifier/provider.mjs";
8
8
  import { StorageAdapter } from "./adapter/storage.mjs";
9
+ import { Ai } from "./ai.mjs";
9
10
  import { Auth } from "./auth.mjs";
11
+ import { DEFAULT_SCRATCH_DIR, resolveShelfOptions } from "./options.mjs";
12
+ import { ALLOW_SERVERLESS_ENV, assertServerless, isServerlessHost } from "./serverless.mjs";
10
13
  import { AdapterCategory } from "./adapter/metadata.mjs";
11
- import { CaptureQueue } from "./adapter/capture-queue.mjs";
12
14
  import { z } from "zod";
13
15
  import { Logger } from "pino";
14
16
  //#region src/config.d.ts
@@ -127,7 +129,10 @@ interface ShelfConfig {
127
129
  * helper document; falls back to the request origin when unset.
128
130
  */
129
131
  publicBaseUrl?: string;
130
- captureConcurrency?: number;
132
+ /**
133
+ * Working directory for capture and inline statics extraction. Defaults to
134
+ * `<os.tmpdir()>/storyshelf`; publishing and capture extract there.
135
+ */
131
136
  scratchDir?: string;
132
137
  purgeTtlDays?: number;
133
138
  /** Branch baseline TTL, days; null disables branch GC (default 30). */
@@ -141,14 +146,24 @@ interface ShelfConfig {
141
146
  */
142
147
  serverTiming?: boolean;
143
148
  /**
144
- * Max zip size (bytes) eligible for inline statics extraction at upload.
145
- * Unset (or 0) disables inline extraction — statics land via capture.
149
+ * Largest zip (bytes) extracted inline in the upload request; a larger zip is published by a
150
+ * `publish` job (or refused with 413 on a host that runs no consumer). The count is taken
151
+ * while the upload streams, never from `Content-Length`. Default 50 MB; `0` sends every zip to
152
+ * a `publish` job.
146
153
  */
147
154
  maxInlineUnzipSize?: number;
155
+ /** Most entries an uploaded Storybook zip may hold (default 50 000); more fails the publish. */
156
+ maxZipEntries?: number;
157
+ /**
158
+ * Most uncompressed bytes an uploaded Storybook zip may expand to (default 2 GiB), counted while
159
+ * extracting; more fails the publish. The compressed size is no bound on its own.
160
+ */
161
+ maxUnzippedBytes?: number;
148
162
  viewports?: ShelfViewport[];
149
163
  adapters?: Record<string, AdapterSnapshot>;
150
- notifications?: NotificationsConfig;
151
164
  }
165
+ /** Zod schema validating `notifications.config`. */
166
+ declare const notificationsConfigSchema: z.ZodType<NotificationsConfig>;
152
167
  /** Zod schema validating the shelf-level configuration. */
153
168
  declare const shelfConfigSchema: z.ZodType<ShelfConfig>;
154
169
  /** Zod schema validating the UI branding configuration. */
@@ -167,16 +182,110 @@ declare function validateConfig(config: Record<string, unknown>): ShelfConfig;
167
182
  * @returns The validated UI configuration.
168
183
  */
169
184
  declare function validateUiConfig(config: Record<string, unknown>): UIConfig;
185
+ /** Testing options: what renders, how many run at once, and how screenshots are compared. */
186
+ interface ShelfTestingOptions {
187
+ /** Pure renderer. Required: `testing` without a `runner` throws. */
188
+ runner: CaptureRunner;
189
+ /** Jobs this instance runs at once; auto-sized from CPU and memory when unset. */
190
+ concurrency?: number;
191
+ /**
192
+ * Retries after a first failed attempt before a capture job fails for good (default 2: three
193
+ * attempts). One limit covers failed attempts, lost leases and forked-child crashes.
194
+ */
195
+ retries?: number;
196
+ /**
197
+ * Lease of a job of the database queue, in seconds (default 300: 5 minutes). A running job
198
+ * renews it on a heartbeat (every `min(30 s, lease / 3)`) and on progress, so a stage that prints
199
+ * nothing is not redelivered while its process lives; a crashed holder's job is claimed by
200
+ * another instance once the lease runs out, so a shorter lease recovers crashes sooner.
201
+ */
202
+ leaseSeconds?: number;
203
+ /**
204
+ * Module run in a forked capture child (it calls `runCaptureChild` from `@storyshelf/core/capture`).
205
+ * The app consumes the queue and pushes each job to the child over IPC. Needs `runner`, which
206
+ * serves as the in-process fallback.
207
+ */
208
+ workerEntry?: string;
209
+ /**
210
+ * Split a big build across the queue: captures (story x viewport x engine) per shard. A build of
211
+ * up to twice this size still renders in one piece. Unset keeps every build in one job. Needs
212
+ * `runner`. With `workerEntry` the forked child plans and renders shards and puts them on the
213
+ * database queue itself.
214
+ */
215
+ shardSize?: number;
216
+ /**
217
+ * Requests per minute one client IP may make to the signed Storybook URL route, `/_s/<token>/*`
218
+ * (ADR 0007, decision 5). Default 6000, enough for a render fetching thousands of assets from one
219
+ * farm IP; a larger farm behind one address raises it. Over the limit the route answers `429`
220
+ * before it looks at the token, so the answer says nothing about a token's validity.
221
+ */
222
+ storybookUrlRateLimit?: number;
223
+ /**
224
+ * Where captures run. `auto` (default) forks when `workerEntry` is set and the host can afford
225
+ * a second process; `in-process` never forks; `fork` forks regardless of the host and fails at
226
+ * boot if it cannot.
227
+ */
228
+ mode?: "auto" | "in-process" | "fork";
229
+ /** Screenshot comparison, shared by capture and the re-diff endpoint. */
230
+ compare?: ShelfCompareOptions;
231
+ /** Image library selection; see {@link ShelfImagesOptions}. */
232
+ images?: ShelfImagesOptions;
233
+ /**
234
+ * Clock and timers of the database job queue. Tests inject a manual clock so lease and poll
235
+ * transitions do not depend on wall time; production leaves it unset (`Date.now` and the global
236
+ * timers).
237
+ */
238
+ queueClock?: {
239
+ now: () => number;
240
+ timers: {
241
+ setTimeout(callback: () => void, ms: number): unknown;
242
+ clearTimeout(handle: unknown): void;
243
+ };
244
+ };
245
+ }
246
+ /** Notification options: who can deliver, over which transport, with what branding. */
247
+ interface ShelfNotificationsOptions {
248
+ /** Provider adapters (Slack, Teams, email, ...); a channel's `provider` must name one of these. */
249
+ notifiers?: NotifierProvider[];
250
+ /** Email transport. Listed here so its setup/teardown/validation hooks run with the app's. */
251
+ emailSender?: EmailSender;
252
+ /** Site-wide brand and sender settings for outgoing notifications. */
253
+ config?: NotificationsConfig;
254
+ }
255
+ /** Comparison options. */
256
+ interface ShelfCompareOptions {
257
+ /**
258
+ * Worker threads for pixel diffs: default CPU count minus one (min 1), `0` diffs on the main
259
+ * thread. Takes precedence over `STORYSHELF_DIFF_WORKERS`.
260
+ */
261
+ threads?: number;
262
+ }
263
+ /** Image-handling options: which library decodes, encodes and resizes the PNGs. */
264
+ interface ShelfImagesOptions {
265
+ /**
266
+ * Image library for diffs, diff overlays and AI thumbnails: `"pngjs"` (default, pure JavaScript,
267
+ * runs anywhere) or `"sharp"` (native, several times faster on large PNGs; needs the optional
268
+ * `sharp` package installed). Falls back to `STORYSHELF_IMAGE_ENGINE`. The pixel comparison is
269
+ * pixelmatch either way, so verdicts match.
270
+ */
271
+ engine?: "pngjs" | "sharp";
272
+ }
170
273
  /** Adapter and configuration options for creating the shelf router. */
171
274
  interface ShelfOptions {
172
275
  database: DatabaseAdapter;
173
276
  storage: StorageAdapter;
174
- captureRunner?: CaptureRunner;
175
- captureQueue?: CaptureQueue;
277
+ /**
278
+ * Testing (render + diff in the background). Absent means Storybook hosting only: no renderer,
279
+ * no queue, and the tuning below is unreachable rather than silently ignored.
280
+ */
281
+ testing?: ShelfTestingOptions;
176
282
  auth?: Auth;
177
- gitHosts?: GitHostProvider[];
178
- notifiers?: NotifierProvider[];
179
- emailSender?: EmailSender;
283
+ /** AI insights surface (ADR 0016). Set ⇒ AI on site-wide; absent ⇒ off. */
284
+ ai?: Ai;
285
+ /** Design-tool providers (Figma, …) that resolve links, metadata and previews. */
286
+ design?: DesignProvider[];
287
+ /** Notification subsystem: providers, the email transport, and shared brand/sender settings. */
288
+ notifications?: ShelfNotificationsOptions;
180
289
  logger?: Logger;
181
290
  ui?: UIConfig;
182
291
  config?: ShelfConfig;
@@ -196,5 +305,5 @@ interface ObservabilityHandle {
196
305
  shutdown(): Promise<void>;
197
306
  }
198
307
  //#endregion
199
- export { AdapterSnapshot, AuthUiConfig, BrandTheme, DEFAULT_MAX_UPLOAD_BYTES, NotificationsConfig, ObservabilityHandle, ShelfConfig, ShelfOptions, ShelfViewport, UIConfig, shelfConfigSchema, uiConfigSchema, validateConfig, validateUiConfig };
308
+ export { ALLOW_SERVERLESS_ENV, AdapterSnapshot, AuthUiConfig, BrandTheme, DEFAULT_MAX_UPLOAD_BYTES, DEFAULT_SCRATCH_DIR, NotificationsConfig, ObservabilityHandle, ShelfCompareOptions, ShelfConfig, ShelfImagesOptions, ShelfNotificationsOptions, ShelfOptions, ShelfTestingOptions, ShelfViewport, UIConfig, assertServerless, isServerlessHost, notificationsConfigSchema, resolveShelfOptions, shelfConfigSchema, uiConfigSchema, validateConfig, validateUiConfig };
200
309
  //# sourceMappingURL=config.d.mts.map