@storyshelf/core 0.6.2 → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (727) hide show
  1. package/README.md +49 -32
  2. package/dist/adapter/capture-queue.d.mts +44 -4
  3. package/dist/adapter/capture-runner.d.mts +134 -12
  4. package/dist/adapter/capture-runner.mjs +9 -12
  5. package/dist/adapter/database.d.mts +89 -10
  6. package/dist/adapter/database.mjs +4 -3
  7. package/dist/adapter/database.mjs.map +1 -1
  8. package/dist/adapter/design.d.mts +83 -0
  9. package/dist/adapter/design.mjs +27 -0
  10. package/dist/adapter/design.mjs.map +1 -0
  11. package/dist/adapter/email-sender.d.mts +0 -2
  12. package/dist/adapter/metadata.d.mts +3 -12
  13. package/dist/adapter/notifier.d.mts +6 -3
  14. package/dist/adapter/notifier.mjs +5 -1
  15. package/dist/adapter/oauth.d.mts +50 -0
  16. package/dist/adapter/setup.d.mts +4 -7
  17. package/dist/adapter/setup.mjs +3 -3
  18. package/dist/adapter/setup.mjs.map +1 -1
  19. package/dist/adapter/storage.d.mts +1 -3
  20. package/dist/adapter/webhook-events.d.mts +0 -2
  21. package/dist/adapter/webhook-events.mjs +13 -14
  22. package/dist/adapter/webhook-events.mjs.map +1 -1
  23. package/dist/adapters/capture-target-offers.d.mts +26 -0
  24. package/dist/adapters/capture-target-offers.mjs +57 -0
  25. package/dist/adapters/capture-target-offers.mjs.map +1 -0
  26. package/dist/adapters/capture-target.d.mts +69 -0
  27. package/dist/adapters/capture-target.mjs +75 -0
  28. package/dist/adapters/capture-target.mjs.map +1 -0
  29. package/dist/adapters/notifier/build-comment.d.mts +22 -0
  30. package/dist/adapters/notifier/build-comment.mjs +23 -0
  31. package/dist/adapters/notifier/build-comment.mjs.map +1 -0
  32. package/dist/adapters/notifier/build-state.d.mts +97 -0
  33. package/dist/adapters/notifier/build-state.mjs +217 -0
  34. package/dist/adapters/notifier/build-state.mjs.map +1 -0
  35. package/dist/adapters/notifier/events.d.mts +4 -4
  36. package/dist/adapters/notifier/events.mjs +32 -20
  37. package/dist/adapters/notifier/events.mjs.map +1 -1
  38. package/dist/adapters/notifier/format.d.mts +0 -2
  39. package/dist/adapters/notifier/format.mjs +1 -2
  40. package/dist/adapters/notifier/provider.d.mts +53 -9
  41. package/dist/adapters/notifier/provider.mjs +11 -0
  42. package/dist/adapters/notifier/provider.mjs.map +1 -0
  43. package/dist/adapters/notifier/state.d.mts +22 -0
  44. package/dist/adapters/notifier/state.mjs +65 -0
  45. package/dist/adapters/notifier/state.mjs.map +1 -0
  46. package/dist/adapters/notifier/types.d.mts +51 -4
  47. package/dist/adapters/remote-browser.d.mts +168 -0
  48. package/dist/adapters/remote-browser.mjs +201 -0
  49. package/dist/adapters/remote-browser.mjs.map +1 -0
  50. package/dist/adapters/remote-lease-attempt.mjs +39 -0
  51. package/dist/adapters/remote-lease-attempt.mjs.map +1 -0
  52. package/dist/adapters/remote-lease-error.d.mts +25 -0
  53. package/dist/adapters/remote-lease-error.mjs +54 -0
  54. package/dist/adapters/remote-lease-error.mjs.map +1 -0
  55. package/dist/adapters/remote-lease-held.d.mts +15 -0
  56. package/dist/adapters/remote-lease-held.mjs +86 -0
  57. package/dist/adapters/remote-lease-held.mjs.map +1 -0
  58. package/dist/adapters/remote-lease-shutdown.d.mts +12 -0
  59. package/dist/adapters/remote-lease-shutdown.mjs +32 -0
  60. package/dist/adapters/remote-lease-shutdown.mjs.map +1 -0
  61. package/dist/adapters/remote-lease.d.mts +39 -0
  62. package/dist/adapters/remote-lease.mjs +175 -0
  63. package/dist/adapters/remote-lease.mjs.map +1 -0
  64. package/dist/adapters/remote-limiter.mjs +121 -0
  65. package/dist/adapters/remote-limiter.mjs.map +1 -0
  66. package/dist/adapters/remote-pool.d.mts +56 -0
  67. package/dist/adapters/remote-pool.mjs +195 -0
  68. package/dist/adapters/remote-pool.mjs.map +1 -0
  69. package/dist/adapters/render-runs.d.mts +23 -0
  70. package/dist/adapters/render-runs.mjs +40 -0
  71. package/dist/adapters/render-runs.mjs.map +1 -0
  72. package/dist/adapters/setup-runner.d.mts +0 -2
  73. package/dist/adapters/setup-runner.mjs +3 -6
  74. package/dist/adapters/setup-runner.mjs.map +1 -1
  75. package/dist/adapters/sources.d.mts +10 -0
  76. package/dist/adapters/sources.mjs +19 -0
  77. package/dist/adapters/sources.mjs.map +1 -0
  78. package/dist/adapters/validate.d.mts +0 -2
  79. package/dist/adapters/validate.mjs +27 -20
  80. package/dist/adapters/validate.mjs.map +1 -1
  81. package/dist/ai.d.mts +103 -0
  82. package/dist/ai.mjs +18 -0
  83. package/dist/ai.mjs.map +1 -0
  84. package/dist/auth.d.mts +0 -2
  85. package/dist/auth.mjs +1 -2
  86. package/dist/brand-packs.d.mts +0 -2
  87. package/dist/brand-packs.mjs +0 -1
  88. package/dist/capture/a11y/axe-source.d.mts +16 -0
  89. package/dist/capture/a11y/axe-source.mjs +36 -0
  90. package/dist/capture/a11y/axe-source.mjs.map +1 -0
  91. package/dist/capture/a11y/in-page.d.mts +25 -0
  92. package/dist/capture/a11y/in-page.mjs +59 -0
  93. package/dist/capture/a11y/in-page.mjs.map +1 -0
  94. package/dist/capture/a11y/map.d.mts +22 -0
  95. package/dist/capture/a11y/map.mjs +47 -0
  96. package/dist/capture/a11y/map.mjs.map +1 -0
  97. package/dist/capture/a11y/options.d.mts +21 -0
  98. package/dist/capture/a11y/options.mjs +74 -0
  99. package/dist/capture/a11y/options.mjs.map +1 -0
  100. package/dist/capture/adapter.d.mts +46 -5
  101. package/dist/capture/adapter.mjs +1 -2
  102. package/dist/capture/adapter.mjs.map +1 -1
  103. package/dist/capture/affected.d.mts +2 -2
  104. package/dist/capture/affected.mjs +14 -6
  105. package/dist/capture/affected.mjs.map +1 -1
  106. package/dist/capture/attempt-logger.mjs +83 -0
  107. package/dist/capture/attempt-logger.mjs.map +1 -0
  108. package/dist/capture/browsers.d.mts +33 -0
  109. package/dist/capture/browsers.mjs +66 -0
  110. package/dist/capture/browsers.mjs.map +1 -0
  111. package/dist/capture/build-state/deliver.d.mts +30 -0
  112. package/dist/capture/build-state/deliver.mjs +117 -0
  113. package/dist/capture/build-state/deliver.mjs.map +1 -0
  114. package/dist/capture/build-state/index.d.mts +8 -0
  115. package/dist/capture/build-state/notify-job.d.mts +54 -0
  116. package/dist/capture/build-state/notify-job.mjs +132 -0
  117. package/dist/capture/build-state/notify-job.mjs.map +1 -0
  118. package/dist/capture/build-state/publisher.d.mts +21 -0
  119. package/dist/capture/build-state/publisher.mjs +106 -0
  120. package/dist/capture/build-state/publisher.mjs.map +1 -0
  121. package/dist/capture/build-state/resume.d.mts +7 -0
  122. package/dist/capture/build-state/resume.mjs +46 -0
  123. package/dist/capture/build-state/resume.mjs.map +1 -0
  124. package/dist/capture/build-state/types.d.mts +47 -0
  125. package/dist/capture/catalog/catalogue.d.mts +20 -0
  126. package/dist/capture/catalog/catalogue.mjs +52 -0
  127. package/dist/capture/catalog/catalogue.mjs.map +1 -0
  128. package/dist/capture/catalog/components.d.mts +21 -0
  129. package/dist/capture/catalog/components.mjs +54 -0
  130. package/dist/capture/catalog/components.mjs.map +1 -0
  131. package/dist/capture/catalog/history.d.mts +28 -0
  132. package/dist/capture/catalog/history.mjs +50 -0
  133. package/dist/capture/catalog/history.mjs.map +1 -0
  134. package/dist/capture/catalog/hook.d.mts +12 -0
  135. package/dist/capture/catalog/hook.mjs +18 -0
  136. package/dist/capture/catalog/hook.mjs.map +1 -0
  137. package/dist/capture/catalog/index.d.mts +11 -0
  138. package/dist/capture/catalog/load.d.mts +24 -0
  139. package/dist/capture/catalog/load.mjs +48 -0
  140. package/dist/capture/catalog/load.mjs.map +1 -0
  141. package/dist/capture/catalog/parse.d.mts +13 -0
  142. package/dist/capture/catalog/parse.mjs +55 -0
  143. package/dist/capture/catalog/parse.mjs.map +1 -0
  144. package/dist/capture/catalog/read.d.mts +15 -0
  145. package/dist/capture/catalog/read.mjs +39 -0
  146. package/dist/capture/catalog/read.mjs.map +1 -0
  147. package/dist/capture/catalog/types.d.mts +31 -0
  148. package/dist/capture/comparison-reference.d.mts +27 -0
  149. package/dist/capture/comparison-reference.mjs +75 -0
  150. package/dist/capture/comparison-reference.mjs.map +1 -0
  151. package/dist/capture/consumer/capture-handler.d.mts +56 -0
  152. package/dist/capture/consumer/capture-handler.mjs +117 -0
  153. package/dist/capture/consumer/capture-handler.mjs.map +1 -0
  154. package/dist/capture/consumer/idle.d.mts +15 -0
  155. package/dist/capture/consumer/idle.mjs +24 -0
  156. package/dist/capture/consumer/idle.mjs.map +1 -0
  157. package/dist/capture/consumer/index.d.mts +11 -0
  158. package/dist/capture/consumer/index.mjs +138 -0
  159. package/dist/capture/consumer/index.mjs.map +1 -0
  160. package/dist/capture/consumer/loop.mjs +109 -0
  161. package/dist/capture/consumer/loop.mjs.map +1 -0
  162. package/dist/capture/consumer/metrics.d.mts +39 -0
  163. package/dist/capture/consumer/metrics.mjs +37 -0
  164. package/dist/capture/consumer/metrics.mjs.map +1 -0
  165. package/dist/capture/consumer/retry.d.mts +31 -0
  166. package/dist/capture/consumer/retry.mjs +33 -0
  167. package/dist/capture/consumer/retry.mjs.map +1 -0
  168. package/dist/capture/consumer/run-job.mjs +194 -0
  169. package/dist/capture/consumer/run-job.mjs.map +1 -0
  170. package/dist/capture/consumer/startup.mjs +37 -0
  171. package/dist/capture/consumer/startup.mjs.map +1 -0
  172. package/dist/capture/consumer/types.d.mts +95 -0
  173. package/dist/capture/crash-failure.d.mts +23 -0
  174. package/dist/capture/crash-failure.mjs +69 -0
  175. package/dist/capture/crash-failure.mjs.map +1 -0
  176. package/dist/capture/db-queue/cadence.d.mts +30 -0
  177. package/dist/capture/db-queue/cadence.mjs +37 -0
  178. package/dist/capture/db-queue/cadence.mjs.map +1 -0
  179. package/dist/capture/db-queue/claim.d.mts +7 -0
  180. package/dist/capture/db-queue/claim.mjs +148 -0
  181. package/dist/capture/db-queue/claim.mjs.map +1 -0
  182. package/dist/capture/db-queue/clock.mjs +11 -0
  183. package/dist/capture/db-queue/clock.mjs.map +1 -0
  184. package/dist/capture/db-queue/codec.mjs +75 -0
  185. package/dist/capture/db-queue/codec.mjs.map +1 -0
  186. package/dist/capture/db-queue/index.d.mts +18 -0
  187. package/dist/capture/db-queue/index.mjs +89 -0
  188. package/dist/capture/db-queue/index.mjs.map +1 -0
  189. package/dist/capture/db-queue/keeper.d.mts +34 -0
  190. package/dist/capture/db-queue/keeper.mjs +91 -0
  191. package/dist/capture/db-queue/keeper.mjs.map +1 -0
  192. package/dist/capture/db-queue/lease.mjs +45 -0
  193. package/dist/capture/db-queue/lease.mjs.map +1 -0
  194. package/dist/capture/db-queue/lifecycle.mjs +35 -0
  195. package/dist/capture/db-queue/lifecycle.mjs.map +1 -0
  196. package/dist/capture/db-queue/operations.mjs +93 -0
  197. package/dist/capture/db-queue/operations.mjs.map +1 -0
  198. package/dist/capture/db-queue/poll-loop.d.mts +28 -0
  199. package/dist/capture/db-queue/poll-loop.mjs +88 -0
  200. package/dist/capture/db-queue/poll-loop.mjs.map +1 -0
  201. package/dist/capture/db-queue/poll.d.mts +8 -0
  202. package/dist/capture/db-queue/poll.mjs +68 -0
  203. package/dist/capture/db-queue/poll.mjs.map +1 -0
  204. package/dist/capture/db-queue/timers.d.mts +10 -0
  205. package/dist/capture/db-queue/timers.mjs +36 -0
  206. package/dist/capture/db-queue/timers.mjs.map +1 -0
  207. package/dist/capture/db-queue/types.d.mts +81 -0
  208. package/dist/capture/db-queue/types.mjs +11 -0
  209. package/dist/capture/db-queue/types.mjs.map +1 -0
  210. package/dist/capture/db-queue/wake.mjs +47 -0
  211. package/dist/capture/db-queue/wake.mjs.map +1 -0
  212. package/dist/capture/design.mjs +38 -0
  213. package/dist/capture/design.mjs.map +1 -0
  214. package/dist/capture/diff-record.mjs +24 -5
  215. package/dist/capture/diff-record.mjs.map +1 -1
  216. package/dist/capture/dispatch.d.mts +13 -10
  217. package/dist/capture/dispatch.mjs +102 -111
  218. package/dist/capture/dispatch.mjs.map +1 -1
  219. package/dist/capture/enrich.mjs +59 -0
  220. package/dist/capture/enrich.mjs.map +1 -0
  221. package/dist/capture/failure-sets.mjs +21 -0
  222. package/dist/capture/failure-sets.mjs.map +1 -0
  223. package/dist/capture/fingerprint.d.mts +40 -0
  224. package/dist/capture/fingerprint.mjs +82 -0
  225. package/dist/capture/fingerprint.mjs.map +1 -0
  226. package/dist/capture/forked/channel.d.mts +23 -0
  227. package/dist/capture/forked/child.d.mts +32 -0
  228. package/dist/capture/forked/child.mjs +201 -0
  229. package/dist/capture/forked/child.mjs.map +1 -0
  230. package/dist/capture/forked/crash-tracker.mjs +22 -0
  231. package/dist/capture/forked/crash-tracker.mjs.map +1 -0
  232. package/dist/capture/forked/decision.d.mts +24 -0
  233. package/dist/capture/forked/decision.mjs +26 -0
  234. package/dist/capture/forked/decision.mjs.map +1 -0
  235. package/dist/capture/forked/exit.mjs +11 -0
  236. package/dist/capture/forked/exit.mjs.map +1 -0
  237. package/dist/capture/forked/fork.d.mts +29 -0
  238. package/dist/capture/forked/fork.mjs +92 -0
  239. package/dist/capture/forked/fork.mjs.map +1 -0
  240. package/dist/capture/forked/forked-capture.d.mts +38 -0
  241. package/dist/capture/forked/forked-capture.mjs +239 -0
  242. package/dist/capture/forked/forked-capture.mjs.map +1 -0
  243. package/dist/capture/forked/lease-book.mjs +45 -0
  244. package/dist/capture/forked/lease-book.mjs.map +1 -0
  245. package/dist/capture/forked/protocol.d.mts +36 -0
  246. package/dist/capture/forked/protocol.mjs +24 -0
  247. package/dist/capture/forked/protocol.mjs.map +1 -0
  248. package/dist/capture/forked/runs.mjs +74 -0
  249. package/dist/capture/forked/runs.mjs.map +1 -0
  250. package/dist/capture/guards.mjs +1 -2
  251. package/dist/capture/ignore-regions.d.mts +36 -0
  252. package/dist/capture/ignore-regions.mjs +65 -0
  253. package/dist/capture/ignore-regions.mjs.map +1 -0
  254. package/dist/capture/isolate.mjs +140 -0
  255. package/dist/capture/isolate.mjs.map +1 -0
  256. package/dist/capture/job-lease.d.mts +26 -0
  257. package/dist/capture/job-lease.mjs +56 -0
  258. package/dist/capture/job-lease.mjs.map +1 -0
  259. package/dist/capture/matrix.mjs +298 -0
  260. package/dist/capture/matrix.mjs.map +1 -0
  261. package/dist/capture/modes.d.mts +23 -0
  262. package/dist/capture/modes.mjs +106 -0
  263. package/dist/capture/modes.mjs.map +1 -0
  264. package/dist/capture/orchestrator.d.mts +37 -7
  265. package/dist/capture/orchestrator.mjs +120 -110
  266. package/dist/capture/orchestrator.mjs.map +1 -1
  267. package/dist/capture/pipeline.d.mts +9 -4
  268. package/dist/capture/pipeline.mjs +284 -48
  269. package/dist/capture/pipeline.mjs.map +1 -1
  270. package/dist/capture/progress.d.mts +9 -0
  271. package/dist/capture/progress.mjs +27 -0
  272. package/dist/capture/progress.mjs.map +1 -0
  273. package/dist/capture/publish/accept.d.mts +37 -0
  274. package/dist/capture/publish/accept.mjs +27 -0
  275. package/dist/capture/publish/accept.mjs.map +1 -0
  276. package/dist/capture/publish/complete.d.mts +44 -0
  277. package/dist/capture/publish/complete.mjs +63 -0
  278. package/dist/capture/publish/complete.mjs.map +1 -0
  279. package/dist/capture/publish/extract.d.mts +18 -0
  280. package/dist/capture/publish/extract.mjs +120 -0
  281. package/dist/capture/publish/extract.mjs.map +1 -0
  282. package/dist/capture/publish/handler.d.mts +26 -0
  283. package/dist/capture/publish/handler.mjs +61 -0
  284. package/dist/capture/publish/handler.mjs.map +1 -0
  285. package/dist/capture/publish/index.d.mts +11 -0
  286. package/dist/capture/publish/invalid-zip.d.mts +8 -0
  287. package/dist/capture/publish/invalid-zip.mjs +11 -0
  288. package/dist/capture/publish/invalid-zip.mjs.map +1 -0
  289. package/dist/capture/publish/limits.d.mts +35 -0
  290. package/dist/capture/publish/limits.mjs +38 -0
  291. package/dist/capture/publish/limits.mjs.map +1 -0
  292. package/dist/capture/publish/published.d.mts +13 -0
  293. package/dist/capture/publish/published.mjs +17 -0
  294. package/dist/capture/publish/published.mjs.map +1 -0
  295. package/dist/capture/publish/run.d.mts +31 -0
  296. package/dist/capture/publish/run.mjs +29 -0
  297. package/dist/capture/publish/run.mjs.map +1 -0
  298. package/dist/capture/rediff.d.mts +1 -3
  299. package/dist/capture/rediff.mjs +23 -9
  300. package/dist/capture/rediff.mjs.map +1 -1
  301. package/dist/capture/render.mjs +52 -0
  302. package/dist/capture/render.mjs.map +1 -0
  303. package/dist/capture/scratch.d.mts +42 -0
  304. package/dist/capture/scratch.mjs +136 -0
  305. package/dist/capture/scratch.mjs.map +1 -0
  306. package/dist/capture/shard-plan.mjs +127 -0
  307. package/dist/capture/shard-plan.mjs.map +1 -0
  308. package/dist/capture/shards/context.mjs +51 -0
  309. package/dist/capture/shards/context.mjs.map +1 -0
  310. package/dist/capture/shards/execute.mjs +175 -0
  311. package/dist/capture/shards/execute.mjs.map +1 -0
  312. package/dist/capture/shards/fan-out.mjs +125 -0
  313. package/dist/capture/shards/fan-out.mjs.map +1 -0
  314. package/dist/capture/shards/history.mjs +34 -0
  315. package/dist/capture/shards/history.mjs.map +1 -0
  316. package/dist/capture/shards/reduce.mjs +96 -0
  317. package/dist/capture/shards/reduce.mjs.map +1 -0
  318. package/dist/capture/sizing.d.mts +0 -2
  319. package/dist/capture/sizing.mjs +2 -13
  320. package/dist/capture/sizing.mjs.map +1 -1
  321. package/dist/capture/skip-checks.mjs +3 -67
  322. package/dist/capture/skip-checks.mjs.map +1 -1
  323. package/dist/capture/statics.d.mts +7 -10
  324. package/dist/capture/statics.mjs +26 -74
  325. package/dist/capture/statics.mjs.map +1 -1
  326. package/dist/capture/storybook-urls.d.mts +38 -0
  327. package/dist/capture/storybook-urls.mjs +41 -0
  328. package/dist/capture/storybook-urls.mjs.map +1 -0
  329. package/dist/capture/storybook.d.mts +12 -6
  330. package/dist/capture/storybook.mjs +63 -19
  331. package/dist/capture/storybook.mjs.map +1 -1
  332. package/dist/capture/target.mjs +20 -0
  333. package/dist/capture/target.mjs.map +1 -0
  334. package/dist/capture/targets.d.mts +23 -0
  335. package/dist/capture/targets.mjs +31 -0
  336. package/dist/capture/targets.mjs.map +1 -0
  337. package/dist/capture/tests.d.mts +35 -0
  338. package/dist/capture/tests.mjs +136 -0
  339. package/dist/capture/tests.mjs.map +1 -0
  340. package/dist/capture/token-chunks.mjs +91 -0
  341. package/dist/capture/token-chunks.mjs.map +1 -0
  342. package/dist/capture.d.mts +63 -7
  343. package/dist/capture.mjs +51 -3
  344. package/dist/config.d.mts +136 -14
  345. package/dist/config.mjs +14 -8
  346. package/dist/config.mjs.map +1 -1
  347. package/dist/diff.d.mts +7 -3
  348. package/dist/diff.mjs +15 -3
  349. package/dist/diff.mjs.map +1 -0
  350. package/dist/index.d.mts +3 -3
  351. package/dist/index.mjs +2 -2
  352. package/dist/insights/budget.d.mts +18 -0
  353. package/dist/insights/budget.mjs +32 -0
  354. package/dist/insights/budget.mjs.map +1 -0
  355. package/dist/insights/envelope.d.mts +57 -0
  356. package/dist/insights/envelope.mjs +59 -0
  357. package/dist/insights/envelope.mjs.map +1 -0
  358. package/dist/insights/evidence-health.d.mts +30 -0
  359. package/dist/insights/evidence-health.mjs +27 -0
  360. package/dist/insights/evidence-health.mjs.map +1 -0
  361. package/dist/insights/evidence.d.mts +53 -0
  362. package/dist/insights/evidence.mjs +63 -0
  363. package/dist/insights/evidence.mjs.map +1 -0
  364. package/dist/insights/hash.d.mts +16 -0
  365. package/dist/insights/hash.mjs +20 -0
  366. package/dist/insights/hash.mjs.map +1 -0
  367. package/dist/insights/limits.d.mts +22 -0
  368. package/dist/insights/limits.mjs +23 -0
  369. package/dist/insights/limits.mjs.map +1 -0
  370. package/dist/insights/prompts/v1.d.mts +11 -0
  371. package/dist/insights/prompts/v1.mjs +33 -0
  372. package/dist/insights/prompts/v1.mjs.map +1 -0
  373. package/dist/insights/redact.d.mts +7 -0
  374. package/dist/insights/redact.mjs +23 -0
  375. package/dist/insights/redact.mjs.map +1 -0
  376. package/dist/insights/text.mjs +43 -0
  377. package/dist/insights/text.mjs.map +1 -0
  378. package/dist/insights.d.mts +11 -0
  379. package/dist/insights.mjs +12 -0
  380. package/dist/logger.d.mts +0 -2
  381. package/dist/logger.mjs +18 -3
  382. package/dist/logger.mjs.map +1 -1
  383. package/dist/models/ai-budget-alert.d.mts +21 -0
  384. package/dist/models/ai-budget-alert.mjs +37 -0
  385. package/dist/models/ai-budget-alert.mjs.map +1 -0
  386. package/dist/models/ai-usage.d.mts +38 -0
  387. package/dist/models/ai-usage.mjs +60 -0
  388. package/dist/models/ai-usage.mjs.map +1 -0
  389. package/dist/models/baseline-approval.d.mts +18 -0
  390. package/dist/models/baseline-approval.mjs +41 -0
  391. package/dist/models/baseline-approval.mjs.map +1 -0
  392. package/dist/models/baseline-archive.d.mts +82 -0
  393. package/dist/models/baseline-archive.mjs +105 -0
  394. package/dist/models/baseline-archive.mjs.map +1 -0
  395. package/dist/models/baseline-atomic.mjs +66 -0
  396. package/dist/models/baseline-atomic.mjs.map +1 -0
  397. package/dist/models/baseline-conflict.d.mts +6 -0
  398. package/dist/models/baseline-conflict.mjs +9 -0
  399. package/dist/models/baseline-conflict.mjs.map +1 -0
  400. package/dist/models/baseline-export.d.mts +17 -0
  401. package/dist/models/baseline-export.mjs +135 -0
  402. package/dist/models/baseline-export.mjs.map +1 -0
  403. package/dist/models/baseline-import.mjs +117 -0
  404. package/dist/models/baseline-import.mjs.map +1 -0
  405. package/dist/models/baseline-origin.d.mts +16 -0
  406. package/dist/models/baseline-origin.mjs +35 -0
  407. package/dist/models/baseline-origin.mjs.map +1 -0
  408. package/dist/models/baseline-status.d.mts +0 -2
  409. package/dist/models/baseline-status.mjs +1 -2
  410. package/dist/models/baseline-transfer.d.mts +48 -0
  411. package/dist/models/baseline-transfer.mjs +149 -0
  412. package/dist/models/baseline-transfer.mjs.map +1 -0
  413. package/dist/models/baseline.d.mts +37 -7
  414. package/dist/models/baseline.mjs +152 -28
  415. package/dist/models/baseline.mjs.map +1 -1
  416. package/dist/models/build-component.d.mts +26 -0
  417. package/dist/models/build-component.mjs +54 -0
  418. package/dist/models/build-component.mjs.map +1 -0
  419. package/dist/models/build-review-status.d.mts +27 -0
  420. package/dist/models/build-review-status.mjs +36 -0
  421. package/dist/models/build-review-status.mjs.map +1 -0
  422. package/dist/models/build-review.d.mts +26 -0
  423. package/dist/models/build-review.mjs +53 -0
  424. package/dist/models/build-review.mjs.map +1 -0
  425. package/dist/models/build.d.mts +25 -5
  426. package/dist/models/build.mjs +53 -15
  427. package/dist/models/build.mjs.map +1 -1
  428. package/dist/models/capture-attempt.d.mts +7 -3
  429. package/dist/models/capture-attempt.mjs +30 -6
  430. package/dist/models/capture-attempt.mjs.map +1 -1
  431. package/dist/models/capture-job.d.mts +104 -0
  432. package/dist/models/capture-job.mjs +287 -0
  433. package/dist/models/capture-job.mjs.map +1 -0
  434. package/dist/models/capture-log.d.mts +1 -3
  435. package/dist/models/capture-log.mjs +5 -5
  436. package/dist/models/capture-log.mjs.map +1 -1
  437. package/dist/models/capture-shard.d.mts +60 -0
  438. package/dist/models/capture-shard.mjs +189 -0
  439. package/dist/models/capture-shard.mjs.map +1 -0
  440. package/dist/models/changeset.d.mts +46 -0
  441. package/dist/models/changeset.mjs +80 -0
  442. package/dist/models/changeset.mjs.map +1 -0
  443. package/dist/models/columns.mjs +18 -0
  444. package/dist/models/columns.mjs.map +1 -0
  445. package/dist/models/comment.d.mts +4 -3
  446. package/dist/models/comment.mjs +8 -6
  447. package/dist/models/comment.mjs.map +1 -1
  448. package/dist/models/component.d.mts +41 -0
  449. package/dist/models/component.mjs +59 -0
  450. package/dist/models/component.mjs.map +1 -0
  451. package/dist/models/connections.d.mts +39 -0
  452. package/dist/models/connections.mjs +111 -0
  453. package/dist/models/connections.mjs.map +1 -0
  454. package/dist/models/content-ref.d.mts +1 -3
  455. package/dist/models/content-ref.mjs +2 -3
  456. package/dist/models/content-ref.mjs.map +1 -1
  457. package/dist/models/credentials.d.mts +0 -2
  458. package/dist/models/credentials.mjs +13 -4
  459. package/dist/models/credentials.mjs.map +1 -1
  460. package/dist/models/design-credentials.d.mts +39 -0
  461. package/dist/models/design-credentials.mjs +85 -0
  462. package/dist/models/design-credentials.mjs.map +1 -0
  463. package/dist/models/design-health.d.mts +14 -0
  464. package/dist/models/design-health.mjs +24 -0
  465. package/dist/models/design-health.mjs.map +1 -0
  466. package/dist/models/design-nodes.d.mts +81 -0
  467. package/dist/models/design-nodes.mjs +221 -0
  468. package/dist/models/design-nodes.mjs.map +1 -0
  469. package/dist/models/design-renders.mjs +73 -0
  470. package/dist/models/design-renders.mjs.map +1 -0
  471. package/dist/models/design-resolve.d.mts +27 -0
  472. package/dist/models/design-resolve.mjs +40 -0
  473. package/dist/models/design-resolve.mjs.map +1 -0
  474. package/dist/models/design.d.mts +37 -0
  475. package/dist/models/design.mjs +89 -0
  476. package/dist/models/design.mjs.map +1 -0
  477. package/dist/models/inherited-ratio.d.mts +19 -0
  478. package/dist/models/inherited-ratio.mjs +21 -0
  479. package/dist/models/inherited-ratio.mjs.map +1 -0
  480. package/dist/models/insight.d.mts +68 -0
  481. package/dist/models/insight.mjs +161 -0
  482. package/dist/models/insight.mjs.map +1 -0
  483. package/dist/models/label.d.mts +4 -4
  484. package/dist/models/label.mjs +26 -12
  485. package/dist/models/label.mjs.map +1 -1
  486. package/dist/models/member.d.mts +1 -3
  487. package/dist/models/member.mjs +6 -6
  488. package/dist/models/member.mjs.map +1 -1
  489. package/dist/models/notification-channel.d.mts +37 -5
  490. package/dist/models/notification-channel.mjs +89 -11
  491. package/dist/models/notification-channel.mjs.map +1 -1
  492. package/dist/models/notification-subscription.d.mts +1 -4
  493. package/dist/models/notification-subscription.mjs +8 -11
  494. package/dist/models/notification-subscription.mjs.map +1 -1
  495. package/dist/models/project-group-mapping.d.mts +6 -3
  496. package/dist/models/project-group-mapping.mjs +15 -6
  497. package/dist/models/project-group-mapping.mjs.map +1 -1
  498. package/dist/models/project.d.mts +9 -3
  499. package/dist/models/project.mjs +10 -6
  500. package/dist/models/project.mjs.map +1 -1
  501. package/dist/models/public-origin.d.mts +61 -0
  502. package/dist/models/public-origin.mjs +113 -0
  503. package/dist/models/public-origin.mjs.map +1 -0
  504. package/dist/models/review-switch-off.d.mts +12 -0
  505. package/dist/models/review-switch-off.mjs +25 -0
  506. package/dist/models/review-switch-off.mjs.map +1 -0
  507. package/dist/models/site-settings.d.mts +21 -0
  508. package/dist/models/site-settings.mjs +47 -0
  509. package/dist/models/site-settings.mjs.map +1 -0
  510. package/dist/models/snapshot.d.mts +39 -3
  511. package/dist/models/snapshot.mjs +54 -5
  512. package/dist/models/snapshot.mjs.map +1 -1
  513. package/dist/models/token.d.mts +13 -3
  514. package/dist/models/token.mjs +24 -7
  515. package/dist/models/token.mjs.map +1 -1
  516. package/dist/models/usage.d.mts +74 -0
  517. package/dist/models/usage.mjs +148 -0
  518. package/dist/models/usage.mjs.map +1 -0
  519. package/dist/models/user.d.mts +1 -3
  520. package/dist/models/user.mjs +5 -5
  521. package/dist/models/user.mjs.map +1 -1
  522. package/dist/models/webhook.d.mts +15 -3
  523. package/dist/models/webhook.mjs +34 -6
  524. package/dist/models/webhook.mjs.map +1 -1
  525. package/dist/models.d.mts +30 -4
  526. package/dist/models.mjs +31 -6
  527. package/dist/options.d.mts +16 -0
  528. package/dist/options.mjs +88 -0
  529. package/dist/options.mjs.map +1 -0
  530. package/dist/paths.d.mts +21 -6
  531. package/dist/paths.mjs +57 -12
  532. package/dist/paths.mjs.map +1 -1
  533. package/dist/retention/ai.d.mts +16 -0
  534. package/dist/retention/ai.mjs +22 -0
  535. package/dist/retention/ai.mjs.map +1 -0
  536. package/dist/retention/pending.mjs +46 -0
  537. package/dist/retention/pending.mjs.map +1 -0
  538. package/dist/retention/published-gzip-sweep.mjs +28 -0
  539. package/dist/retention/published-gzip-sweep.mjs.map +1 -0
  540. package/dist/retention/screenshot-sweep.d.mts +49 -0
  541. package/dist/retention/screenshot-sweep.mjs +127 -0
  542. package/dist/retention/screenshot-sweep.mjs.map +1 -0
  543. package/dist/retention.d.mts +16 -4
  544. package/dist/retention.mjs +76 -16
  545. package/dist/retention.mjs.map +1 -1
  546. package/dist/schema/baseline.d.mts +8 -2
  547. package/dist/schema/build-component.d.mts +23 -0
  548. package/dist/schema/build-review.d.mts +15 -0
  549. package/dist/schema/build.d.mts +7 -2
  550. package/dist/schema/capture-attempt.d.mts +0 -2
  551. package/dist/schema/capture-job.d.mts +58 -0
  552. package/dist/schema/capture-shard.d.mts +33 -0
  553. package/dist/schema/comment.d.mts +2 -2
  554. package/dist/schema/connection.d.mts +22 -0
  555. package/dist/schema/content-ref.d.mts +0 -2
  556. package/dist/schema/design.d.mts +56 -0
  557. package/dist/schema/insight.d.mts +52 -0
  558. package/dist/schema/label.d.mts +0 -2
  559. package/dist/schema/member.d.mts +0 -2
  560. package/dist/schema/notification.d.mts +4 -2
  561. package/dist/schema/project-group-mapping.d.mts +0 -2
  562. package/dist/schema/project.d.mts +21 -2
  563. package/dist/schema/site-setting.d.mts +19 -0
  564. package/dist/schema/snapshot.d.mts +17 -2
  565. package/dist/schema/token.d.mts +0 -2
  566. package/dist/schema/usage.d.mts +28 -0
  567. package/dist/schema/user.d.mts +0 -2
  568. package/dist/schema/webhook.d.mts +0 -2
  569. package/dist/schema.d.mts +12 -6
  570. package/dist/serverless.d.mts +19 -0
  571. package/dist/serverless.mjs +36 -0
  572. package/dist/serverless.mjs.map +1 -0
  573. package/dist/test-helpers/build-reference-contract.d.mts +14 -0
  574. package/dist/test-helpers/build-reference-contract.mjs +66 -0
  575. package/dist/test-helpers/build-reference-contract.mjs.map +1 -0
  576. package/dist/test-helpers/create-project.d.mts +1 -3
  577. package/dist/test-helpers/create-project.mjs +1 -2
  578. package/dist/test-helpers/database-contract.d.mts +0 -2
  579. package/dist/test-helpers/database-contract.mjs +37 -2
  580. package/dist/test-helpers/database-contract.mjs.map +1 -1
  581. package/dist/test-helpers/deferred.d.mts +37 -0
  582. package/dist/test-helpers/deferred.mjs +60 -0
  583. package/dist/test-helpers/deferred.mjs.map +1 -0
  584. package/dist/test-helpers/design-contract.d.mts +19 -0
  585. package/dist/test-helpers/design-contract.mjs +39 -0
  586. package/dist/test-helpers/design-contract.mjs.map +1 -0
  587. package/dist/test-helpers/fake-adapters.d.mts +0 -2
  588. package/dist/test-helpers/fake-adapters.mjs +1 -2
  589. package/dist/test-helpers/fake-database.d.mts +0 -2
  590. package/dist/test-helpers/fake-database.mjs +21 -4
  591. package/dist/test-helpers/fake-database.mjs.map +1 -1
  592. package/dist/test-helpers/fake-design.d.mts +41 -0
  593. package/dist/test-helpers/fake-design.mjs +113 -0
  594. package/dist/test-helpers/fake-design.mjs.map +1 -0
  595. package/dist/test-helpers/fake-notifier.d.mts +19 -0
  596. package/dist/test-helpers/fake-notifier.mjs +43 -0
  597. package/dist/test-helpers/fake-notifier.mjs.map +1 -0
  598. package/dist/test-helpers/fake-storage.d.mts +0 -2
  599. package/dist/test-helpers/fake-storage.mjs +1 -2
  600. package/dist/test-helpers/fake-tables.mjs +260 -69
  601. package/dist/test-helpers/fake-tables.mjs.map +1 -1
  602. package/dist/test-helpers/manual-clock.d.mts +25 -0
  603. package/dist/test-helpers/manual-clock.mjs +55 -0
  604. package/dist/test-helpers/manual-clock.mjs.map +1 -0
  605. package/dist/test-helpers/notifier-contract.d.mts +7 -3
  606. package/dist/test-helpers/notifier-contract.mjs +33 -5
  607. package/dist/test-helpers/notifier-contract.mjs.map +1 -1
  608. package/dist/test-helpers/queue-contract.d.mts +16 -4
  609. package/dist/test-helpers/queue-contract.mjs +196 -3
  610. package/dist/test-helpers/queue-contract.mjs.map +1 -1
  611. package/dist/test-helpers/queue-multi-instance.d.mts +18 -0
  612. package/dist/test-helpers/queue-multi-instance.mjs +205 -0
  613. package/dist/test-helpers/queue-multi-instance.mjs.map +1 -0
  614. package/dist/test-helpers/runner-contract.d.mts +0 -2
  615. package/dist/test-helpers/runner-contract.mjs +12 -2
  616. package/dist/test-helpers/runner-contract.mjs.map +1 -1
  617. package/dist/test-helpers/sql-chunks.mjs +25 -2
  618. package/dist/test-helpers/sql-chunks.mjs.map +1 -1
  619. package/dist/test-helpers/storage-contract.d.mts +0 -2
  620. package/dist/test-helpers/storage-contract.mjs +2 -3
  621. package/dist/test-helpers.d.mts +10 -4
  622. package/dist/test-helpers.mjs +9 -3
  623. package/dist/tracing.mjs +36 -6
  624. package/dist/tracing.mjs.map +1 -1
  625. package/dist/types.d.mts +14 -5
  626. package/dist/types.mjs +22 -6
  627. package/dist/types.mjs.map +1 -1
  628. package/dist/urls.d.mts +4 -2
  629. package/dist/urls.mjs +12 -4
  630. package/dist/urls.mjs.map +1 -1
  631. package/dist/utils/adaptive-concurrency.d.mts +64 -0
  632. package/dist/utils/adaptive-concurrency.mjs +148 -0
  633. package/dist/utils/adaptive-concurrency.mjs.map +1 -0
  634. package/dist/utils/connect-retry.d.mts +26 -0
  635. package/dist/utils/connect-retry.mjs +42 -0
  636. package/dist/utils/connect-retry.mjs.map +1 -0
  637. package/dist/utils/encrypt.d.mts +0 -2
  638. package/dist/utils/encrypt.mjs +1 -2
  639. package/dist/utils/environment.d.mts +17 -0
  640. package/dist/utils/environment.mjs +58 -0
  641. package/dist/utils/environment.mjs.map +1 -0
  642. package/dist/utils/hash.d.mts +0 -2
  643. package/dist/utils/hash.mjs +1 -2
  644. package/dist/utils/http.d.mts +29 -3
  645. package/dist/utils/http.mjs +100 -19
  646. package/dist/utils/http.mjs.map +1 -1
  647. package/dist/utils/map-adaptive.d.mts +13 -0
  648. package/dist/utils/map-adaptive.mjs +71 -0
  649. package/dist/utils/map-adaptive.mjs.map +1 -0
  650. package/dist/utils/map-limit.d.mts +8 -0
  651. package/dist/utils/map-limit.mjs +31 -0
  652. package/dist/utils/map-limit.mjs.map +1 -0
  653. package/dist/utils/mime.d.mts +0 -2
  654. package/dist/utils/mime.mjs +1 -2
  655. package/dist/utils/page-limiter.d.mts +35 -0
  656. package/dist/utils/page-limiter.mjs +55 -0
  657. package/dist/utils/page-limiter.mjs.map +1 -0
  658. package/dist/utils/path-security.d.mts +0 -2
  659. package/dist/utils/path-security.mjs +2 -4
  660. package/dist/utils/path-security.mjs.map +1 -1
  661. package/dist/utils/public-origin.d.mts +18 -0
  662. package/dist/utils/public-origin.mjs +74 -0
  663. package/dist/utils/public-origin.mjs.map +1 -0
  664. package/dist/utils/redact.d.mts +0 -2
  665. package/dist/utils/redact.mjs +4 -2
  666. package/dist/utils/redact.mjs.map +1 -1
  667. package/dist/utils/remote-environment.d.mts +76 -0
  668. package/dist/utils/remote-environment.mjs +163 -0
  669. package/dist/utils/remote-environment.mjs.map +1 -0
  670. package/dist/utils/resources.d.mts +62 -0
  671. package/dist/utils/resources.mjs +121 -0
  672. package/dist/utils/resources.mjs.map +1 -0
  673. package/dist/utils/screenshot-store.d.mts +13 -0
  674. package/dist/utils/screenshot-store.mjs +40 -0
  675. package/dist/utils/screenshot-store.mjs.map +1 -0
  676. package/dist/utils/session-gate.d.mts +23 -0
  677. package/dist/utils/session-gate.mjs +69 -0
  678. package/dist/utils/session-gate.mjs.map +1 -0
  679. package/dist/utils/storybook-token.d.mts +89 -0
  680. package/dist/utils/storybook-token.mjs +135 -0
  681. package/dist/utils/storybook-token.mjs.map +1 -0
  682. package/dist/utils/storybook-url.d.mts +13 -0
  683. package/dist/utils/storybook-url.mjs +20 -0
  684. package/dist/utils/storybook-url.mjs.map +1 -0
  685. package/dist/utils/timing.d.mts +0 -2
  686. package/dist/utils/timing.mjs +2 -3
  687. package/dist/utils/timing.mjs.map +1 -1
  688. package/dist/utils/ulid.d.mts +0 -2
  689. package/dist/utils/ulid.mjs +1 -2
  690. package/dist/utils/zip-read.mjs +128 -0
  691. package/dist/utils/zip-read.mjs.map +1 -0
  692. package/dist/utils/zip-write.d.mts +16 -0
  693. package/dist/utils/zip-write.mjs +187 -0
  694. package/dist/utils/zip-write.mjs.map +1 -0
  695. package/dist/utils.d.mts +17 -3
  696. package/dist/utils.mjs +18 -4
  697. package/package.json +35 -26
  698. package/dist/adapter/capture-runner.mjs.map +0 -1
  699. package/dist/adapter/git-host/comments.d.mts +0 -41
  700. package/dist/adapter/git-host/comments.mjs +0 -54
  701. package/dist/adapter/git-host/comments.mjs.map +0 -1
  702. package/dist/adapter/git-host/helpers.d.mts +0 -13
  703. package/dist/adapter/git-host/helpers.mjs +0 -30
  704. package/dist/adapter/git-host/helpers.mjs.map +0 -1
  705. package/dist/adapter/git-host.d.mts +0 -42
  706. package/dist/capture/queue.d.mts +0 -38
  707. package/dist/capture/queue.mjs +0 -98
  708. package/dist/capture/queue.mjs.map +0 -1
  709. package/dist/capture/recovery.d.mts +0 -21
  710. package/dist/capture/recovery.mjs +0 -83
  711. package/dist/capture/recovery.mjs.map +0 -1
  712. package/dist/capture/status-fanout.mjs +0 -72
  713. package/dist/capture/status-fanout.mjs.map +0 -1
  714. package/dist/diff/engine.d.mts +0 -16
  715. package/dist/diff/engine.mjs +0 -87
  716. package/dist/diff/engine.mjs.map +0 -1
  717. package/dist/diff/options.d.mts +0 -42
  718. package/dist/diff/options.mjs +0 -15
  719. package/dist/diff/options.mjs.map +0 -1
  720. package/dist/models/status-config.d.mts +0 -38
  721. package/dist/models/status-config.mjs +0 -63
  722. package/dist/models/status-config.mjs.map +0 -1
  723. package/dist/schema/status-config.d.mts +0 -16
  724. package/dist/test-helpers/git-contract.d.mts +0 -11
  725. package/dist/test-helpers/git-contract.mjs +0 -34
  726. package/dist/test-helpers/git-contract.mjs.map +0 -1
  727. /package/dist/adapter/{git-host.mjs → oauth.mjs} +0 -0
