@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
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # @storyshelf/core
2
2
 
3
- The domain layer of StoryShelf: adapter interfaces, models, capture pipeline, diff engine, and retention logic — with no HTTP dependency, so workers import it without pulling a server. The Hono router lives in `@storyshelf/app`. Compose pluggable adapters into a complete self-hosted visual testing server.
3
+ The domain layer of StoryShelf: adapter interfaces, models, capture pipeline, diff engine, and retention logic — with no HTTP dependency, so the capture consumer imports it without pulling a server. The Hono router lives in `@storyshelf/app`. Compose pluggable adapters into a complete self-hosted visual testing server.
4
4
 
5
5
  ## Install
6
6
 
@@ -22,13 +22,12 @@ import { createShelfApp } from "@storyshelf/app";
22
22
  const app = createShelfApp({
23
23
  database, // DatabaseAdapter
24
24
  storage, // StorageAdapter
25
- captureRunner, // CaptureRunner (optional)
25
+ testing: { runner: captureRunner, concurrency: 2, compare: { threads: 2 } }, // capture pipeline + screenshot comparison (optional; absent = Storybook hosting only)
26
26
  auth, // Auth from @storyshelf/auth (optional)
27
- gitHosts, // GitHostProvider[] (optional)
27
+ notifications: { notifiers: [...chatNotifiers, ...gitNotifiers] }, // NotifierProvider[]: chat, email and git (optional)
28
28
  logger, // pino Logger (optional; built internally if omitted)
29
29
  ui: { name: "My Shelf" }, // UIConfig (optional)
30
30
  config: {
31
- captureConcurrency: 2,
32
31
  purgeTtlDays: 30,
33
32
  branchTtlDays: 30,
34
33
  branchGcIntervalMs: 86_400_000,
@@ -39,23 +38,37 @@ const app = createShelfApp({
39
38
  serve({ fetch: app.fetch, port: 3000 });
40
39
  ```
41
40
 
41
+ Adapter `setup` hooks kick off in the background when the router is created. Await them before serving for fail-fast startup (or let the first request gate on settlement), and tear down adapters on shutdown:
42
+
43
+ ```ts
44
+ await app.lifecycle.setup();
45
+
46
+ const server = serve({ fetch: app.fetch, port: 3000 });
47
+ process.on("SIGTERM", () => {
48
+ app.lifecycle
49
+ .teardown()
50
+ .then(() => server.close())
51
+ .catch(() => {});
52
+ });
53
+ ```
54
+
42
55
  ## API
43
56
 
44
57
  ### `createShelfApp(options: ShelfOptions): Hono`
45
58
 
46
59
  Assembles the router from the provided adapters. `ShelfOptions`:
47
60
 
48
- | Option | Type | Description |
49
- | --------------- | --------------------------- | ---------------------------------------------------------------------------------------- |
50
- | `database` | `DatabaseAdapter` | **Required.** Data access. |
51
- | `storage` | `StorageAdapter` | **Required.** Blob storage for screenshots, diffs, storybook archives. |
52
- | `captureRunner` | `CaptureRunner` | Optional. Enables the async capture pipeline (pure renderer). |
53
- | `captureQueue` | `CaptureQueue` | Optional. Queue adapter; defaults to `InMemoryCaptureQueue`. |
54
- | `auth` | `Auth` (`@storyshelf/auth`) | Optional. Enables auth and the login UI. |
55
- | `gitHosts` | `GitHostProvider[]` | Optional. Git-host adapters (GitHub/GitLab) for status checks, merge gates, PR comments. |
56
- | `logger` | `Logger` (pino) | Optional. Shared logger. Construct a fallback via `createShelfLogger()`. |
57
- | `ui` | `UIConfig` | Optional. UI branding. |
58
- | `config` | `ShelfConfig` | Optional. Server behavior. |
61
+ | Option | Type | Description |
62
+ | ----------------- | --------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
63
+ | `database` | `DatabaseAdapter` | **Required.** Data access. |
64
+ | `storage` | `StorageAdapter` | **Required.** Blob storage for screenshots, diffs, storybook archives. |
65
+ | `testing` | `{ runner, concurrency?, compare?, images? }` | Optional. Enables the async capture pipeline: `runner` (pure renderer; required, `testing: {}` throws; captures queue on the database), `concurrency` (jobs at once; default 2 on hosts with ≥ 2 CPUs and ≥ 3 GB, otherwise 1), `retries` (default 2). Absent means Storybook hosting only. `workerEntry` runs captures in a forked child the app pushes jobs to (`runCaptureChild`); `mode` is `auto` (default), `in-process` or `fork`. |
66
+ | `testing.compare` | `{ threads? }` | Optional. Worker threads for pixel diffs (default CPU count − 1; `0` = main thread). Also serves the re-diff endpoint. Overrides `STORYSHELF_DIFF_WORKERS`. |
67
+ | `notifications` | `{ notifiers?, emailSender?, config? }` | Optional. `notifiers` (Slack/Teams/email providers and the GitHub/GitLab git providers of `@storyshelf/notify-git`), `emailSender` (transport whose lifecycle hooks run with the app's), `config` (`fromEmail`, `fromName`, `footerText`, `slackUsername`). |
68
+ | `auth` | `Auth` (`@storyshelf/auth`) | Optional. Enables auth and the login UI. |
69
+ | `logger` | `Logger` (pino) | Optional. Shared logger. Construct a fallback via `createShelfLogger()`. |
70
+ | `ui` | `UIConfig` | Optional. UI branding. |
71
+ | `config` | `ShelfConfig` | Optional. Server behavior. |
59
72
 
60
73
  ### `ShelfConfig`
61
74
 
@@ -63,13 +76,14 @@ Assembles the router from the provided adapters. `ShelfOptions`:
63
76
  interface ShelfConfig {
64
77
  secret?: string; // session signing secret
65
78
  publishedBaseDomain?: string; // for published storybook URLs
66
- captureConcurrency?: number; // concurrent capture jobs (default 2)
67
- scratchDir?: string; // capture working directory (required with captureRunner)
79
+ scratchDir?: string; // working directory for publishing and capture (default: <os.tmpdir()>/storyshelf)
68
80
  purgeTtlDays?: number; // purge builds older than N days
69
81
  branchTtlDays?: number | null; // branch baseline TTL, days; null disables GC (default 30)
70
82
  branchGcIntervalMs?: number; // branch GC interval, ms; daily via interval clock (default 86_400_000)
71
83
  maxUploadBytes?: number; // single-zip upload cap (default 1 GiB)
72
- maxInlineUnzipSize?: number; // inline statics extraction cap; unset = capture-only
84
+ maxInlineUnzipSize?: number; // largest zip extracted inline at upload (default 50 MB; 0 = always a publish job)
85
+ maxZipEntries?: number; // most entries a zip may hold (default 50 000)
86
+ maxUnzippedBytes?: number; // most uncompressed bytes a zip may expand to (default 2 GiB)
73
87
  viewports?: Viewport[]; // capture viewports
74
88
  }
75
89
  ```
@@ -95,7 +109,8 @@ All adapters are constructor-injected (no AsyncLocalStorage). See `docs/architec
95
109
  - `Auth` (`@storyshelf/auth`) — the shelf authentication singleton: `check(request)`, `handler` (mount at `/api/auth/*`), `loginMethods()`, invites, sessions, passkeys. `AuthUser` and the shared `SESSION_COOKIE` live in `core/types`.
96
110
  - `CaptureRunner` (`core/adapter/capture-runner`) — a **pure capture renderer**: `render(input) => RenderResult`, `cancel(buildId)`. Also exports `RenderedSnapshot`, `RenderResult`, `StoryEntry`, `StorySourceAdapter`, `Viewport`.
97
111
  - `CaptureQueue` (`core/adapter/capture-queue`) — `enqueue({ buildId, reqId? })`, plus `status`, `active`, `recent`. Also exports `CaptureJob`, `QueueEntry`, `JobStatus`.
98
- - `GitHostProvider` / `GitHostAdapter` (`core/adapter/git-host`) — set commit status checks, detect merges, and upsert PR comments. Real providers ship in `@storyshelf/git-github` and `@storyshelf/git-gitlab`. Also exports `CheckStatus`.
112
+ - `DesignProvider` / `DesignClient` (`core/adapter/design`) — validate design links and fetch file metadata and rendered previews from a design tool. The Figma provider ships in `@storyshelf/design-figma`; also exports `parseDesignUrl` and `InvalidDesignUrlError`.
113
+ - `NotifierProvider` / `NotifierAdapter` (`core/adapter/notifier`) — one family with two delivery kinds: `message` providers (`@storyshelf/notify-chat`, `@storyshelf/notify-email`) `send` a formatted message; `state` providers (`@storyshelf/notify-git`: GitHub, GitLab) `setState` a commit status or pull-request comment, idempotently. Also exports `emitNotifications`, `statusesForBuild` (the pure build-to-statuses function), `writeBuildState`, `isStateProvider`, `NotifierState` and `NotifierStateTarget`; `core/capture` exports the `notify` job (`createBuildStatePublisher`, `createNotifyHandler`, `createNotifyEnqueuer`).
99
114
 
100
115
  ### Logging
101
116
 
@@ -105,11 +120,15 @@ All adapters are constructor-injected (no AsyncLocalStorage). See `docs/architec
105
120
 
106
121
  Import from `core/capture`, `core/diff`, and the model entries — never from the barrel:
107
122
 
108
- - `executeCaptureJob({ buildId, reqId }, deps)` (`core/capture`) — the capture **orchestrator**: loads the build, marks it `capturing`, extracts the uploaded archive into `scratchDir`, discovers stories, delegates rendering to a pure `CaptureRunner`, and persists. `createShelfApp` wires it into a `CaptureQueue` when `capture` is supplied (and requires `ShelfConfig.scratchDir`). Also exports `CaptureJobOptions`.
123
+ - `executeCaptureJob({ buildId, reqId }, deps)` (`core/capture`) — the capture **orchestrator**: loads the build, marks it `capturing`, extracts the uploaded archive into `scratchDir`, discovers stories, delegates rendering to a pure `CaptureRunner`, and persists. `createShelfApp` wires it into a `CaptureQueue` when `testing` is supplied (and requires `ShelfConfig.scratchDir`). Also exports `CaptureJobOptions`.
109
124
  - `persistCapture(ctx: CaptureContext)` (`core/capture`) — writes screenshots, diffs against the branch baseline, creates snapshots, and finalizes a build from a pure renderer's `captures`. Also exports `CaptureContext`.
110
125
  - `StorybookAdapter` (`core/capture`) — reads a built Storybook's `index.json`/`stories.json`.
111
- - `InMemoryCaptureQueue` (`core/capture`) — in-process, concurrency-limited queue for long-lived hosts; supply a remote queue with a separate worker for serverless.
112
- - `diffImages(baseline: Buffer, current: Buffer, options: DiffOptions): DiffResult` (`core/diff`) — pixelmatch-based diff. Also exports `DiffOptions`, `DiffResult`.
126
+ - `createCatalogLoader({ db, storage })`, `createCatalogHook(loader)`, `catalogueBuild`, `parseStorybookIndex`, `groupComponents`, `componentBuildHistory` (`core/capture`) — the Storybook catalog of a published build (ADR 0006, decision 9): `catalog.json` plus one `build_components` row per component, written by the `afterPublish` hook, loaded through an in-process LRU and catalogued lazily for older builds. `BuildComponentModel` (`core/models`) reads and replaces the rows.
127
+ - `BuildReviewModel`, `deriveReviewStatus`, `latestVerdicts` (`core/models`) — build-level review (ADR 0013, decision 3): `build_reviews` rows (a reviewer's newest row is their verdict) and the pure rule that turns them into `approved`, `rejected` or `pending` when `testing` is off and review is on. `publishVerdict` (`core/capture`) takes the project's review switch: a published non-default build is accepted when review is off.
128
+ - `computeChangeset`, `changesetOf`, `findChangesetBaseline`, `acceptPendingWithoutWork` (`core/models`) — the catalog changeset of a build (components added, removed and changed against its baseline build, ADR 0013 decision 8) and the pass that accepts a project's idle pending builds when review is turned off. `Retention.purge` (`core/retention`) also removes `pending` builds idle past the retention window.
129
+ - `createDatabaseCaptureQueue(db, options)` (`core/capture`) — a `PollableCaptureQueue` on the app's own database (`capture_jobs`; ADR 0006): per-attempt claim rows fence concurrent instances, leases follow progress, retries back off, `cancel(jobId | buildId)` reaches the holder within 5 s. Not wired into the app yet. `startPollLoop` and `keepJobLease` are the consumer-side helpers.
130
+ - `createCaptureConsumer({ queue, capture, handlers, config })` (`core/capture`) — the consumer loop over any `PollableCaptureQueue`: a handler per job kind (`capture` runs the core dispatch), a slot before each poll, retries with exponential backoff and the final-attempt rule, lease kept by progress, cancel and lease loss stop the run, `stop()` drains. `runCaptureChild` (forked capture) runs it over IPC.
131
+ - `diffImages(baseline: Buffer, current: Buffer, options: DiffOptions): Promise<DiffResult>` (`core/diff`) — pixelmatch-based diff (async since 0.7: the optional `sharp` codec is async). An optional fourth `codec` argument selects the PNG codec and defaults to `pngjs`. Re-exported from `@storyshelf/image`, which owns the image engines; also exports `diffImagesAsync` (worker pool), `configureImages({ engine, threads })`, `DiffOptions`, `DiffResult`. `configureDiffPool` remains as a deprecated alias.
113
132
  - Models, schema, and row types back every entity; retention runs inside the router (`Retention.purge` for builds + `Retention.purgeStaleBranches` for branch GC via `retention-timer.ts` daily sweep). (Models are private implementation details with no public entry — reach row types via `core/schema`.)
114
133
 
115
134
  ### Helpers
@@ -125,15 +144,13 @@ See `docs/architecture.md` and the ADRs in `docs/adr/`.
125
144
 
126
145
  ## Deployment targets
127
146
 
128
- The core router is runtime-agnostic (Web `Request`/`Response`, `fetch`, `crypto`, `URL`). The only Node-specific piece is the in-process `InMemoryCaptureQueue`, which suits long-lived Node servers; serverless runtimes swap in a remote `CaptureQueue` (e.g. `@storyshelf/queue-sqs`) plus a separate worker. You assemble a server for any platform — `storyshelf server init` generates a scaffold with the adapters you choose:
147
+ The core router is runtime-agnostic (Web `Request`/`Response`, `fetch`, `crypto`, `URL`). The Node-specific piece is the capture consumer and its optional forked child, which need a long-lived Node server: that is what the `testing` option turns on, and the database is the queue (ADR 0006). Without `testing` an instance only hosts Storybooks and runs on serverless platforms too. You assemble a server for any platform — `storyshelf server init` generates a scaffold with the adapters you choose:
129
148
 
130
- | Platform | Database | Storage | Capture queue | Server entry |
131
- | ------------------------------------------ | ------------------------------------- | -------------------------------- | ------------------------------- | -------------------------- |
132
- | **Vercel** | `@storyshelf/db-sqlite/turso` | `@storyshelf/storage-s3` (R2/S3) | Remote `CaptureQueue` + worker | Hono + `@hono/vercel-edge` |
133
- | **Cloudflare Workers** | `@storyshelf/db-sqlite/turso` | `@storyshelf/storage-s3` (R2) | Workers Queues `CaptureQueue` | Hono + Workers entry |
134
- | **Azure Functions** | `@storyshelf/db-sqlite/turso` | `@storyshelf/storage-s3` (Blob) | Azure Queues `CaptureQueue` | Hono + Azure handler |
135
- | **AWS Lambda** | `@storyshelf/db-sqlite/turso` | `@storyshelf/storage-s3` | SQS `CaptureQueue` | Hono + Lambda handler |
136
- | **Deno Deploy** | `@storyshelf/db-sqlite/turso` | `@storyshelf/storage-s3` | Custom `CaptureQueue` (Deno KV) | Hono + Deno entry |
137
- | **Bun / Node (VPS, Fly, Railway, Render)** | `db-sqlite` (+ `./bun-sqlite` on Bun) | `storage-local` / `storage-s3` | `InMemoryCaptureQueue` | `storyshelf-server serve` |
149
+ | Platform | Database | Storage | `testing` (capture) | Server entry |
150
+ | -------------------------------------------------------------------- | ------------------------------------- | ---------------------------------------------- | ------------------- | --------------------------------- |
151
+ | **Vercel, AWS Lambda, Azure Functions** | `@storyshelf/db-sqlite/turso` | `@storyshelf/storage-s3` | No (hosting only) | Hono + platform handler |
152
+ | **Cloudflare Workers** | `@storyshelf/db-sqlite/d1` or turso | `@storyshelf/storage-s3` (R2) | No (hosting only) | Hono + Workers entry |
153
+ | **Bun / Node (VPS, Fly, Railway, Render)** | `db-sqlite` (+ `./bun-sqlite` on Bun) | `storage-local` / `storage-s3` | Yes, database queue | `storyshelf-server serve` |
154
+ | **Container platforms (ECS, Cloud Run, Container Apps, Kubernetes)** | `db-postgres` / `db-mysql` | `storage-s3` / `storage-gcs` / `storage-azure` | Yes, database queue | `storyshelf server init` scaffold |
138
155
 
139
- All clouds are equal — pick the adapters that match your infrastructure. See the **Deployment** guide for recipes including a minimal Turso + S3 + `InMemoryCaptureQueue` example.
156
+ All clouds are equal — pick the adapters that match your infrastructure. See the **Deployment** guide for recipes including a minimal Turso + S3 example.
@@ -1,12 +1,13 @@
1
1
  import __tsdown_shims_path from 'node:path';
2
2
  import __tsdown_shims_url from 'node:url';
3
3
  import { Adapter } from "./metadata.mjs";
4
- //#region src/adapters/capture-queue.d.ts
5
4
  /** Lifecycle status of a queued capture job. */
6
5
  type JobStatus = "queued" | "running" | "completed" | "failed" | "cancelled";
7
6
  /** Observable state of a single capture queue entry. */
8
7
  interface QueueEntry {
9
8
  buildId: string;
9
+ /** Set on the entry of a shard job; the build's own entry has none. */
10
+ shard?: string;
10
11
  status: JobStatus;
11
12
  queuedAt: string;
12
13
  startedAt?: string;
@@ -23,6 +24,11 @@ interface CaptureJob {
23
24
  * instead of starting a root span; absent means start a new trace.
24
25
  */
25
26
  traceparent?: string;
27
+ /**
28
+ * `capture_shards` row to render. Absent on a build job, which plans the build (and, when it is
29
+ * big, hands out shard jobs) or captures it whole; every transport carries it through unchanged.
30
+ */
31
+ shard?: string;
26
32
  }
27
33
  /** A job polled from a queue with transport metadata. */
28
34
  interface PollableJob extends CaptureJob {
@@ -30,9 +36,21 @@ interface PollableJob extends CaptureJob {
30
36
  receipt?: string;
31
37
  /** Number of delivery attempts already made (0 = first delivery). */
32
38
  attempts?: number;
39
+ /**
40
+ * Lease (visibility timeout / ack deadline / lock) in ms granted at poll
41
+ * time. The worker renews at a fraction of this while a capture runs;
42
+ * absent means the transport has no renewable lease.
43
+ */
44
+ leaseMs?: number;
33
45
  /** Raw transport message for debugging. */
34
46
  raw?: unknown;
35
47
  }
48
+ /**
49
+ * Outcome of renewing (or inspecting) a polled job's lease: `lost` means another consumer owns it
50
+ * now or the job already ended; `cancelled` means someone asked for the job to stop, and the holder
51
+ * should cancel its run and settle the job (queues without cancel never report it).
52
+ */
53
+ type LeaseRenewal = "ok" | "lost" | "cancelled";
36
54
  /**
37
55
  * A capture job queue, decoupled from the runtime.
38
56
  *
@@ -59,6 +77,12 @@ interface CaptureQueue extends Adapter<{
59
77
  active(): Promise<QueueEntry[]>;
60
78
  /** The most recent queue entries, newest first. */
61
79
  recent(limit: number): Promise<QueueEntry[]>;
80
+ /**
81
+ * Cancel by job id, or every unfinished job of a build by build id (every job kind of the build on the database queue). Optional. A job that has not
82
+ * started ends `cancelled` at once; a running one is flagged, and its holder sees `"cancelled"`
83
+ * from `extend`/`inspect`. Resolves true when anything matched.
84
+ */
85
+ cancel?(id: string): Promise<boolean>;
62
86
  }
63
87
  /** Extension for queues that support worker-side polling. */
64
88
  interface PollableCaptureQueue extends CaptureQueue {
@@ -68,12 +92,28 @@ interface PollableCaptureQueue extends CaptureQueue {
68
92
  }): Promise<PollableJob | null>;
69
93
  /** Acknowledge successful processing of a polled job. */
70
94
  ack(job: PollableJob): Promise<void>;
71
- /** Negatively acknowledge; requeue with optional delay when possible. */
95
+ /**
96
+ * Negatively acknowledge; requeue with optional delay when possible. `requeue: false` is a final
97
+ * failure: the job is dropped, and `error` says why for queues that keep a record of it.
98
+ */
72
99
  nack(job: PollableJob, options?: {
73
100
  requeue?: boolean;
74
101
  delayMs?: number;
102
+ error?: string;
75
103
  }): Promise<void>;
104
+ /**
105
+ * Extend the lease on an in-flight job by another `job.leaseMs`. Optional:
106
+ * queues without a renewable lease (e.g. Redis) omit it. May update
107
+ * `job.receipt` in place when the transport rotates it. Resolves `"lost"`
108
+ * only when the transport conclusively reports the message is no longer
109
+ * owned by this consumer; transient failures must reject.
110
+ */
111
+ extend?(job: PollableJob): Promise<LeaseRenewal>;
112
+ /**
113
+ * Read the job's state without renewing its lease: the holder's periodic cancel check.
114
+ * Optional; same outcomes as `extend`.
115
+ */
116
+ inspect?(job: PollableJob): Promise<LeaseRenewal>;
76
117
  }
77
- //#endregion
78
- export { CaptureJob, CaptureQueue, JobStatus, PollableCaptureQueue, PollableJob, QueueEntry };
118
+ export { CaptureJob, CaptureQueue, JobStatus, LeaseRenewal, PollableCaptureQueue, PollableJob, QueueEntry };
79
119
  //# sourceMappingURL=capture-queue.d.mts.map
@@ -1,10 +1,36 @@
1
1
  import __tsdown_shims_path from 'node:path';
2
2
  import __tsdown_shims_url from 'node:url';
3
- import { StoryEntry, StorySourceAdapter, Viewport } from "../capture/adapter.mjs";
3
+ import { StoryEntry, StoryParameters, StorySourceAdapter, Viewport } from "../capture/adapter.mjs";
4
+ import { BROWSER_NAMES, BrowserName, CaptureTarget, DEFAULT_BROWSER, ParsedTarget, RunnerTarget, TARGET_NAME_PATTERN, TargetLaunchError, TargetReach, TargetStatus, engineOf, isBrowserName, isCaptureTarget, parseTarget, tryParseTarget, unavailableReason } from "../adapters/capture-target.mjs";
5
+ import { TargetOffers, createTargetOffers } from "../adapters/capture-target-offers.mjs";
6
+ import { RemoteBrowser, RemoteConnectContext, RemoteConnection, RemoteLeaseOutcome, RemoteLeasedConnection, RemoteOptions, RemoteProtocol, RemotePurpose, RemoteReleaseInfo, RemoteSupport, RemoteTarget, defineRemote, hasSchemeFor, isRemoteBrowser, remoteTargetsOf, scrubConnection } from "../adapters/remote-browser.mjs";
7
+ import { HeldConnection } from "../adapters/remote-lease-held.mjs";
8
+ import { RemoteConnectError, RemoteConnectErrorOptions } from "../adapters/remote-lease-error.mjs";
9
+ import { onRemoteShutdown, shutdownRemote } from "../adapters/remote-lease-shutdown.mjs";
10
+ import { ConnectLeasedContext, ConnectLeasedOptions, connectLeased } from "../adapters/remote-lease.mjs";
11
+ import { PoolLease, RefCounted, RefCountedOptions, refCounted } from "../adapters/remote-pool.mjs";
12
+ import { RenderRuns } from "../adapters/render-runs.mjs";
4
13
  import { Adapter } from "./metadata.mjs";
5
14
  import { JobStatus } from "./capture-queue.mjs";
6
15
  import { Logger } from "pino";
7
- //#region src/adapters/capture-runner.d.ts
16
+ /**
17
+ * The rendering environment a runner captured in. Two captures with the same environment (and
18
+ * engine and viewport) should produce identical pixels; a different one explains a visual diff
19
+ * that no code change caused. Every field is optional: runners report what they can.
20
+ */
21
+ interface CaptureEnvironment {
22
+ /** Browser build, as the driver reports it (for example `124.0.6367.29`). */
23
+ browserVersion?: string;
24
+ /**
25
+ * OS and CPU text rendering depends on: the host's `process.platform-arch` for a local browser;
26
+ * for a remote one what the browser reported (`linux`, `windows`), never the host's.
27
+ */
28
+ platform?: string;
29
+ /** Device pixel ratio the pages were rendered at. */
30
+ deviceScaleFactor?: number;
31
+ /** Digest of the installed system fonts, when they could be listed. */
32
+ fontsHash?: string;
33
+ }
8
34
  /** A screenshot produced by a capture renderer. */
9
35
  interface RenderedSnapshot {
10
36
  /** The rendered story (echoed back from the render request). */
@@ -15,6 +41,25 @@ interface RenderedSnapshot {
15
41
  viewport?: Viewport;
16
42
  /** PNG screenshot bytes. */
17
43
  screenshot: Buffer;
44
+ /** Target that produced the screenshot (the request's `target`); chromium when absent. */
45
+ browser?: CaptureTarget;
46
+ /**
47
+ * Wall-clock milliseconds the renderer spent on this capture, when it measured it. Recorded per
48
+ * snapshot and read back as the per-story cost a shard plan orders its work by (ADR 0005).
49
+ */
50
+ durationMs?: number;
51
+ /** Axe violation texts found on this capture (empty or absent: none, or not checked). */
52
+ a11y?: string[];
53
+ /**
54
+ * Set by the orchestrator when it already wrote the screenshot to storage
55
+ * (via `onCapture`); `screenshot` is then empty and must not be written again.
56
+ * Runners never set this.
57
+ */
58
+ stored?: boolean;
59
+ /** Where the orchestrator stored it (content-addressed); set together with `stored`. */
60
+ storedPath?: string;
61
+ /** Environment of the render pass that produced it; filled in by the orchestrator from {@link RenderResult.environment}. */
62
+ environment?: CaptureEnvironment;
18
63
  }
19
64
  /** A story/viewport that a renderer could not capture. */
20
65
  interface RenderFailure {
@@ -24,6 +69,8 @@ interface RenderFailure {
24
69
  viewportName: string;
25
70
  /** Error message. */
26
71
  error: string;
72
+ /** Target the failure happened on; chromium when absent. */
73
+ browser?: CaptureTarget;
27
74
  }
28
75
  /** The outcome of a render request. */
29
76
  interface RenderResult {
@@ -31,6 +78,17 @@ interface RenderResult {
31
78
  captures: RenderedSnapshot[];
32
79
  /** Story/viewport pairs the renderer could not capture. */
33
80
  failures: RenderFailure[];
81
+ /** What this render ran on; optional so third-party runners keep working. */
82
+ environment?: CaptureEnvironment;
83
+ }
84
+ /** What a runner reports for one Storybook `.test()` entry it ran in the iframe. */
85
+ interface TestOutcome {
86
+ /** The test entry's id (`<story id>:<test name slug>`). */
87
+ storyId: string;
88
+ status: "passed" | "failed";
89
+ /** Why it failed: the assertion, render error or timeout message. */
90
+ error?: string;
91
+ durationMs: number;
34
92
  }
35
93
  /**
36
94
  * A pure capture renderer.
@@ -43,12 +101,13 @@ interface RenderResult {
43
101
  * orchestrator's job (see `capture/orchestrator.ts`), keeping every adapter
44
102
  * implementation free of server concerns.
45
103
  */
46
- type BrowserName = "chromium" | "firefox" | "webkit" | "chrome";
47
- /** Browser names accepted for capture rendering (Chromium default). */
48
- declare const BROWSER_NAMES: readonly ["chromium", "firefox", "webkit", "chrome"];
49
104
  interface CaptureRunner extends Adapter<{
50
105
  readonly category: "capture-runner";
51
- readonly supportedBrowsers?: readonly BrowserName[];
106
+ /**
107
+ * Every target the runner offers, default first (ADR 0007, decision 1), with whether each can
108
+ * render now. A runner that omits it offers any target.
109
+ */
110
+ readonly targets?: readonly RunnerTarget[];
52
111
  }> {
53
112
  /**
54
113
  * Render configured viewports for the given stories of an extracted
@@ -59,6 +118,13 @@ interface CaptureRunner extends Adapter<{
59
118
  render(input: {
60
119
  /** Build being captured, used to correlate cancels with in-flight work. */
61
120
  buildId: string;
121
+ /**
122
+ * This call's handle within the build, for `cancel(buildId, runId)`: several renders of one
123
+ * build (its shards) can be in flight in one process. Absent, the build id is used.
124
+ */
125
+ runId?: string | undefined;
126
+ /** The shard's 1-based position in the build's plan, for a remote service that routes per shard. */
127
+ shardIndex?: number | undefined;
62
128
  /** Root of the already-extracted Storybook build. */
63
129
  storybookDir: string;
64
130
  /** Stories to render. */
@@ -73,8 +139,22 @@ interface CaptureRunner extends Adapter<{
73
139
  playTimeoutMs?: number;
74
140
  /** Whether to run a11y checks (axe) before screenshot; annotated as non-blocking. */
75
141
  runA11y?: boolean;
76
- /** Browser to use for rendering (chromium default). */
77
- browser?: BrowserName;
142
+ /** Target to render on (chromium when absent). */
143
+ target?: CaptureTarget;
144
+ /**
145
+ * An absolute URL to the build's Storybook that the target's browser can reach, set for a
146
+ * `reach: "url"` target (ADR 0007, decision 5). The runner navigates there instead of to its
147
+ * loopback server; a `reach: "url"` target given none fails to start. Never logged.
148
+ */
149
+ storybookUrl?: string;
150
+ /**
151
+ * Optional streaming hand-off. When provided, the runner awaits it with each
152
+ * capture as soon as it is taken, then drops the buffer instead of adding the
153
+ * capture to `RenderResult.captures`, so a large build never holds every
154
+ * screenshot in memory. A rejection is reported as a render failure for that
155
+ * story/viewport. Runners that do not support it return captures as usual.
156
+ */
157
+ onCapture?: (capture: RenderedSnapshot) => Promise<void>;
78
158
  /**
79
159
  * Test/extension seam: override the story source adapter (defaults to
80
160
  * `StorybookAdapter`). Only the renderer uses it; discovery stays the
@@ -82,9 +162,51 @@ interface CaptureRunner extends Adapter<{
82
162
  */
83
163
  adapter?: StorySourceAdapter;
84
164
  }): Promise<RenderResult>;
85
- /** Cancel a pending or in-flight render for a build. */
86
- cancel(buildId: string): Promise<void>;
165
+ /**
166
+ * Optional pre-pass reading each story's fully resolved parameters (project,
167
+ * component and story levels stacked) from the running preview. Storybook's
168
+ * index rarely carries parameters, so this is how the orchestrator learns
169
+ * which modes a story declares before it builds the capture matrix.
170
+ * Absent or failing, the orchestrator falls back to index parameters.
171
+ */
172
+ extractParameters?(input: {
173
+ buildId: string;
174
+ storybookDir: string;
175
+ stories: StoryEntry[];
176
+ logger?: Logger;
177
+ /** Target to read the parameters on: the project's primary (chromium when absent). */
178
+ target?: CaptureTarget;
179
+ /** As on `render`: the URL a `reach: "url"` target's browser opens. */
180
+ storybookUrl?: string;
181
+ adapter?: StorySourceAdapter;
182
+ }): Promise<Record<string, StoryParameters>>;
183
+ /**
184
+ * Optional: run Storybook 10 `.test()` entries (index `subtype: "test"`) as interaction tests.
185
+ * Each entry's iframe URL renders the story it is written under and runs the test body as the
186
+ * play function; the runner reports pass or fail per entry from Storybook's own events, and
187
+ * takes no screenshot. A runner without it leaves projects that turn tests on with a warning.
188
+ * Cancellable with `cancel`, like `render`.
189
+ */
190
+ runTests?(input: {
191
+ buildId: string;
192
+ runId?: string | undefined;
193
+ storybookDir: string;
194
+ /** The test entries to run (`StoryEntry.parentId` is set). */
195
+ tests: StoryEntry[];
196
+ logger?: Logger;
197
+ /** Timeout for one test (render plus body) in ms. */
198
+ playTimeoutMs?: number;
199
+ /** Target to run on: the project's primary (chromium when absent). */
200
+ target?: CaptureTarget;
201
+ /** As on `render`: the URL a `reach: "url"` target's browser opens. */
202
+ storybookUrl?: string;
203
+ adapter?: StorySourceAdapter;
204
+ }): Promise<TestOutcome[]>;
205
+ /**
206
+ * Cancel in-flight renders of a build: the ones started with `runId`, or every one of the build
207
+ * when it is absent. Runners can track their calls with {@link RenderRuns}.
208
+ */
209
+ cancel(buildId: string, runId?: string): Promise<void>;
87
210
  }
88
- //#endregion
89
- export { BROWSER_NAMES, BrowserName, CaptureRunner, type JobStatus, RenderFailure, RenderResult, RenderedSnapshot, type StoryEntry, type StorySourceAdapter, type Viewport };
211
+ export { BROWSER_NAMES, type BrowserName, CaptureEnvironment, CaptureRunner, type CaptureTarget, type ConnectLeasedContext, type ConnectLeasedOptions, DEFAULT_BROWSER, type HeldConnection, type JobStatus, type ParsedTarget, type PoolLease, type RefCounted, type RefCountedOptions, type RemoteBrowser, type RemoteConnectContext, RemoteConnectError, type RemoteConnectErrorOptions, type RemoteConnection, type RemoteLeaseOutcome, type RemoteLeasedConnection, type RemoteOptions, type RemoteProtocol, type RemotePurpose, type RemoteReleaseInfo, type RemoteSupport, type RemoteTarget, RenderFailure, RenderResult, RenderRuns, RenderedSnapshot, type RunnerTarget, type StoryEntry, type StorySourceAdapter, TARGET_NAME_PATTERN, TargetLaunchError, type TargetOffers, type TargetReach, type TargetStatus, TestOutcome, type Viewport, connectLeased, createTargetOffers, defineRemote, engineOf, hasSchemeFor, isBrowserName, isCaptureTarget, isRemoteBrowser, onRemoteShutdown, parseTarget, refCounted, remoteTargetsOf, scrubConnection, shutdownRemote, tryParseTarget, unavailableReason };
90
212
  //# sourceMappingURL=capture-runner.d.mts.map
@@ -1,15 +1,12 @@
1
1
  import "node:path";
2
2
  import "node:url";
3
3
  import.meta.url;
4
- //#region src/adapters/capture-runner.ts
5
- /** Browser names accepted for capture rendering (Chromium default). */
6
- const BROWSER_NAMES = [
7
- "chromium",
8
- "firefox",
9
- "webkit",
10
- "chrome"
11
- ];
12
- //#endregion
13
- export { BROWSER_NAMES };
14
-
15
- //# sourceMappingURL=capture-runner.mjs.map
4
+ import { BROWSER_NAMES, DEFAULT_BROWSER, TARGET_NAME_PATTERN, TargetLaunchError, engineOf, isBrowserName, isCaptureTarget, parseTarget, tryParseTarget, unavailableReason } from "../adapters/capture-target.mjs";
5
+ import { createTargetOffers } from "../adapters/capture-target-offers.mjs";
6
+ import { defineRemote, hasSchemeFor, isRemoteBrowser, remoteTargetsOf, scrubConnection } from "../adapters/remote-browser.mjs";
7
+ import { RemoteConnectError } from "../adapters/remote-lease-error.mjs";
8
+ import { onRemoteShutdown, shutdownRemote } from "../adapters/remote-lease-shutdown.mjs";
9
+ import { connectLeased } from "../adapters/remote-lease.mjs";
10
+ import { refCounted } from "../adapters/remote-pool.mjs";
11
+ import { RenderRuns } from "../adapters/render-runs.mjs";
12
+ export { BROWSER_NAMES, DEFAULT_BROWSER, RemoteConnectError, RenderRuns, TARGET_NAME_PATTERN, TargetLaunchError, connectLeased, createTargetOffers, defineRemote, engineOf, hasSchemeFor, isBrowserName, isCaptureTarget, isRemoteBrowser, onRemoteShutdown, parseTarget, refCounted, remoteTargetsOf, scrubConnection, shutdownRemote, tryParseTarget, unavailableReason };
@@ -2,21 +2,35 @@ import __tsdown_shims_path from 'node:path';
2
2
  import __tsdown_shims_url from 'node:url';
3
3
  import { Adapter, AdapterMetadata } from "./metadata.mjs";
4
4
  import { SQL, Table } from "drizzle-orm";
5
- //#region src/adapters/database.d.ts
5
+ /** A fenced reference write lost its generation race and should be retried. */
6
+ declare class ReferenceGenerationConflict extends Error {}
6
7
  /** Type-safe table map enforced on every DatabaseAdapter. */
7
8
  interface Tables {
8
9
  projects: Table;
9
- projectStatusConfigs: Table;
10
10
  builds: Table;
11
11
  captureAttempts: Table;
12
12
  captureLogs: Table;
13
+ captureShards: Table;
14
+ captureJobs: Table;
15
+ buildComponents: Table;
16
+ buildReviews: Table;
17
+ siteSettings: Table;
13
18
  snapshots: Table;
14
19
  baselines: Table;
15
20
  comments: Table;
16
21
  labelTypes: Table;
17
22
  buildLabels: Table;
23
+ projectLinks: Table;
24
+ designLinks: Table;
25
+ designCredentials: Table;
26
+ userConnections: Table;
27
+ designNodes: Table;
28
+ buildPackageUsage: Table;
18
29
  tokens: Table;
19
30
  webhooks: Table;
31
+ insights: Table;
32
+ aiUsage: Table;
33
+ aiBudgetAlerts: Table;
20
34
  notificationChannels: Table;
21
35
  notificationSubscriptions: Table;
22
36
  users: Table;
@@ -61,16 +75,84 @@ interface TxStore {
61
75
  /** Count rows matching an optional where condition. */
62
76
  count(table: Table, where?: SQL): Promise<number>;
63
77
  }
64
- /** Database abstraction over Drizzle tables, agnostic of dialect and driver. */
65
- interface DatabaseAdapter extends Adapter<{
78
+ /** An owner of durable protection for a build. Historical comparisons are not build owners. */
79
+ interface BuildReferenceOwner {
80
+ type: "baseline" | "investigation";
81
+ id: string;
82
+ projectId: string;
83
+ }
84
+ /** One owner's complete new reference set for an atomic multi-owner mutation. */
85
+ interface BuildReferenceChange {
86
+ owner: BuildReferenceOwner;
87
+ buildIds: readonly string[];
88
+ }
89
+ /** A complete owner reference replacement guarded by its last observed generation. */
90
+ interface FencedBuildReferenceChange extends BuildReferenceChange {
91
+ expectedGeneration: number;
92
+ }
93
+ /**
94
+ * An explicit database capability; an ordinary transaction does not establish this contract.
95
+ * Implementations serialize admissions, reference changes, and deletion claims across processes.
96
+ * Their tests must use independent connections, including promotion/purge and pin/purge races.
97
+ */
98
+ interface BuildReferenceLifecycle {
99
+ /** Return the durable generation for an owner, or zero before its first reference mutation.
100
+ * This is a snapshot: callers must pass it to a fenced mutation, which rechecks atomically. */
101
+ referenceGeneration(owner: BuildReferenceOwner): Promise<number>;
102
+ /** Atomically fence and replace multiple owners, or roll back all owners and domain writes. */
103
+ replaceManyFencedReferences<T>(changes: readonly FencedBuildReferenceChange[], writeDomain: (tx: TxStore) => Promise<T>): Promise<{
104
+ result: T;
105
+ generations: number[];
106
+ }>;
107
+ /** Compare and advance an owner's durable generation with its reference and domain writes.
108
+ * Generation zero denotes an owner with no earlier mutations. A stale generation rejects the
109
+ * whole transaction. Generations survive release so an old worker cannot release a newer pin. */
110
+ replaceFencedReferences<T>(owner: BuildReferenceOwner, expectedGeneration: number, buildIds: readonly string[], writeDomain: (tx: TxStore) => Promise<T>): Promise<{
111
+ result: T;
112
+ generation: number;
113
+ }>;
114
+ /**
115
+ * Atomically replace one owner's complete reference set and make its domain writes. Both old and
116
+ * new builds must be locked in stable order, checked for project ownership and availability,
117
+ * and committed with the domain mutation. Unknown or tombstoned builds reject admission.
118
+ */
119
+ replaceReferences<T>(owner: BuildReferenceOwner, buildIds: readonly string[], writeDomain: (tx: TxStore) => Promise<T>): Promise<T>;
120
+ /** Atomically replace several owners' reference sets and the shared domain writes. */
121
+ replaceManyReferences<T>(changes: readonly BuildReferenceChange[], writeDomain: (tx: TxStore) => Promise<T>): Promise<T>;
122
+ /**
123
+ * In the same concurrency domain as admissions, irreversibly tombstone a build only if no
124
+ * protecting reference remains. Existing tombstones are resumable and never become available.
125
+ * Storage deletion must happen after this operation commits, outside database locks.
126
+ */
127
+ claimDeletion(projectId: string, buildId: string): Promise<"claimed" | "protected" | "deleting" | "missing">;
128
+ }
129
+ /** Database-specific metadata: the family plus what the backing platform can carry. */
130
+ interface DatabaseAdapterMetadata {
66
131
  readonly category: "database";
67
- }> {
132
+ /**
133
+ * `false` when the database cannot back a deployment with `testing` (ADR 0006, decision 3): it
134
+ * is reachable only from a platform that ends the process after each request (Cloudflare D1).
135
+ * Unset means it can.
136
+ */
137
+ readonly supportsTesting?: boolean;
138
+ }
139
+ /** Database abstraction over Drizzle tables, agnostic of dialect and driver. */
140
+ interface DatabaseAdapter extends Adapter<DatabaseAdapterMetadata> {
141
+ /**
142
+ * Present only when the adapter implements the cross-process retention safety contract.
143
+ * `transact` by itself is not evidence of this capability.
144
+ */
145
+ readonly buildReferenceLifecycle?: BuildReferenceLifecycle;
68
146
  /** Table handles for this adapter's dialect, enforced with type safety. */
69
147
  readonly tables: Tables;
70
148
  /** Insert a row and return the inserted record. */
71
149
  insert<T extends Table>(table: T, values: T["$inferInsert"]): Promise<T["$inferSelect"]>;
72
150
  /** Update a row by id and return the updated record. */
73
151
  update<T extends Table>(table: T, id: string, values: Partial<T["$inferInsert"]>): Promise<T["$inferSelect"]>;
152
+ /** Atomically update a row only while `where` matches; return the current row, or null if absent.
153
+ * Custom adapters must implement the condition in the same database statement as the update.
154
+ */
155
+ updateWhere<T extends Table>(table: T, id: string, values: Partial<T["$inferInsert"]>, where: SQL): Promise<T["$inferSelect"] | null>;
74
156
  /** Fetch a single row by id, or null if not found. */
75
157
  get<T extends Table>(table: T, id: string): Promise<T["$inferSelect"] | null>;
76
158
  /** Delete a row by id. */
@@ -90,15 +172,12 @@ interface DatabaseAdapter extends Adapter<{
90
172
  }
91
173
  /** Driver-supplied identity plus lifecycle hooks. */
92
174
  interface DrizzleAdapterOptions {
93
- metadata: AdapterMetadata & {
94
- readonly category: "database";
95
- };
175
+ metadata: AdapterMetadata & DatabaseAdapterMetadata;
96
176
  tables: Tables;
97
177
  migrate: () => Promise<void> | void;
98
178
  close: () => Promise<void> | void;
99
179
  /** Cheap liveness probe (e.g. `SELECT 1`); omitted when the driver has none. */
100
180
  ping?: () => Promise<void> | void;
101
181
  }
102
- //#endregion
103
- export { DatabaseAdapter, DrizzleAdapterOptions, ListOptions, MAX_LIST_LIMIT, REQUIRED_TABLE_KEYS, Tables, TxStore, clampListLimit };
182
+ export { BuildReferenceChange, BuildReferenceLifecycle, BuildReferenceOwner, DatabaseAdapter, DatabaseAdapterMetadata, DrizzleAdapterOptions, FencedBuildReferenceChange, ListOptions, MAX_LIST_LIMIT, REQUIRED_TABLE_KEYS, ReferenceGenerationConflict, Tables, TxStore, clampListLimit };
104
183
  //# sourceMappingURL=database.d.mts.map