@@ -6,14 +6,14 @@ import { DatabaseAdapter } from "../adapter/database.mjs";
6
6
  import { StorageAdapter } from "../adapter/storage.mjs";
7
7
  import { SecretInput } from "../utils/encrypt.mjs";
8
8
  import { Build } from "../schema/build.mjs";
9
+ import { Project } from "../schema/project.mjs";
9
10
  import { BuildTables } from "../models/build.mjs";
10
11
  import { AttemptLogRecorder } from "../models/capture-attempt.mjs";
11
- import { Project } from "../schema/project.mjs";
12
12
  import { BaselineTables } from "../models/baseline.mjs";
13
13
  import { SnapshotTables } from "../models/snapshot.mjs";
14
14
  import { InheritedStory } from "./affected.mjs";
15
+ import { CaptureProgress } from "./progress.mjs";
15
16
  import { Logger } from "pino";
16
- //#region src/capture/pipeline.d.ts
17
17
  /**
18
18
  * Persist a completed capture run: write screenshots, diff against the branch
19
19
  * baseline, create snapshots, and finalize the build.
@@ -27,7 +27,7 @@ import { Logger } from "pino";
27
27
  * @param flakyFailedStoryIds - Story ids that failed but are marked flaky
28
28
  * (non-blocking). They are logged as warnings and do not block the build.
29
29
  */
30
- declare function persistCapture(ctx: CaptureContext, renderFailedStoryIds?: ReadonlySet<string>, flakyFailedStoryIds?: ReadonlySet<string>, a11yFailedStoryIds?: ReadonlySet<string>): Promise<void>;
30
+ declare function persistCapture(input: CaptureContext, renderFailedStoryIds?: ReadonlySet<string>, flakyFailedStoryIds?: ReadonlySet<string>, a11yFailedStoryIds?: ReadonlySet<string>): Promise<void>;
31
31
  /** Table handles required by the capture pipeline. */
32
32
  type PipelineTables = BuildTables & BaselineTables & SnapshotTables;
33
33
  /** Persistence inputs for a completed capture run. */
@@ -44,6 +44,10 @@ interface CaptureContext {
44
44
  build: Build;
45
45
  /** Viewports at which stories were captured. */
46
46
  viewports: Viewport[];
47
+ /** Engines captured this run, primary first (default: chromium only). */
48
+ browsers?: string[];
49
+ /** Secondary engines with no baselines yet; worked out by `persistCapture`, or fixed up front by a shard plan. */
50
+ freshBrowsers?: ReadonlySet<string>;
47
51
  /** Screenshot buffers produced by the capture renderer. */
48
52
  captures: RenderedSnapshot[];
49
53
  /** Stories inheriting their baseline without rendering (affected capture). */
@@ -52,9 +56,10 @@ interface CaptureContext {
52
56
  logger?: Logger;
53
57
  /** Optional per-attempt log recorder (mirrors logger lines into the DB). */
54
58
  recordLog?: AttemptLogRecorder;
59
+ /** Called per snapshot persisted, so the job's lease sees a long diff phase making progress. */
60
+ progress?: CaptureProgress | undefined;
55
61
  /** Server secret for decrypting webhook secrets at send time. */
56
62
  secret?: SecretInput;
57
63
  }
58
- //#endregion
59
64
  export { CaptureContext, PipelineTables, persistCapture };
60
65
  //# sourceMappingURL=pipeline.d.mts.map
@@ -1,16 +1,21 @@
1
1
  import "node:path";
2
2
  import "node:url";
3
3
  import.meta.url;
4
- import { BuildModel } from "../models/build.mjs";
4
+ import { ReferenceGenerationConflict } from "../adapter/database.mjs";
5
+ import { DEFAULT_BROWSER } from "../adapters/capture-target.mjs";
5
6
  import { emitAttemptLog } from "../models/capture-attempt.mjs";
6
- import { diffPath, screenshotPath } from "../paths.mjs";
7
- import { BaselineModel } from "../models/baseline.mjs";
7
+ import { BuildModel } from "../models/build.mjs";
8
+ import { diffPath } from "../paths.mjs";
9
+ import { storeScreenshot } from "../utils/screenshot-store.mjs";
10
+ import { BaselineWriteConflict } from "../models/baseline-conflict.mjs";
8
11
  import { NO_BASELINE } from "../models/baseline-status.mjs";
12
+ import { BaselineModel } from "../models/baseline.mjs";
13
+ import { assertScreenshotBuffer } from "./guards.mjs";
9
14
  import { SnapshotModel } from "../models/snapshot.mjs";
15
+ import { mapLimit } from "../utils/map-limit.mjs";
16
+ import { freezeComparison, sourceSnapshotId } from "./comparison-reference.mjs";
10
17
  import { diffStoredScreenshots, writeDiffOverlay } from "./diff-record.mjs";
11
- import { assertScreenshotBuffer } from "./guards.mjs";
12
- import { SIZING_DEFAULTS, infraHashFor } from "./sizing.mjs";
13
- //#region src/capture/pipeline.ts
18
+ import { buildFingerprint, changedFields, fingerprintHash, mergeFingerprint, parseFingerprint } from "./fingerprint.mjs";
14
19
  /**
15
20
  * Persist a completed capture run: write screenshots, diff against the branch
16
21
  * baseline, create snapshots, and finalize the build.
@@ -24,13 +29,24 @@ import { SIZING_DEFAULTS, infraHashFor } from "./sizing.mjs";
24
29
  * @param flakyFailedStoryIds - Story ids that failed but are marked flaky
25
30
  * (non-blocking). They are logged as warnings and do not block the build.
26
31
  */
27
- async function persistCapture(ctx, renderFailedStoryIds = /* @__PURE__ */ new Set(), flakyFailedStoryIds = /* @__PURE__ */ new Set(), a11yFailedStoryIds = /* @__PURE__ */ new Set()) {
32
+ async function persistCapture(input, renderFailedStoryIds = /* @__PURE__ */ new Set(), flakyFailedStoryIds = /* @__PURE__ */ new Set(), a11yFailedStoryIds = /* @__PURE__ */ new Set()) {
33
+ const sets = await persistRendered(input, renderFailedStoryIds, flakyFailedStoryIds, a11yFailedStoryIds);
34
+ for (const id of await persistInherited(input)) sets.failed.add(id);
35
+ await finalizeBuild(input, allStoryIds(input), sets.failed, sets.flaky, sets.a11y);
36
+ }
37
+ /**
38
+ * Persist the rendered captures only: screenshots, diffs and snapshot rows, without the
39
+ * inherited snapshots or the build finalize. A sharded capture runs this once per shard.
40
+ */
41
+ async function persistRendered(input, renderFailedStoryIds = /* @__PURE__ */ new Set(), flakyFailedStoryIds = /* @__PURE__ */ new Set(), a11yFailedStoryIds = /* @__PURE__ */ new Set()) {
42
+ const ctx = await withFreshBrowsers(input);
28
43
  const failedStoryIds = new Set(renderFailedStoryIds);
29
44
  const flakyIds = new Set(flakyFailedStoryIds);
30
45
  const a11yIds = new Set(a11yFailedStoryIds);
31
- await Promise.all(ctx.captures.map(async (capture) => {
46
+ for (const group of capturesByPhase(ctx)) await mapLimit(group, 4, async (capture) => {
32
47
  try {
33
48
  await persistSnapshot(ctx, capture);
49
+ ctx.progress?.();
34
50
  } catch (error) {
35
51
  if (flakyIds.has(capture.story.id) || a11yIds.has(capture.story.id)) {
36
52
  if (flakyIds.has(capture.story.id)) flakyIds.add(capture.story.id);
@@ -55,7 +71,7 @@ async function persistCapture(ctx, renderFailedStoryIds = /* @__PURE__ */ new Se
55
71
  viewport: capture.viewportName
56
72
  });
57
73
  }
58
- }));
74
+ });
59
75
  for (const id of flakyIds) if (!failedStoryIds.has(id)) {
60
76
  ctx.logger?.warn({ storyId: id }, "flaky story failed (non-blocking)");
61
77
  await emitAttemptLog(ctx.recordLog, ctx.logger, "warn", "flaky story failed (non-blocking)", { storyId: id });
@@ -64,8 +80,62 @@ async function persistCapture(ctx, renderFailedStoryIds = /* @__PURE__ */ new Se
64
80
  ctx.logger?.warn({ storyId: id }, "a11y violations found (non-blocking)");
65
81
  await emitAttemptLog(ctx.recordLog, ctx.logger, "warn", "a11y violations found (non-blocking)", { storyId: id });
66
82
  }
67
- for (const id of await persistInherited(ctx)) failedStoryIds.add(id);
68
- await finalize(ctx, allStoryIds(ctx), failedStoryIds, flakyIds, a11yIds);
83
+ return {
84
+ failed: failedStoryIds,
85
+ flaky: flakyIds,
86
+ a11y: a11yIds
87
+ };
88
+ }
89
+ /** Engines of this run, primary (first) first. */
90
+ function runBrowsers(ctx) {
91
+ const listed = ctx.browsers && ctx.browsers.length > 0 ? ctx.browsers : [DEFAULT_BROWSER];
92
+ return [...new Set(listed)];
93
+ }
94
+ function primaryBrowser(ctx) {
95
+ return runBrowsers(ctx)[0] ?? "chromium";
96
+ }
97
+ /** The capture's axe violation texts as the JSON stored on the snapshot; null when there are none. */
98
+ function a11yJsonOf(capture) {
99
+ return capture.a11y && capture.a11y.length > 0 ? JSON.stringify(capture.a11y) : null;
100
+ }
101
+ function browserOf(capture) {
102
+ return capture.browser ?? "chromium";
103
+ }
104
+ /** Captures split into the primary engine's, then everyone else's. */
105
+ function capturesByPhase(ctx) {
106
+ const primary = primaryBrowser(ctx);
107
+ const first = ctx.captures.filter((capture) => browserOf(capture) === primary);
108
+ const rest = ctx.captures.filter((capture) => browserOf(capture) !== primary);
109
+ return rest.length > 0 ? [first, rest] : [first];
110
+ }
111
+ /** Secondary engines with no baseline yet (their first snapshots bootstrap from the primary). */
112
+ async function freshBrowsersOf(ctx) {
113
+ const primary = primaryBrowser(ctx);
114
+ const baselines = new BaselineModel(ctx.db, ctx.tables, ctx.storage, ctx.secret);
115
+ const secondary = runBrowsers(ctx).filter((browser) => browser !== primary);
116
+ const checks = await Promise.all(secondary.map(async (browser) => ({
117
+ browser,
118
+ fresh: !await baselines.hasAny(ctx.project.id, browser)
119
+ })));
120
+ return new Set(checks.filter((check) => check.fresh).map((check) => check.browser));
121
+ }
122
+ /** Mark secondary engines with no baseline yet: their first snapshots bootstrap. */
123
+ async function withFreshBrowsers(ctx) {
124
+ return ctx.freshBrowsers ? ctx : {
125
+ ...ctx,
126
+ freshBrowsers: await freshBrowsersOf(ctx)
127
+ };
128
+ }
129
+ /**
130
+ * A newly enabled engine accepts a story/mode's first snapshot when the
131
+ * primary engine's snapshot of it is clean (Chromatic's "auto-accepted where
132
+ * the primary browser was accepted"); anything else goes to review as `new`.
133
+ */
134
+ async function bootstrapAccepts(ctx, capture) {
135
+ const browser = browserOf(capture);
136
+ if (!ctx.freshBrowsers?.has(browser)) return false;
137
+ const primary = primaryBrowser(ctx);
138
+ return (await new SnapshotModel(ctx.db, ctx.tables).listByBuild(ctx.build.id)).some((snapshot) => snapshot.storyId === capture.story.id && snapshot.viewportName === capture.viewportName && (snapshot.browser ?? "chromium") === primary && (snapshot.status === "approved" || snapshot.status === "unchanged"));
69
139
  }
70
140
  /** Persist one inherited snapshot; returns the story id on failure. */
71
141
  async function tryPersistInherited(ctx, inherited) {
@@ -86,25 +156,45 @@ async function tryPersistInherited(ctx, inherited) {
86
156
  }
87
157
  }
88
158
  /** Persist inherited snapshots; a failure marks the story failed. */
159
+ /** Persist the inherited snapshots (stories reusing their baseline); returns the story ids that failed. */
89
160
  async function persistInherited(ctx) {
90
- const outcomes = await Promise.all((ctx.inherited ?? []).map(async (inherited) => await tryPersistInherited(ctx, inherited)));
161
+ const outcomes = await mapLimit(ctx.inherited ?? [], 4, async (inherited) => {
162
+ const failed = await tryPersistInherited(ctx, inherited);
163
+ ctx.progress?.();
164
+ return failed;
165
+ });
91
166
  return new Set(outcomes.filter((id) => id !== null));
92
167
  }
93
168
  /** Create an unchanged snapshot reusing the baseline screenshot. */
94
169
  async function persistInheritedSnapshot(ctx, inherited) {
95
- const infraHash = infraHashFor(ctx.project.browser ?? "chromium", ctx.viewports, SIZING_DEFAULTS);
170
+ const browser = browserOf(inherited);
171
+ const infraHash = inherited.baseline.infraHash;
96
172
  const snapshots = new SnapshotModel(ctx.db, ctx.tables);
173
+ const comparison = await freezeComparison(ctx.storage, ctx.project.id, ctx.build.id, inherited.baseline, {
174
+ defaultBranch: ctx.project.gitDefaultBranch,
175
+ mode: modeJsonOf(inherited.viewport),
176
+ target: browser,
177
+ width: inherited.viewport.width,
178
+ height: inherited.viewport.height,
179
+ captureFingerprint: inherited.baseline.fingerprint ?? null,
180
+ sourceSnapshotId: await sourceSnapshotId(ctx.db, inherited.baseline)
181
+ });
97
182
  const snapshot = await snapshots.create(ctx.project.id, ctx.build.id, {
183
+ ...comparison,
184
+ browser,
98
185
  storyId: inherited.story.id,
99
186
  storyName: inherited.story.name,
100
187
  storyTitle: inherited.story.title,
101
188
  storyImportPath: inherited.story.importPath ?? "",
189
+ designUrl: inherited.story.designUrl ?? null,
102
190
  viewportName: inherited.viewport.name,
103
191
  viewportWidth: inherited.viewport.width,
104
192
  viewportHeight: inherited.viewport.height,
105
193
  screenshotPath: inherited.baseline.screenshotPath,
106
194
  infraHash,
195
+ mode: modeJsonOf(inherited.viewport),
107
196
  inherited: true,
197
+ sourceBuildId: inherited.baseline.sourceBuildId ?? null,
108
198
  baselineId: inherited.baseline.id,
109
199
  baselineVersion: inherited.baseline.updatedAt
110
200
  });
@@ -123,6 +213,10 @@ function allStoryIds(ctx) {
123
213
  for (const inherited of ctx.inherited ?? []) ids.add(inherited.story.id);
124
214
  return ids;
125
215
  }
216
+ /** JSON for the snapshot `mode` column: the globals a mode applied (null for plain viewports). */
217
+ function modeJsonOf(viewport) {
218
+ return viewport?.globals ? JSON.stringify(viewport.globals) : null;
219
+ }
126
220
  function viewportByName(ctx, name) {
127
221
  return ctx.viewports.find((v) => v.name === name) ?? {
128
222
  name,
@@ -130,77 +224,212 @@ function viewportByName(ctx, name) {
130
224
  height: 0
131
225
  };
132
226
  }
133
- async function persistSnapshot(ctx, capture) {
227
+ /** Where the capture's screenshot lives: already stored by the orchestrator, or stored now. */
228
+ async function screenshotLocation(ctx, capture) {
229
+ if (capture.storedPath) return capture.storedPath;
134
230
  assertScreenshotBuffer(capture.screenshot);
231
+ return await storeScreenshot(ctx.storage, ctx.project.id, capture.screenshot);
232
+ }
233
+ async function persistSnapshot(ctx, capture) {
135
234
  const viewport = capture.viewport ?? viewportByName(ctx, capture.viewportName);
136
- const screenshot = screenshotPath(ctx.project.id, ctx.build.id, capture.story.id, capture.viewportName);
137
- await ctx.storage.write(screenshot, capture.screenshot);
138
- const baseline = await resolveBaseline(ctx, capture.story.id, capture.viewportName);
235
+ const browser = browserOf(capture);
236
+ const screenshot = await screenshotLocation(ctx, capture);
237
+ const baseline = await resolveBaseline(ctx, capture.story.id, capture.viewportName, browser);
139
238
  if (!baseline) {
140
239
  await createWithoutBaseline(ctx, capture, viewport, screenshot);
141
240
  return;
142
241
  }
143
242
  await createWithBaseline(ctx, capture, viewport, screenshot, baseline);
144
243
  }
145
- async function resolveBaseline(ctx, storyId, viewport) {
146
- return await new BaselineModel(ctx.db, ctx.tables, ctx.storage, ctx.secret).resolve(ctx.project.id, storyId, viewport, ctx.build.gitBranch, ctx.project.gitDefaultBranch);
244
+ async function resolveBaseline(ctx, storyId, viewport, browser) {
245
+ return await new BaselineModel(ctx.db, ctx.tables, ctx.storage, ctx.secret).resolve(ctx.project.id, storyId, viewport, ctx.build.gitBranch, ctx.project.gitDefaultBranch, browser);
147
246
  }
148
247
  async function createWithoutBaseline(ctx, capture, viewport, screenshot) {
149
248
  const snapshots = new SnapshotModel(ctx.db, ctx.tables);
150
- const status = ctx.build.isDefault ? "approved" : "new";
151
- const infraHash = infraHashFor(ctx.project.browser ?? "chromium", ctx.viewports, SIZING_DEFAULTS);
249
+ const browser = browserOf(capture);
250
+ const accepted = ctx.build.isDefault || await bootstrapAccepts(ctx, capture);
251
+ const status = accepted ? "approved" : "new";
252
+ const now = fingerprintOf(capture, viewport);
152
253
  const snapshot = await snapshots.create(ctx.project.id, ctx.build.id, {
254
+ browser,
255
+ durationMs: capture.durationMs ?? null,
256
+ a11yViolations: a11yJsonOf(capture),
153
257
  storyId: capture.story.id,
154
258
  storyName: capture.story.name,
155
259
  storyTitle: capture.story.title,
156
260
  storyImportPath: capture.story.importPath ?? "",
261
+ designUrl: capture.story.designUrl ?? null,
157
262
  viewportName: capture.viewportName,
158
263
  viewportWidth: viewport.width,
159
264
  viewportHeight: viewport.height,
160
265
  screenshotPath: screenshot,
161
- infraHash,
266
+ infraHash: now.infraHash,
267
+ mode: modeJsonOf(viewport),
162
268
  baselineVersion: NO_BASELINE
163
269
  });
164
270
  await snapshots.setStatus(snapshot.id, status);
165
- if (ctx.build.isDefault) await new BaselineModel(ctx.db, ctx.tables, ctx.storage, ctx.secret).upsert(ctx.project.id, capture.story.id, capture.viewportName, ctx.build.gitBranch, snapshot.id, screenshot, infraHash);
271
+ if (accepted) await new BaselineModel(ctx.db, ctx.tables, ctx.storage, ctx.secret).upsert(ctx.project.id, capture.story.id, capture.viewportName, ctx.build.gitBranch, snapshot.id, screenshot, now.infraHash, {
272
+ mode: modeJsonOf(viewport),
273
+ browser,
274
+ fingerprint: now.json
275
+ });
276
+ }
277
+ function fingerprintOf(capture, viewport) {
278
+ return captureFingerprintOf(buildFingerprint(browserOf(capture), viewport, capture.environment));
279
+ }
280
+ /** A fingerprint as stored: its hash (the `infraHash`) and JSON. */
281
+ function captureFingerprintOf(fingerprint) {
282
+ return {
283
+ fingerprint,
284
+ infraHash: fingerprintHash(fingerprint),
285
+ json: JSON.stringify(fingerprint)
286
+ };
166
287
  }
288
+ /**
289
+ * What changed in the capture environment since the baseline was recorded, or null when nothing
290
+ * did. Compared component by component, only where both sides report a value: a capture with no
291
+ * environment (spooled before a browser crash) is unknown, not a change. A baseline from before
292
+ * fingerprints cannot be compared, so it is never reported as changed; it is backfilled instead.
293
+ */
294
+ function environmentChange(baseline, now) {
295
+ const from = parseFingerprint(baseline.fingerprint);
296
+ if (!from) return null;
297
+ const changed = changedFields(from, now.fingerprint);
298
+ return changed.length > 0 ? {
299
+ changed,
300
+ from,
301
+ to: now.fingerprint
302
+ } : null;
303
+ }
304
+ /**
305
+ * A changed environment migrates the baseline without a diff only on the default branch, which is
306
+ * authoritative and auto-approves its own changes anyway. A feature branch still diffs: a real
307
+ * change is reported as `changed` with the environment change attached, never auto-accepted.
308
+ */
167
309
  async function createWithBaseline(ctx, capture, viewport, screenshot, baseline) {
168
- const result = await diffStoredScreenshots(ctx.storage, ctx.project, baseline.screenshotPath, screenshot, capture.story.parameters?.diffThreshold);
169
- const infraHash = infraHashFor(ctx.project.browser ?? "chromium", ctx.viewports, SIZING_DEFAULTS);
170
- const snapshots = new SnapshotModel(ctx.db, ctx.tables);
171
- const snapshot = await snapshots.create(ctx.project.id, ctx.build.id, {
310
+ const now = fingerprintOf(capture, viewport);
311
+ const change = environmentChange(baseline, now);
312
+ const input = {
313
+ ctx,
314
+ capture,
315
+ viewport,
316
+ screenshot,
317
+ baseline,
318
+ now,
319
+ change,
320
+ comparison: await freezeComparison(ctx.storage, ctx.project.id, ctx.build.id, baseline, {
321
+ defaultBranch: ctx.project.gitDefaultBranch,
322
+ mode: modeJsonOf(viewport),
323
+ target: browserOf(capture),
324
+ width: viewport.width,
325
+ height: viewport.height,
326
+ captureFingerprint: now.json,
327
+ sourceSnapshotId: await sourceSnapshotId(ctx.db, baseline)
328
+ })
329
+ };
330
+ if (change && ctx.build.isDefault) await persistMigration(input, change);
331
+ else await persistDiff(input);
332
+ }
333
+ /** The fingerprint to write on the baseline: the capture's, keeping components it did not report. */
334
+ function baselineFingerprintOf(input) {
335
+ const earlier = parseFingerprint(input.baseline.fingerprint);
336
+ return captureFingerprintOf(mergeFingerprint(earlier, input.now.fingerprint));
337
+ }
338
+ function snapshotInput(input) {
339
+ const { capture, viewport, screenshot, baseline, now } = input;
340
+ return {
341
+ browser: browserOf(capture),
342
+ durationMs: capture.durationMs ?? null,
343
+ a11yViolations: a11yJsonOf(capture),
172
344
  storyId: capture.story.id,
173
345
  storyName: capture.story.name,
174
346
  storyTitle: capture.story.title,
175
347
  storyImportPath: capture.story.importPath ?? "",
348
+ designUrl: capture.story.designUrl ?? null,
176
349
  viewportName: capture.viewportName,
177
350
  viewportWidth: viewport.width,
178
351
  viewportHeight: viewport.height,
179
352
  screenshotPath: screenshot,
180
- infraHash,
353
+ infraHash: now.infraHash,
354
+ mode: modeJsonOf(viewport),
181
355
  baselineId: baseline.id,
182
- baselineVersion: baseline.updatedAt
356
+ baselineVersion: baseline.updatedAt,
357
+ ...input.comparison
358
+ };
359
+ }
360
+ /**
361
+ * The default branch's capture environment changed (browser build, fonts, platform, scale): pixels
362
+ * would differ with no code change, so no diff is computed. The snapshot is accepted, records what
363
+ * changed, and the new screenshot becomes the baseline.
364
+ */
365
+ async function persistMigration(input, change) {
366
+ const { ctx, capture, viewport, screenshot, now } = input;
367
+ const snapshots = new SnapshotModel(ctx.db, ctx.tables);
368
+ const snapshot = await snapshots.create(ctx.project.id, ctx.build.id, {
369
+ ...snapshotInput(input),
370
+ envChange: JSON.stringify(change)
371
+ });
372
+ await snapshots.update(snapshot.id, {
373
+ status: "unchanged",
374
+ diffPath: null,
375
+ diffPixels: 0,
376
+ diffRatio: 0,
377
+ diffPassed: true,
378
+ infraHash: now.infraHash
183
379
  });
184
- const shouldAutomigrate = result.sizeChanged && !result.passed && ctx.project.automigrate && baseline.infraHash !== null && baseline.infraHash !== infraHash;
185
- const status = shouldAutomigrate ? "unchanged" : diffStatus(result.passed, ctx.build.isDefault);
186
- const diff = diffPath(ctx.project.id, ctx.build.id, capture.story.id, capture.viewportName);
187
- const passed = shouldAutomigrate ? true : result.passed;
188
- const pixels = shouldAutomigrate ? 0 : result.diffPixels;
189
- const ratio = shouldAutomigrate ? 0 : result.diffRatio;
190
- const overlay = await writeDiffOverlay(ctx.storage, diff, result, passed);
380
+ await upsertDefaultBaseline(ctx, snapshot.id, capture, screenshot, baselineFingerprintOf(input));
381
+ ctx.logger?.debug({
382
+ storyId: capture.story.id,
383
+ viewport: viewport.name,
384
+ changed: change.changed
385
+ }, "capture environment changed; accepted without a diff");
386
+ }
387
+ /** Diff against the baseline; a feature-branch environment change rides along as `envChange`. */
388
+ async function persistDiff(input) {
389
+ const { ctx, capture, screenshot, baseline, now, change } = input;
390
+ const result = await diffStoredScreenshots(ctx.storage, ctx.project, baseline.screenshotPath === screenshot ? screenshot : input.comparison.comparisonImagePath, screenshot, capture.story.parameters?.diffThreshold);
391
+ const snapshots = new SnapshotModel(ctx.db, ctx.tables);
392
+ const snapshot = await snapshots.create(ctx.project.id, ctx.build.id, {
393
+ ...snapshotInput(input),
394
+ ...change ? { envChange: JSON.stringify(change) } : {}
395
+ });
396
+ const diff = diffPath(ctx.project.id, ctx.build.id, capture.story.id, capture.viewportName, browserOf(capture));
397
+ const overlay = await writeDiffOverlay(ctx.storage, diff, result, result.passed);
191
398
  await snapshots.update(snapshot.id, {
192
- status,
399
+ status: diffStatus(result.passed, ctx.build.isDefault),
193
400
  diffPath: overlay,
194
- diffPixels: pixels,
195
- diffRatio: ratio,
196
- diffPassed: passed,
197
- infraHash
401
+ diffPixels: result.diffPixels,
402
+ diffRatio: result.diffRatio,
403
+ diffPassed: result.passed,
404
+ infraHash: now.infraHash
198
405
  });
199
- if (ctx.build.isDefault && (shouldAutomigrate || !passed)) await upsertDefaultBaseline(ctx, snapshot.id, capture, screenshot, infraHash);
406
+ if (ctx.build.isDefault) await refreshDefaultBaseline(input, snapshot.id, result.passed);
407
+ }
408
+ /**
409
+ * After a default-branch diff: a failed diff moves the baseline to the new screenshot; a passing
410
+ * one backfills the fingerprint when it was missing or had components the capture now reports.
411
+ */
412
+ async function refreshDefaultBaseline(input, snapshotId, passed) {
413
+ const { ctx, capture, screenshot, baseline } = input;
414
+ const target = baselineFingerprintOf(input);
415
+ if (!passed) await upsertDefaultBaseline(ctx, snapshotId, capture, screenshot, target);
416
+ else if (!baseline.fingerprint || baseline.infraHash !== target.infraHash) try {
417
+ await new BaselineModel(ctx.db, ctx.tables, ctx.storage, ctx.secret).backfillFingerprint(baseline, target.infraHash, target.json);
418
+ } catch (error) {
419
+ if (!(error instanceof BaselineWriteConflict || error instanceof ReferenceGenerationConflict)) throw error;
420
+ ctx.logger?.debug({
421
+ err: error,
422
+ baselineId: baseline.id
423
+ }, "skipped baseline fingerprint backfill after concurrent write");
424
+ }
200
425
  }
201
426
  /** Default-branch builds are authoritative: the captured screenshot becomes the baseline. */
202
- async function upsertDefaultBaseline(ctx, snapshotId, capture, screenshot, infraHash) {
203
- await new BaselineModel(ctx.db, ctx.tables, ctx.storage, ctx.secret).upsert(ctx.project.id, capture.story.id, capture.viewportName, ctx.build.gitBranch, snapshotId, screenshot, infraHash);
427
+ async function upsertDefaultBaseline(ctx, snapshotId, capture, screenshot, now) {
428
+ await new BaselineModel(ctx.db, ctx.tables, ctx.storage, ctx.secret).upsert(ctx.project.id, capture.story.id, capture.viewportName, ctx.build.gitBranch, snapshotId, screenshot, now.infraHash, {
429
+ mode: modeJsonOf(capture.viewport),
430
+ browser: browserOf(capture),
431
+ fingerprint: now.json
432
+ });
204
433
  }
205
434
  /** Snapshot status after diffing: default-branch changes are auto-approved, not queued for review. */
206
435
  function diffStatus(passed, isDefault) {
@@ -213,8 +442,16 @@ function finalBuildStatus(isDefault, failedCount, hasCaptures, build) {
213
442
  if (isDefault || hasCaptures && build.changedCount === 0) return "approved";
214
443
  return "reviewing";
215
444
  }
216
- async function finalize(ctx, storyIds, failedStoryIds, flakyFailedStoryIds = /* @__PURE__ */ new Set(), a11yFailedStoryIds = /* @__PURE__ */ new Set()) {
217
- const builds = new BuildModel(ctx.db, ctx.tables);
445
+ /**
446
+ * Close out a capture: roll the snapshot counts up, set the build's final status from the failed
447
+ * story ids, and (on the default branch) drop baselines of stories that no longer exist.
448
+ */
449
+ async function finalizeBuild(ctx, storyIds, failedStoryIds, flakyFailedStoryIds = /* @__PURE__ */ new Set(), a11yFailedStoryIds = /* @__PURE__ */ new Set()) {
450
+ const builds = new BuildModel(ctx.db, ctx.tables, ctx.logger);
451
+ if ((await builds.get(ctx.build.id))?.status === "cancelled") {
452
+ ctx.logger?.debug({ buildId: ctx.build.id }, "build is cancelled; finalize skipped");
453
+ return;
454
+ }
218
455
  const build = await builds.updateCounts(ctx.build.id);
219
456
  const hasCaptures = storyIds.size > 0;
220
457
  const status = finalBuildStatus(ctx.build.isDefault, failedStoryIds.size, hasCaptures, build);
@@ -229,7 +466,6 @@ async function finalize(ctx, storyIds, failedStoryIds, flakyFailedStoryIds = /*
229
466
  await builds.setStatus(ctx.build.id, status);
230
467
  if (ctx.build.isDefault && hasCaptures) await new BaselineModel(ctx.db, ctx.tables, ctx.storage, ctx.secret).removeOrphans(ctx.project.id, new Set(storyIds));
231
468
  }
232
- //#endregion
233
- export { diffStatus, persistCapture };
469
+ export { diffStatus, finalizeBuild, freshBrowsersOf, persistCapture, persistInherited, persistRendered };
234
470
 
235
471
  //# sourceMappingURL=pipeline.mjs.map