@storyshelf/core 0.6.2 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +49 -32
- package/dist/adapter/capture-queue.d.mts +44 -2
- package/dist/adapter/capture-runner.d.mts +127 -10
- package/dist/adapter/capture-runner.mjs +5 -12
- package/dist/adapter/database.d.mts +27 -8
- package/dist/adapter/database.mjs.map +1 -1
- package/dist/adapter/design.d.mts +85 -0
- package/dist/adapter/design.mjs +28 -0
- package/dist/adapter/design.mjs.map +1 -0
- package/dist/adapter/metadata.d.mts +3 -10
- package/dist/adapter/notifier.d.mts +6 -3
- package/dist/adapter/notifier.mjs +5 -1
- package/dist/adapter/oauth.d.mts +52 -0
- package/dist/adapter/setup.d.mts +4 -5
- package/dist/adapter/setup.mjs +2 -1
- package/dist/adapter/setup.mjs.map +1 -1
- package/dist/adapter/webhook-events.mjs +1 -1
- package/dist/adapters/capture-target-offers.d.mts +28 -0
- package/dist/adapters/capture-target-offers.mjs +58 -0
- package/dist/adapters/capture-target-offers.mjs.map +1 -0
- package/dist/adapters/capture-target.d.mts +71 -0
- package/dist/adapters/capture-target.mjs +76 -0
- package/dist/adapters/capture-target.mjs.map +1 -0
- package/dist/adapters/notifier/build-comment.d.mts +24 -0
- package/dist/adapters/notifier/build-comment.mjs +24 -0
- package/dist/adapters/notifier/build-comment.mjs.map +1 -0
- package/dist/adapters/notifier/build-state.d.mts +99 -0
- package/dist/adapters/notifier/build-state.mjs +218 -0
- package/dist/adapters/notifier/build-state.mjs.map +1 -0
- package/dist/adapters/notifier/events.d.mts +4 -2
- package/dist/adapters/notifier/events.mjs +31 -18
- package/dist/adapters/notifier/events.mjs.map +1 -1
- package/dist/adapters/notifier/provider.d.mts +53 -7
- package/dist/adapters/notifier/provider.mjs +12 -0
- package/dist/adapters/notifier/provider.mjs.map +1 -0
- package/dist/adapters/notifier/state.d.mts +24 -0
- package/dist/adapters/notifier/state.mjs +66 -0
- package/dist/adapters/notifier/state.mjs.map +1 -0
- package/dist/adapters/notifier/types.d.mts +51 -2
- package/dist/adapters/remote-browser.d.mts +87 -0
- package/dist/adapters/remote-browser.mjs +103 -0
- package/dist/adapters/remote-browser.mjs.map +1 -0
- package/dist/adapters/render-runs.d.mts +25 -0
- package/dist/adapters/render-runs.mjs +41 -0
- package/dist/adapters/render-runs.mjs.map +1 -0
- package/dist/adapters/setup-runner.mjs +2 -4
- package/dist/adapters/setup-runner.mjs.map +1 -1
- package/dist/adapters/sources.d.mts +12 -0
- package/dist/adapters/sources.mjs +20 -0
- package/dist/adapters/sources.mjs.map +1 -0
- package/dist/adapters/validate.mjs +25 -18
- package/dist/adapters/validate.mjs.map +1 -1
- package/dist/ai.d.mts +105 -0
- package/dist/ai.mjs +19 -0
- package/dist/ai.mjs.map +1 -0
- package/dist/capture/a11y/axe-source.d.mts +18 -0
- package/dist/capture/a11y/axe-source.mjs +37 -0
- package/dist/capture/a11y/axe-source.mjs.map +1 -0
- package/dist/capture/a11y/in-page.d.mts +27 -0
- package/dist/capture/a11y/in-page.mjs +60 -0
- package/dist/capture/a11y/in-page.mjs.map +1 -0
- package/dist/capture/a11y/map.d.mts +24 -0
- package/dist/capture/a11y/map.mjs +48 -0
- package/dist/capture/a11y/map.mjs.map +1 -0
- package/dist/capture/a11y/options.d.mts +23 -0
- package/dist/capture/a11y/options.mjs +75 -0
- package/dist/capture/a11y/options.mjs.map +1 -0
- package/dist/capture/adapter.d.mts +41 -3
- package/dist/capture/adapter.mjs.map +1 -1
- package/dist/capture/affected.d.mts +2 -0
- package/dist/capture/affected.mjs +13 -4
- package/dist/capture/affected.mjs.map +1 -1
- package/dist/capture/attempt-logger.mjs +84 -0
- package/dist/capture/attempt-logger.mjs.map +1 -0
- package/dist/capture/browsers.d.mts +35 -0
- package/dist/capture/browsers.mjs +67 -0
- package/dist/capture/browsers.mjs.map +1 -0
- package/dist/capture/build-state/deliver.d.mts +32 -0
- package/dist/capture/build-state/deliver.mjs +118 -0
- package/dist/capture/build-state/deliver.mjs.map +1 -0
- package/dist/capture/build-state/index.d.mts +8 -0
- package/dist/capture/build-state/notify-job.d.mts +56 -0
- package/dist/capture/build-state/notify-job.mjs +133 -0
- package/dist/capture/build-state/notify-job.mjs.map +1 -0
- package/dist/capture/build-state/publisher.d.mts +23 -0
- package/dist/capture/build-state/publisher.mjs +107 -0
- package/dist/capture/build-state/publisher.mjs.map +1 -0
- package/dist/capture/build-state/resume.d.mts +9 -0
- package/dist/capture/build-state/resume.mjs +47 -0
- package/dist/capture/build-state/resume.mjs.map +1 -0
- package/dist/capture/build-state/types.d.mts +49 -0
- package/dist/capture/catalog/catalogue.d.mts +22 -0
- package/dist/capture/catalog/catalogue.mjs +53 -0
- package/dist/capture/catalog/catalogue.mjs.map +1 -0
- package/dist/capture/catalog/components.d.mts +23 -0
- package/dist/capture/catalog/components.mjs +55 -0
- package/dist/capture/catalog/components.mjs.map +1 -0
- package/dist/capture/catalog/history.d.mts +30 -0
- package/dist/capture/catalog/history.mjs +51 -0
- package/dist/capture/catalog/history.mjs.map +1 -0
- package/dist/capture/catalog/hook.d.mts +14 -0
- package/dist/capture/catalog/hook.mjs +19 -0
- package/dist/capture/catalog/hook.mjs.map +1 -0
- package/dist/capture/catalog/index.d.mts +11 -0
- package/dist/capture/catalog/load.d.mts +26 -0
- package/dist/capture/catalog/load.mjs +49 -0
- package/dist/capture/catalog/load.mjs.map +1 -0
- package/dist/capture/catalog/parse.d.mts +15 -0
- package/dist/capture/catalog/parse.mjs +56 -0
- package/dist/capture/catalog/parse.mjs.map +1 -0
- package/dist/capture/catalog/read.d.mts +12 -0
- package/dist/capture/catalog/read.mjs +33 -0
- package/dist/capture/catalog/read.mjs.map +1 -0
- package/dist/capture/catalog/types.d.mts +33 -0
- package/dist/capture/consumer/capture-handler.d.mts +58 -0
- package/dist/capture/consumer/capture-handler.mjs +118 -0
- package/dist/capture/consumer/capture-handler.mjs.map +1 -0
- package/dist/capture/consumer/idle.d.mts +17 -0
- package/dist/capture/consumer/idle.mjs +25 -0
- package/dist/capture/consumer/idle.mjs.map +1 -0
- package/dist/capture/consumer/index.d.mts +13 -0
- package/dist/capture/consumer/index.mjs +139 -0
- package/dist/capture/consumer/index.mjs.map +1 -0
- package/dist/capture/consumer/loop.mjs +110 -0
- package/dist/capture/consumer/loop.mjs.map +1 -0
- package/dist/capture/consumer/metrics.d.mts +41 -0
- package/dist/capture/consumer/metrics.mjs +38 -0
- package/dist/capture/consumer/metrics.mjs.map +1 -0
- package/dist/capture/consumer/retry.d.mts +33 -0
- package/dist/capture/consumer/retry.mjs +34 -0
- package/dist/capture/consumer/retry.mjs.map +1 -0
- package/dist/capture/consumer/run-job.mjs +195 -0
- package/dist/capture/consumer/run-job.mjs.map +1 -0
- package/dist/capture/consumer/startup.mjs +38 -0
- package/dist/capture/consumer/startup.mjs.map +1 -0
- package/dist/capture/consumer/types.d.mts +97 -0
- package/dist/capture/crash-failure.d.mts +25 -0
- package/dist/capture/crash-failure.mjs +70 -0
- package/dist/capture/crash-failure.mjs.map +1 -0
- package/dist/capture/db-queue/cadence.d.mts +32 -0
- package/dist/capture/db-queue/cadence.mjs +38 -0
- package/dist/capture/db-queue/cadence.mjs.map +1 -0
- package/dist/capture/db-queue/claim.d.mts +9 -0
- package/dist/capture/db-queue/claim.mjs +132 -0
- package/dist/capture/db-queue/claim.mjs.map +1 -0
- package/dist/capture/db-queue/clock.mjs +12 -0
- package/dist/capture/db-queue/clock.mjs.map +1 -0
- package/dist/capture/db-queue/codec.mjs +76 -0
- package/dist/capture/db-queue/codec.mjs.map +1 -0
- package/dist/capture/db-queue/index.d.mts +20 -0
- package/dist/capture/db-queue/index.mjs +89 -0
- package/dist/capture/db-queue/index.mjs.map +1 -0
- package/dist/capture/db-queue/keeper.d.mts +36 -0
- package/dist/capture/db-queue/keeper.mjs +92 -0
- package/dist/capture/db-queue/keeper.mjs.map +1 -0
- package/dist/capture/db-queue/lease.mjs +46 -0
- package/dist/capture/db-queue/lease.mjs.map +1 -0
- package/dist/capture/db-queue/lifecycle.mjs +36 -0
- package/dist/capture/db-queue/lifecycle.mjs.map +1 -0
- package/dist/capture/db-queue/operations.mjs +94 -0
- package/dist/capture/db-queue/operations.mjs.map +1 -0
- package/dist/capture/db-queue/poll-loop.d.mts +30 -0
- package/dist/capture/db-queue/poll-loop.mjs +89 -0
- package/dist/capture/db-queue/poll-loop.mjs.map +1 -0
- package/dist/capture/db-queue/poll.d.mts +10 -0
- package/dist/capture/db-queue/poll.mjs +69 -0
- package/dist/capture/db-queue/poll.mjs.map +1 -0
- package/dist/capture/db-queue/timers.d.mts +12 -0
- package/dist/capture/db-queue/timers.mjs +37 -0
- package/dist/capture/db-queue/timers.mjs.map +1 -0
- package/dist/capture/db-queue/types.d.mts +83 -0
- package/dist/capture/db-queue/types.mjs +12 -0
- package/dist/capture/db-queue/types.mjs.map +1 -0
- package/dist/capture/db-queue/wake.mjs +48 -0
- package/dist/capture/db-queue/wake.mjs.map +1 -0
- package/dist/capture/design.mjs +39 -0
- package/dist/capture/design.mjs.map +1 -0
- package/dist/capture/diff-record.mjs +23 -3
- package/dist/capture/diff-record.mjs.map +1 -1
- package/dist/capture/dispatch.d.mts +12 -7
- package/dist/capture/dispatch.mjs +86 -107
- package/dist/capture/dispatch.mjs.map +1 -1
- package/dist/capture/enrich.mjs +60 -0
- package/dist/capture/enrich.mjs.map +1 -0
- package/dist/capture/failure-sets.mjs +22 -0
- package/dist/capture/failure-sets.mjs.map +1 -0
- package/dist/capture/fingerprint.d.mts +42 -0
- package/dist/capture/fingerprint.mjs +83 -0
- package/dist/capture/fingerprint.mjs.map +1 -0
- package/dist/capture/forked/channel.d.mts +25 -0
- package/dist/capture/forked/child.d.mts +34 -0
- package/dist/capture/forked/child.mjs +202 -0
- package/dist/capture/forked/child.mjs.map +1 -0
- package/dist/capture/forked/crash-tracker.mjs +23 -0
- package/dist/capture/forked/crash-tracker.mjs.map +1 -0
- package/dist/capture/forked/decision.d.mts +26 -0
- package/dist/capture/forked/decision.mjs +27 -0
- package/dist/capture/forked/decision.mjs.map +1 -0
- package/dist/capture/forked/exit.mjs +12 -0
- package/dist/capture/forked/exit.mjs.map +1 -0
- package/dist/capture/forked/fork.d.mts +31 -0
- package/dist/capture/forked/fork.mjs +93 -0
- package/dist/capture/forked/fork.mjs.map +1 -0
- package/dist/capture/forked/forked-capture.d.mts +40 -0
- package/dist/capture/forked/forked-capture.mjs +240 -0
- package/dist/capture/forked/forked-capture.mjs.map +1 -0
- package/dist/capture/forked/lease-book.mjs +46 -0
- package/dist/capture/forked/lease-book.mjs.map +1 -0
- package/dist/capture/forked/protocol.d.mts +38 -0
- package/dist/capture/forked/protocol.mjs +25 -0
- package/dist/capture/forked/protocol.mjs.map +1 -0
- package/dist/capture/forked/runs.mjs +75 -0
- package/dist/capture/forked/runs.mjs.map +1 -0
- package/dist/capture/isolate.mjs +141 -0
- package/dist/capture/isolate.mjs.map +1 -0
- package/dist/capture/job-lease.d.mts +28 -0
- package/dist/capture/job-lease.mjs +57 -0
- package/dist/capture/job-lease.mjs.map +1 -0
- package/dist/capture/matrix.mjs +298 -0
- package/dist/capture/matrix.mjs.map +1 -0
- package/dist/capture/modes.d.mts +25 -0
- package/dist/capture/modes.mjs +107 -0
- package/dist/capture/modes.mjs.map +1 -0
- package/dist/capture/orchestrator.d.mts +37 -5
- package/dist/capture/orchestrator.mjs +118 -107
- package/dist/capture/orchestrator.mjs.map +1 -1
- package/dist/capture/pipeline.d.mts +9 -2
- package/dist/capture/pipeline.mjs +250 -45
- package/dist/capture/pipeline.mjs.map +1 -1
- package/dist/capture/progress.d.mts +11 -0
- package/dist/capture/progress.mjs +28 -0
- package/dist/capture/progress.mjs.map +1 -0
- package/dist/capture/publish/accept.d.mts +39 -0
- package/dist/capture/publish/accept.mjs +28 -0
- package/dist/capture/publish/accept.mjs.map +1 -0
- package/dist/capture/publish/complete.d.mts +46 -0
- package/dist/capture/publish/complete.mjs +64 -0
- package/dist/capture/publish/complete.mjs.map +1 -0
- package/dist/capture/publish/extract.d.mts +20 -0
- package/dist/capture/publish/extract.mjs +119 -0
- package/dist/capture/publish/extract.mjs.map +1 -0
- package/dist/capture/publish/handler.d.mts +28 -0
- package/dist/capture/publish/handler.mjs +62 -0
- package/dist/capture/publish/handler.mjs.map +1 -0
- package/dist/capture/publish/index.d.mts +10 -0
- package/dist/capture/publish/limits.d.mts +37 -0
- package/dist/capture/publish/limits.mjs +39 -0
- package/dist/capture/publish/limits.mjs.map +1 -0
- package/dist/capture/publish/published.d.mts +15 -0
- package/dist/capture/publish/published.mjs +18 -0
- package/dist/capture/publish/published.mjs.map +1 -0
- package/dist/capture/publish/run.d.mts +33 -0
- package/dist/capture/publish/run.mjs +30 -0
- package/dist/capture/publish/run.mjs.map +1 -0
- package/dist/capture/rediff.d.mts +1 -1
- package/dist/capture/rediff.mjs +4 -3
- package/dist/capture/rediff.mjs.map +1 -1
- package/dist/capture/render.mjs +53 -0
- package/dist/capture/render.mjs.map +1 -0
- package/dist/capture/scratch.d.mts +44 -0
- package/dist/capture/scratch.mjs +138 -0
- package/dist/capture/scratch.mjs.map +1 -0
- package/dist/capture/shard-plan.mjs +128 -0
- package/dist/capture/shard-plan.mjs.map +1 -0
- package/dist/capture/shards/context.mjs +51 -0
- package/dist/capture/shards/context.mjs.map +1 -0
- package/dist/capture/shards/execute.mjs +174 -0
- package/dist/capture/shards/execute.mjs.map +1 -0
- package/dist/capture/shards/fan-out.mjs +126 -0
- package/dist/capture/shards/fan-out.mjs.map +1 -0
- package/dist/capture/shards/history.mjs +35 -0
- package/dist/capture/shards/history.mjs.map +1 -0
- package/dist/capture/shards/reduce.mjs +97 -0
- package/dist/capture/shards/reduce.mjs.map +1 -0
- package/dist/capture/sizing.mjs +1 -11
- package/dist/capture/sizing.mjs.map +1 -1
- package/dist/capture/skip-checks.mjs +2 -65
- package/dist/capture/skip-checks.mjs.map +1 -1
- package/dist/capture/statics.d.mts +7 -8
- package/dist/capture/statics.mjs +25 -71
- package/dist/capture/statics.mjs.map +1 -1
- package/dist/capture/storybook-urls.d.mts +40 -0
- package/dist/capture/storybook-urls.mjs +41 -0
- package/dist/capture/storybook-urls.mjs.map +1 -0
- package/dist/capture/storybook.d.mts +12 -4
- package/dist/capture/storybook.mjs +56 -16
- package/dist/capture/storybook.mjs.map +1 -1
- package/dist/capture/target.mjs +21 -0
- package/dist/capture/target.mjs.map +1 -0
- package/dist/capture/targets.d.mts +25 -0
- package/dist/capture/targets.mjs +32 -0
- package/dist/capture/targets.mjs.map +1 -0
- package/dist/capture/tests.d.mts +37 -0
- package/dist/capture/tests.mjs +126 -0
- package/dist/capture/tests.mjs.map +1 -0
- package/dist/capture/token-chunks.mjs +74 -0
- package/dist/capture/token-chunks.mjs.map +1 -0
- package/dist/capture.d.mts +60 -7
- package/dist/capture.mjs +48 -3
- package/dist/config.d.mts +121 -12
- package/dist/config.mjs +9 -6
- package/dist/config.mjs.map +1 -1
- package/dist/diff.d.mts +9 -3
- package/dist/diff.mjs +16 -3
- package/dist/diff.mjs.map +1 -0
- package/dist/index.d.mts +1 -1
- package/dist/insights/budget.d.mts +20 -0
- package/dist/insights/budget.mjs +33 -0
- package/dist/insights/budget.mjs.map +1 -0
- package/dist/insights/envelope.d.mts +59 -0
- package/dist/insights/envelope.mjs +60 -0
- package/dist/insights/envelope.mjs.map +1 -0
- package/dist/insights/evidence-health.d.mts +32 -0
- package/dist/insights/evidence-health.mjs +28 -0
- package/dist/insights/evidence-health.mjs.map +1 -0
- package/dist/insights/evidence.d.mts +55 -0
- package/dist/insights/evidence.mjs +64 -0
- package/dist/insights/evidence.mjs.map +1 -0
- package/dist/insights/hash.d.mts +18 -0
- package/dist/insights/hash.mjs +21 -0
- package/dist/insights/hash.mjs.map +1 -0
- package/dist/insights/limits.d.mts +24 -0
- package/dist/insights/limits.mjs +24 -0
- package/dist/insights/limits.mjs.map +1 -0
- package/dist/insights/prompts/v1.d.mts +13 -0
- package/dist/insights/prompts/v1.mjs +34 -0
- package/dist/insights/prompts/v1.mjs.map +1 -0
- package/dist/insights/redact.d.mts +9 -0
- package/dist/insights/redact.mjs +24 -0
- package/dist/insights/redact.mjs.map +1 -0
- package/dist/insights/text.mjs +44 -0
- package/dist/insights/text.mjs.map +1 -0
- package/dist/insights.d.mts +11 -0
- package/dist/insights.mjs +12 -0
- package/dist/logger.mjs +17 -1
- package/dist/logger.mjs.map +1 -1
- package/dist/models/ai-budget-alert.d.mts +23 -0
- package/dist/models/ai-budget-alert.mjs +38 -0
- package/dist/models/ai-budget-alert.mjs.map +1 -0
- package/dist/models/ai-usage.d.mts +40 -0
- package/dist/models/ai-usage.mjs +61 -0
- package/dist/models/ai-usage.mjs.map +1 -0
- package/dist/models/baseline-archive.d.mts +84 -0
- package/dist/models/baseline-archive.mjs +106 -0
- package/dist/models/baseline-archive.mjs.map +1 -0
- package/dist/models/baseline-export.d.mts +19 -0
- package/dist/models/baseline-export.mjs +136 -0
- package/dist/models/baseline-export.mjs.map +1 -0
- package/dist/models/baseline-import.mjs +118 -0
- package/dist/models/baseline-import.mjs.map +1 -0
- package/dist/models/baseline-transfer.d.mts +49 -0
- package/dist/models/baseline-transfer.mjs +121 -0
- package/dist/models/baseline-transfer.mjs.map +1 -0
- package/dist/models/baseline.d.mts +32 -5
- package/dist/models/baseline.mjs +65 -20
- package/dist/models/baseline.mjs.map +1 -1
- package/dist/models/build-component.d.mts +28 -0
- package/dist/models/build-component.mjs +55 -0
- package/dist/models/build-component.mjs.map +1 -0
- package/dist/models/build-review-status.d.mts +29 -0
- package/dist/models/build-review-status.mjs +37 -0
- package/dist/models/build-review-status.mjs.map +1 -0
- package/dist/models/build-review.d.mts +28 -0
- package/dist/models/build-review.mjs +54 -0
- package/dist/models/build-review.mjs.map +1 -0
- package/dist/models/build.d.mts +25 -3
- package/dist/models/build.mjs +50 -11
- package/dist/models/build.mjs.map +1 -1
- package/dist/models/capture-attempt.d.mts +7 -1
- package/dist/models/capture-attempt.mjs +29 -4
- package/dist/models/capture-attempt.mjs.map +1 -1
- package/dist/models/capture-job.d.mts +106 -0
- package/dist/models/capture-job.mjs +288 -0
- package/dist/models/capture-job.mjs.map +1 -0
- package/dist/models/capture-log.d.mts +1 -1
- package/dist/models/capture-log.mjs +4 -3
- package/dist/models/capture-log.mjs.map +1 -1
- package/dist/models/capture-shard.d.mts +62 -0
- package/dist/models/capture-shard.mjs +190 -0
- package/dist/models/capture-shard.mjs.map +1 -0
- package/dist/models/changeset.d.mts +48 -0
- package/dist/models/changeset.mjs +81 -0
- package/dist/models/changeset.mjs.map +1 -0
- package/dist/models/columns.mjs +19 -0
- package/dist/models/columns.mjs.map +1 -0
- package/dist/models/comment.d.mts +4 -1
- package/dist/models/comment.mjs +7 -4
- package/dist/models/comment.mjs.map +1 -1
- package/dist/models/component.d.mts +43 -0
- package/dist/models/component.mjs +60 -0
- package/dist/models/component.mjs.map +1 -0
- package/dist/models/connections.d.mts +41 -0
- package/dist/models/connections.mjs +112 -0
- package/dist/models/connections.mjs.map +1 -0
- package/dist/models/content-ref.d.mts +1 -1
- package/dist/models/content-ref.mjs +1 -1
- package/dist/models/content-ref.mjs.map +1 -1
- package/dist/models/credentials.mjs +12 -2
- package/dist/models/credentials.mjs.map +1 -1
- package/dist/models/design-credentials.d.mts +41 -0
- package/dist/models/design-credentials.mjs +86 -0
- package/dist/models/design-credentials.mjs.map +1 -0
- package/dist/models/design-health.d.mts +16 -0
- package/dist/models/design-health.mjs +25 -0
- package/dist/models/design-health.mjs.map +1 -0
- package/dist/models/design-nodes.d.mts +83 -0
- package/dist/models/design-nodes.mjs +222 -0
- package/dist/models/design-nodes.mjs.map +1 -0
- package/dist/models/design-renders.mjs +74 -0
- package/dist/models/design-renders.mjs.map +1 -0
- package/dist/models/design-resolve.d.mts +29 -0
- package/dist/models/design-resolve.mjs +41 -0
- package/dist/models/design-resolve.mjs.map +1 -0
- package/dist/models/design.d.mts +39 -0
- package/dist/models/design.mjs +90 -0
- package/dist/models/design.mjs.map +1 -0
- package/dist/models/inherited-ratio.d.mts +21 -0
- package/dist/models/inherited-ratio.mjs +22 -0
- package/dist/models/inherited-ratio.mjs.map +1 -0
- package/dist/models/insight.d.mts +70 -0
- package/dist/models/insight.mjs +162 -0
- package/dist/models/insight.mjs.map +1 -0
- package/dist/models/label.d.mts +4 -2
- package/dist/models/label.mjs +25 -10
- package/dist/models/label.mjs.map +1 -1
- package/dist/models/member.d.mts +1 -1
- package/dist/models/member.mjs +5 -4
- package/dist/models/member.mjs.map +1 -1
- package/dist/models/notification-channel.d.mts +37 -3
- package/dist/models/notification-channel.mjs +88 -9
- package/dist/models/notification-channel.mjs.map +1 -1
- package/dist/models/notification-subscription.d.mts +1 -2
- package/dist/models/notification-subscription.mjs +7 -9
- package/dist/models/notification-subscription.mjs.map +1 -1
- package/dist/models/project-group-mapping.d.mts +6 -1
- package/dist/models/project-group-mapping.mjs +14 -4
- package/dist/models/project-group-mapping.mjs.map +1 -1
- package/dist/models/project.d.mts +9 -1
- package/dist/models/project.mjs +9 -4
- package/dist/models/project.mjs.map +1 -1
- package/dist/models/public-origin.d.mts +63 -0
- package/dist/models/public-origin.mjs +114 -0
- package/dist/models/public-origin.mjs.map +1 -0
- package/dist/models/review-switch-off.d.mts +14 -0
- package/dist/models/review-switch-off.mjs +26 -0
- package/dist/models/review-switch-off.mjs.map +1 -0
- package/dist/models/site-settings.d.mts +23 -0
- package/dist/models/site-settings.mjs +48 -0
- package/dist/models/site-settings.mjs.map +1 -0
- package/dist/models/snapshot.d.mts +36 -1
- package/dist/models/snapshot.mjs +50 -3
- package/dist/models/snapshot.mjs.map +1 -1
- package/dist/models/token.d.mts +13 -1
- package/dist/models/token.mjs +23 -5
- package/dist/models/token.mjs.map +1 -1
- package/dist/models/usage.d.mts +76 -0
- package/dist/models/usage.mjs +149 -0
- package/dist/models/usage.mjs.map +1 -0
- package/dist/models/user.d.mts +1 -1
- package/dist/models/user.mjs +4 -3
- package/dist/models/user.mjs.map +1 -1
- package/dist/models/webhook.d.mts +15 -1
- package/dist/models/webhook.mjs +33 -4
- package/dist/models/webhook.mjs.map +1 -1
- package/dist/models.d.mts +26 -3
- package/dist/models.mjs +27 -5
- package/dist/options.d.mts +18 -0
- package/dist/options.mjs +90 -0
- package/dist/options.mjs.map +1 -0
- package/dist/paths.d.mts +19 -4
- package/dist/paths.mjs +51 -10
- package/dist/paths.mjs.map +1 -1
- package/dist/retention/ai.d.mts +18 -0
- package/dist/retention/ai.mjs +23 -0
- package/dist/retention/ai.mjs.map +1 -0
- package/dist/retention/pending.mjs +47 -0
- package/dist/retention/pending.mjs.map +1 -0
- package/dist/retention/screenshot-sweep.d.mts +51 -0
- package/dist/retention/screenshot-sweep.mjs +128 -0
- package/dist/retention/screenshot-sweep.mjs.map +1 -0
- package/dist/retention.d.mts +16 -2
- package/dist/retention.mjs +71 -14
- package/dist/retention.mjs.map +1 -1
- package/dist/schema/baseline.d.mts +6 -0
- package/dist/schema/build-component.d.mts +25 -0
- package/dist/schema/build-review.d.mts +17 -0
- package/dist/schema/build.d.mts +7 -0
- package/dist/schema/capture-job.d.mts +60 -0
- package/dist/schema/capture-shard.d.mts +35 -0
- package/dist/schema/comment.d.mts +2 -0
- package/dist/schema/connection.d.mts +24 -0
- package/dist/schema/design.d.mts +58 -0
- package/dist/schema/insight.d.mts +54 -0
- package/dist/schema/notification.d.mts +4 -0
- package/dist/schema/project.d.mts +21 -0
- package/dist/schema/site-setting.d.mts +21 -0
- package/dist/schema/snapshot.d.mts +12 -0
- package/dist/schema/usage.d.mts +30 -0
- package/dist/schema.d.mts +11 -3
- package/dist/serverless.d.mts +21 -0
- package/dist/serverless.mjs +37 -0
- package/dist/serverless.mjs.map +1 -0
- package/dist/test-helpers/create-project.d.mts +1 -1
- package/dist/test-helpers/deferred.d.mts +39 -0
- package/dist/test-helpers/deferred.mjs +61 -0
- package/dist/test-helpers/deferred.mjs.map +1 -0
- package/dist/test-helpers/design-contract.d.mts +21 -0
- package/dist/test-helpers/design-contract.mjs +40 -0
- package/dist/test-helpers/design-contract.mjs.map +1 -0
- package/dist/test-helpers/fake-database.mjs +14 -2
- package/dist/test-helpers/fake-database.mjs.map +1 -1
- package/dist/test-helpers/fake-design.d.mts +43 -0
- package/dist/test-helpers/fake-design.mjs +114 -0
- package/dist/test-helpers/fake-design.mjs.map +1 -0
- package/dist/test-helpers/fake-notifier.d.mts +21 -0
- package/dist/test-helpers/fake-notifier.mjs +44 -0
- package/dist/test-helpers/fake-notifier.mjs.map +1 -0
- package/dist/test-helpers/fake-tables.mjs +255 -67
- package/dist/test-helpers/fake-tables.mjs.map +1 -1
- package/dist/test-helpers/manual-clock.d.mts +27 -0
- package/dist/test-helpers/manual-clock.mjs +56 -0
- package/dist/test-helpers/manual-clock.mjs.map +1 -0
- package/dist/test-helpers/notifier-contract.d.mts +7 -1
- package/dist/test-helpers/notifier-contract.mjs +32 -3
- package/dist/test-helpers/notifier-contract.mjs.map +1 -1
- package/dist/test-helpers/queue-contract.d.mts +16 -2
- package/dist/test-helpers/queue-contract.mjs +195 -1
- package/dist/test-helpers/queue-contract.mjs.map +1 -1
- package/dist/test-helpers/queue-multi-instance.d.mts +20 -0
- package/dist/test-helpers/queue-multi-instance.mjs +206 -0
- package/dist/test-helpers/queue-multi-instance.mjs.map +1 -0
- package/dist/test-helpers/runner-contract.mjs +11 -0
- package/dist/test-helpers/runner-contract.mjs.map +1 -1
- package/dist/test-helpers/sql-chunks.mjs +23 -0
- package/dist/test-helpers/sql-chunks.mjs.map +1 -1
- package/dist/test-helpers/storage-contract.mjs +1 -1
- package/dist/test-helpers.d.mts +9 -4
- package/dist/test-helpers.mjs +8 -3
- package/dist/types.d.mts +14 -3
- package/dist/types.mjs +21 -4
- package/dist/types.mjs.map +1 -1
- package/dist/urls.d.mts +4 -0
- package/dist/urls.mjs +11 -2
- package/dist/urls.mjs.map +1 -1
- package/dist/utils/adaptive-concurrency.d.mts +66 -0
- package/dist/utils/adaptive-concurrency.mjs +149 -0
- package/dist/utils/adaptive-concurrency.mjs.map +1 -0
- package/dist/utils/connect-retry.d.mts +26 -0
- package/dist/utils/connect-retry.mjs +43 -0
- package/dist/utils/connect-retry.mjs.map +1 -0
- package/dist/utils/environment.d.mts +19 -0
- package/dist/utils/environment.mjs +59 -0
- package/dist/utils/environment.mjs.map +1 -0
- package/dist/utils/http.d.mts +17 -1
- package/dist/utils/http.mjs +22 -3
- package/dist/utils/http.mjs.map +1 -1
- package/dist/utils/map-adaptive.d.mts +15 -0
- package/dist/utils/map-adaptive.mjs +72 -0
- package/dist/utils/map-adaptive.mjs.map +1 -0
- package/dist/utils/map-limit.d.mts +10 -0
- package/dist/utils/map-limit.mjs +32 -0
- package/dist/utils/map-limit.mjs.map +1 -0
- package/dist/utils/page-limiter.d.mts +37 -0
- package/dist/utils/page-limiter.mjs +56 -0
- package/dist/utils/page-limiter.mjs.map +1 -0
- package/dist/utils/public-origin.d.mts +20 -0
- package/dist/utils/public-origin.mjs +75 -0
- package/dist/utils/public-origin.mjs.map +1 -0
- package/dist/utils/redact.mjs +3 -0
- package/dist/utils/redact.mjs.map +1 -1
- package/dist/utils/remote-environment.d.mts +39 -0
- package/dist/utils/remote-environment.mjs +114 -0
- package/dist/utils/remote-environment.mjs.map +1 -0
- package/dist/utils/resources.d.mts +64 -0
- package/dist/utils/resources.mjs +122 -0
- package/dist/utils/resources.mjs.map +1 -0
- package/dist/utils/screenshot-store.d.mts +15 -0
- package/dist/utils/screenshot-store.mjs +41 -0
- package/dist/utils/screenshot-store.mjs.map +1 -0
- package/dist/utils/session-gate.d.mts +22 -0
- package/dist/utils/session-gate.mjs +53 -0
- package/dist/utils/session-gate.mjs.map +1 -0
- package/dist/utils/storybook-token.d.mts +81 -0
- package/dist/utils/storybook-token.mjs +134 -0
- package/dist/utils/storybook-token.mjs.map +1 -0
- package/dist/utils/storybook-url.d.mts +15 -0
- package/dist/utils/storybook-url.mjs +21 -0
- package/dist/utils/storybook-url.mjs.map +1 -0
- package/dist/utils/timing.mjs +1 -1
- package/dist/utils/timing.mjs.map +1 -1
- package/dist/utils/zip-read.mjs +129 -0
- package/dist/utils/zip-read.mjs.map +1 -0
- package/dist/utils/zip-write.d.mts +18 -0
- package/dist/utils/zip-write.mjs +188 -0
- package/dist/utils/zip-write.mjs.map +1 -0
- package/dist/utils.d.mts +17 -3
- package/dist/utils.mjs +18 -4
- package/package.json +32 -23
- package/dist/adapter/capture-runner.mjs.map +0 -1
- package/dist/adapter/git-host/comments.d.mts +0 -41
- package/dist/adapter/git-host/comments.mjs +0 -54
- package/dist/adapter/git-host/comments.mjs.map +0 -1
- package/dist/adapter/git-host/helpers.d.mts +0 -13
- package/dist/adapter/git-host/helpers.mjs +0 -30
- package/dist/adapter/git-host/helpers.mjs.map +0 -1
- package/dist/adapter/git-host.d.mts +0 -42
- package/dist/capture/queue.d.mts +0 -38
- package/dist/capture/queue.mjs +0 -98
- package/dist/capture/queue.mjs.map +0 -1
- package/dist/capture/recovery.d.mts +0 -21
- package/dist/capture/recovery.mjs +0 -83
- package/dist/capture/recovery.mjs.map +0 -1
- package/dist/capture/status-fanout.mjs +0 -72
- package/dist/capture/status-fanout.mjs.map +0 -1
- package/dist/diff/engine.d.mts +0 -16
- package/dist/diff/engine.mjs +0 -87
- package/dist/diff/engine.mjs.map +0 -1
- package/dist/diff/options.d.mts +0 -42
- package/dist/diff/options.mjs +0 -15
- package/dist/diff/options.mjs.map +0 -1
- package/dist/models/status-config.d.mts +0 -38
- package/dist/models/status-config.mjs +0 -63
- package/dist/models/status-config.mjs.map +0 -1
- package/dist/schema/status-config.d.mts +0 -16
- package/dist/test-helpers/git-contract.d.mts +0 -11
- package/dist/test-helpers/git-contract.mjs +0 -34
- package/dist/test-helpers/git-contract.mjs.map +0 -1
- /package/dist/adapter/{git-host.mjs → oauth.mjs} +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fake-tables.mjs","names":[],"sources":["../../src/test-helpers/fake-tables.ts"],"sourcesContent":["/**\n * Dialect-free stub tables for the in-memory test fake.\n *\n * The fake never touches a driver: it only needs table handles whose columns\n * carry the property → column-name mapping (`getTableColumns`) and flow\n * through drizzle's expression builders (`eq`, `and`, `inArray`, `orderBy`)\n * into the `sql-chunks.ts` matcher. Real `Column`/`Table` base classes from\n * the `drizzle-orm` root (already a core dependency) satisfy both without\n * pulling in any dialect package (`sqlite-core`, `pg-core`, …).\n */\nimport { Column, Table } from \"drizzle-orm\";\nimport type { Tables } from \"../adapters/database.ts\";\n\n/** A column handle with driver passthrough mapping (the fake maps nothing). */\nclass FakeColumn extends Column {\n override getSQLType(): string {\n return this.columnType;\n }\n}\n\n// `Table.Symbol` is runtime-only (`@internal`, absent from the public types).\nconst columnsSymbol = (Table as unknown as { Symbol: { Columns: symbol } }).Symbol.Columns;\n\nfunction defineTable(name: string, columns: Record<string, string>): Table {\n const table = new Table(name, undefined, name);\n const handles: Record<string, FakeColumn> = {};\n for (const [property, dbName] of Object.entries(columns)) {\n handles[property] = new FakeColumn(table, {\n name: dbName,\n keyAsName: false,\n notNull: false,\n default: undefined,\n defaultFn: undefined,\n onUpdateFn: undefined,\n hasDefault: false,\n primaryKey: false,\n isUnique: false,\n uniqueName: undefined,\n uniqueType: undefined,\n dataType: \"string\",\n columnType: \"FakeColumn\",\n generated: undefined,\n generatedIdentity: undefined,\n });\n }\n (table as unknown as Record<symbol, unknown>)[columnsSymbol] = handles;\n return table;\n}\n\n// Stub tables matching the real schema's property -> column mapping.\n// No constraints or defaults — just names for whereMatches/orderRows.\nconst projects = defineTable(\"projects\", {\n id: \"id\",\n name: \"name\",\n slug: \"slug\",\n gitRepository: \"git_repository\",\n gitDefaultBranch: \"git_default_branch\",\n pixelThreshold: \"pixel_threshold\",\n maxDiffRatio: \"max_diff_ratio\",\n publicBranchRegex: \"public_branch_regex\",\n storybookMeta: \"storybook_meta\",\n executePlay: \"execute_play\",\n playTimeoutMs: \"play_timeout_ms\",\n runA11y: \"run_a11y\",\n browser: \"browser\",\n viewports: \"viewports\",\n automigrate: \"automigrate\",\n createdAt: \"created_at\",\n updatedAt: \"updated_at\",\n});\n\nconst projectStatusConfigs = defineTable(\"project_status_configs\", {\n id: \"id\",\n projectId: \"project_id\",\n provider: \"provider\",\n config: \"config\",\n tokenEncrypted: \"token_encrypted\",\n createdAt: \"created_at\",\n updatedAt: \"updated_at\",\n});\n\nconst builds = defineTable(\"builds\", {\n id: \"id\",\n projectId: \"project_id\",\n gitSha: \"git_sha\",\n gitBranch: \"git_branch\",\n isDefault: \"is_default\",\n authorEmail: \"author_email\",\n authorName: \"author_name\",\n message: \"message\",\n public: \"public\",\n status: \"status\",\n snapshotCount: \"snapshot_count\",\n changedCount: \"changed_count\",\n approvedCount: \"approved_count\",\n rejectedCount: \"rejected_count\",\n affectedOnly: \"affected_only\",\n baselineSha: \"baseline_sha\",\n changedFiles: \"changed_files\",\n affectedImportPaths: \"affected_import_paths\",\n createdAt: \"created_at\",\n updatedAt: \"updated_at\",\n});\n\nconst captureAttempts = defineTable(\"capture_attempts\", {\n id: \"id\",\n projectId: \"project_id\",\n buildId: \"build_id\",\n attemptNo: \"attempt_no\",\n status: \"status\",\n error: \"error\",\n reqId: \"req_id\",\n storyCount: \"story_count\",\n failedCount: \"failed_count\",\n queuedAt: \"queued_at\",\n startedAt: \"started_at\",\n finishedAt: \"finished_at\",\n createdAt: \"created_at\",\n updatedAt: \"updated_at\",\n});\n\nconst captureLogs = defineTable(\"capture_logs\", {\n id: \"id\",\n projectId: \"project_id\",\n buildId: \"build_id\",\n attemptId: \"attempt_id\",\n seq: \"seq\",\n level: \"level\",\n message: \"message\",\n fields: \"fields\",\n createdAt: \"created_at\",\n});\n\nconst snapshots = defineTable(\"snapshots\", {\n id: \"id\",\n projectId: \"project_id\",\n buildId: \"build_id\",\n storyId: \"story_id\",\n storyName: \"story_name\",\n storyTitle: \"story_title\",\n storyImportPath: \"story_import_path\",\n viewportName: \"viewport_name\",\n viewportWidth: \"viewport_width\",\n viewportHeight: \"viewport_height\",\n screenshotPath: \"screenshot_path\",\n diffPath: \"diff_path\",\n diffPixels: \"diff_pixels\",\n diffRatio: \"diff_ratio\",\n diffPassed: \"diff_passed\",\n status: \"status\",\n reviewedBy: \"reviewed_by\",\n reviewedAt: \"reviewed_at\",\n infraHash: \"infra_hash\",\n inherited: \"inherited\",\n baselineId: \"baseline_id\",\n baselineVersion: \"baseline_version\",\n createdAt: \"created_at\",\n updatedAt: \"updated_at\",\n});\n\nconst baselines = defineTable(\"baselines\", {\n id: \"id\",\n projectId: \"project_id\",\n storyId: \"story_id\",\n viewportName: \"viewport_name\",\n branch: \"branch\",\n snapshotId: \"snapshot_id\",\n screenshotPath: \"screenshot_path\",\n infraHash: \"infra_hash\",\n createdAt: \"created_at\",\n updatedAt: \"updated_at\",\n});\n\nconst comments = defineTable(\"comments\", {\n id: \"id\",\n projectId: \"project_id\",\n buildId: \"build_id\",\n snapshotId: \"snapshot_id\",\n userId: \"user_id\",\n body: \"body\",\n parentId: \"parent_id\",\n resolved: \"resolved\",\n createdAt: \"created_at\",\n updatedAt: \"updated_at\",\n});\n\nconst labelTypes = defineTable(\"label_types\", {\n id: \"id\",\n projectId: \"project_id\",\n key: \"key\",\n name: \"name\",\n linkTemplate: \"link_template\",\n color: \"color\",\n createdAt: \"created_at\",\n});\n\nconst buildLabels = defineTable(\"build_labels\", {\n id: \"id\",\n projectId: \"project_id\",\n buildId: \"build_id\",\n typeKey: \"type_key\",\n value: \"value\",\n createdAt: \"created_at\",\n});\n\nconst tokens = defineTable(\"tokens\", {\n id: \"id\",\n projectId: \"project_id\",\n name: \"name\",\n hash: \"hash\",\n userId: \"user_id\",\n lastUsedAt: \"last_used_at\",\n createdAt: \"created_at\",\n});\n\nconst webhooks = defineTable(\"webhooks\", {\n id: \"id\",\n projectId: \"project_id\",\n url: \"url\",\n secretEncrypted: \"secret_encrypted\",\n events: \"events\",\n createdAt: \"created_at\",\n updatedAt: \"updated_at\",\n});\n\nconst users = defineTable(\"users\", {\n id: \"id\",\n email: \"email\",\n name: \"name\",\n avatarUrl: \"avatar_url\",\n role: \"role\",\n lastLoginAt: \"last_login_at\",\n createdAt: \"created_at\",\n passwordHash: \"password_hash\",\n displayNameOverride: \"display_name_override\",\n authProvider: \"auth_provider\",\n disabled: \"disabled\",\n});\n\nconst userInviteTokens = defineTable(\"user_invite_tokens\", {\n id: \"id\",\n userId: \"user_id\",\n tokenHash: \"token_hash\",\n expiresAt: \"expires_at\",\n usedAt: \"used_at\",\n createdAt: \"created_at\",\n});\n\nconst projectMembers = defineTable(\"project_members\", {\n id: \"id\",\n projectId: \"project_id\",\n userId: \"user_id\",\n role: \"role\",\n source: \"source\",\n createdAt: \"created_at\",\n});\n\nconst projectGroupMappings = defineTable(\"project_group_mappings\", {\n id: \"id\",\n projectId: \"project_id\",\n groupName: \"group_name\",\n role: \"role\",\n createdAt: \"created_at\",\n});\n\nconst notificationChannels = defineTable(\"notification_channels\", {\n id: \"id\",\n projectId: \"project_id\",\n provider: \"provider\",\n config: \"config\",\n secretEncrypted: \"secret_encrypted\",\n events: \"events\",\n enabled: \"enabled\",\n createdAt: \"created_at\",\n updatedAt: \"updated_at\",\n});\n\nconst notificationSubscriptions = defineTable(\"notification_subscriptions\", {\n id: \"id\",\n projectId: \"project_id\",\n userId: \"user_id\",\n events: \"events\",\n via: \"via\",\n enabled: \"enabled\",\n createdAt: \"created_at\",\n});\n\nconst contentRefs = defineTable(\"content_refs\", {\n hash: \"hash\",\n refCount: \"ref_count\",\n lastSeenAt: \"last_seen_at\",\n createdAt: \"created_at\",\n});\n\n/** Stub schema bundled into the `Tables` map every fake serves. */\nexport const fakeSchema: Tables = {\n projects,\n projectStatusConfigs,\n builds,\n captureAttempts,\n captureLogs,\n snapshots,\n baselines,\n comments,\n labelTypes,\n buildLabels,\n tokens,\n webhooks,\n users,\n userInviteTokens,\n projectMembers,\n projectGroupMappings,\n notificationChannels,\n notificationSubscriptions,\n contentRefs,\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"fake-tables.mjs","names":[],"sources":["../../src/test-helpers/fake-tables.ts"],"sourcesContent":["/**\n * Dialect-free stub tables for the in-memory test fake.\n *\n * The fake never touches a driver: it only needs table handles whose columns\n * carry the property → column-name mapping (`getTableColumns`) and flow\n * through drizzle's expression builders (`eq`, `and`, `inArray`, `orderBy`)\n * into the `sql-chunks.ts` matcher. Real `Column`/`Table` base classes from\n * the `drizzle-orm` root (already a core dependency) satisfy both without\n * pulling in any dialect package (`sqlite-core`, `pg-core`, …).\n */\nimport { Column, Table } from \"drizzle-orm\";\nimport type { Tables } from \"../adapters/database.ts\";\n\n/** A column handle with driver passthrough mapping (the fake maps nothing). */\nclass FakeColumn extends Column {\n override getSQLType(): string {\n return this.columnType;\n }\n}\n\n// `Table.Symbol` is runtime-only (`@internal`, absent from the public types).\nconst columnsSymbol = (Table as unknown as { Symbol: { Columns: symbol } }).Symbol.Columns;\n\nfunction defineTable(name: string, columns: Record<string, string>): Table {\n const table = new Table(name, undefined, name);\n const handles: Record<string, FakeColumn> = {};\n for (const [property, dbName] of Object.entries(columns)) {\n handles[property] = new FakeColumn(table, {\n name: dbName,\n keyAsName: false,\n notNull: false,\n default: undefined,\n defaultFn: undefined,\n onUpdateFn: undefined,\n hasDefault: false,\n primaryKey: false,\n isUnique: false,\n uniqueName: undefined,\n uniqueType: undefined,\n dataType: \"string\",\n columnType: \"FakeColumn\",\n generated: undefined,\n generatedIdentity: undefined,\n });\n }\n (table as unknown as Record<symbol, unknown>)[columnsSymbol] = handles;\n return table;\n}\n\n// Stub tables matching the real schema's property -> column mapping.\n// No constraints or defaults — just names for whereMatches/orderRows.\nconst projects = defineTable(\"projects\", {\n id: \"id\",\n name: \"name\",\n slug: \"slug\",\n gitRepository: \"git_repository\",\n gitDefaultBranch: \"git_default_branch\",\n pixelThreshold: \"pixel_threshold\",\n maxDiffRatio: \"max_diff_ratio\",\n publicBranchRegex: \"public_branch_regex\",\n storybookMeta: \"storybook_meta\",\n executePlay: \"execute_play\",\n playTimeoutMs: \"play_timeout_ms\",\n runA11y: \"run_a11y\",\n runTests: \"run_tests\",\n browser: \"browser\",\n viewports: \"viewports\",\n browsers: \"browsers\",\n modesAllowlist: \"modes_allowlist\",\n automigrate: \"automigrate\",\n aiProfile: \"ai_profile\",\n reviewEnabled: \"review_enabled\",\n reviewApprovals: \"review_approvals\",\n storybookUrlTtlSeconds: \"storybook_url_ttl_seconds\",\n createdAt: \"created_at\",\n updatedAt: \"updated_at\",\n});\n\nconst designLinks = defineTable(\"design_links\", {\n id: \"id\",\n projectId: \"project_id\",\n importPath: \"import_path\",\n label: \"label\",\n url: \"url\",\n createdAt: \"created_at\",\n updatedAt: \"updated_at\",\n});\n\nconst designCredentials = defineTable(\"design_credentials\", {\n id: \"id\",\n projectId: \"project_id\",\n provider: \"provider\",\n tokenEncrypted: \"token_encrypted\",\n status: \"status\",\n checkedAt: \"checked_at\",\n createdAt: \"created_at\",\n updatedAt: \"updated_at\",\n});\n\nconst userConnections = defineTable(\"user_connections\", {\n id: \"id\",\n userId: \"user_id\",\n service: \"service\",\n tokenEncrypted: \"token_encrypted\",\n refreshTokenEncrypted: \"refresh_token_encrypted\",\n expiresAt: \"expires_at\",\n status: \"status\",\n createdAt: \"created_at\",\n updatedAt: \"updated_at\",\n});\n\nconst designNodes = defineTable(\"design_nodes\", {\n id: \"id\",\n projectId: \"project_id\",\n provider: \"provider\",\n viewerId: \"viewer_id\",\n fileKey: \"file_key\",\n nodeId: \"node_id\",\n name: \"name\",\n version: \"version\",\n lastModified: \"last_modified\",\n state: \"state\",\n renderPath: \"render_path\",\n renderVersion: \"render_version\",\n fetchedAt: \"fetched_at\",\n createdAt: \"created_at\",\n updatedAt: \"updated_at\",\n});\n\nconst builds = defineTable(\"builds\", {\n id: \"id\",\n projectId: \"project_id\",\n gitSha: \"git_sha\",\n gitBranch: \"git_branch\",\n isDefault: \"is_default\",\n authorEmail: \"author_email\",\n authorName: \"author_name\",\n message: \"message\",\n public: \"public\",\n status: \"status\",\n snapshotCount: \"snapshot_count\",\n changedCount: \"changed_count\",\n approvedCount: \"approved_count\",\n rejectedCount: \"rejected_count\",\n inheritedCount: \"inherited_count\",\n affectedOnly: \"affected_only\",\n baselineSha: \"baseline_sha\",\n changedFiles: \"changed_files\",\n affectedImportPaths: \"affected_import_paths\",\n testResults: \"test_results\",\n createdAt: \"created_at\",\n updatedAt: \"updated_at\",\n});\n\nconst captureAttempts = defineTable(\"capture_attempts\", {\n id: \"id\",\n projectId: \"project_id\",\n buildId: \"build_id\",\n attemptNo: \"attempt_no\",\n status: \"status\",\n error: \"error\",\n reqId: \"req_id\",\n storyCount: \"story_count\",\n failedCount: \"failed_count\",\n queuedAt: \"queued_at\",\n startedAt: \"started_at\",\n finishedAt: \"finished_at\",\n createdAt: \"created_at\",\n updatedAt: \"updated_at\",\n});\n\nconst captureShards = defineTable(\"capture_shards\", {\n id: \"id\",\n projectId: \"project_id\",\n buildId: \"build_id\",\n kind: \"kind\",\n ordinal: \"ordinal\",\n status: \"status\",\n attemptId: \"attempt_id\",\n payload: \"payload\",\n result: \"result\",\n error: \"error\",\n startedAt: \"started_at\",\n finishedAt: \"finished_at\",\n createdAt: \"created_at\",\n updatedAt: \"updated_at\",\n});\n\nconst captureJobs = defineTable(\"capture_jobs\", {\n id: \"id\",\n entry: \"entry\",\n jobId: \"job_id\",\n kind: \"kind\",\n buildId: \"build_id\",\n shardId: \"shard_id\",\n attempt: \"attempt\",\n maxAttempts: \"max_attempts\",\n status: \"status\",\n visibleAt: \"visible_at\",\n owner: \"owner\",\n payload: \"payload\",\n cancelRequestedAt: \"cancel_requested_at\",\n error: \"error\",\n startedAt: \"started_at\",\n finishedAt: \"finished_at\",\n createdAt: \"created_at\",\n updatedAt: \"updated_at\",\n});\n\nconst buildComponents = defineTable(\"build_components\", {\n id: \"id\",\n projectId: \"project_id\",\n buildId: \"build_id\",\n importPath: \"import_path\",\n title: \"title\",\n storyCount: \"story_count\",\n hash: \"hash\",\n createdAt: \"created_at\",\n});\n\nconst buildReviews = defineTable(\"build_reviews\", {\n id: \"id\",\n buildId: \"build_id\",\n userId: \"user_id\",\n verdict: \"verdict\",\n body: \"body\",\n createdAt: \"created_at\",\n});\n\nconst siteSettings = defineTable(\"site_settings\", {\n id: \"id\",\n value: \"value\",\n updatedBy: \"updated_by\",\n createdAt: \"created_at\",\n updatedAt: \"updated_at\",\n});\n\nconst captureLogs = defineTable(\"capture_logs\", {\n id: \"id\",\n projectId: \"project_id\",\n buildId: \"build_id\",\n attemptId: \"attempt_id\",\n seq: \"seq\",\n level: \"level\",\n message: \"message\",\n fields: \"fields\",\n createdAt: \"created_at\",\n});\n\nconst snapshots = defineTable(\"snapshots\", {\n durationMs: \"duration_ms\",\n a11yViolations: \"a11y_violations\",\n id: \"id\",\n projectId: \"project_id\",\n buildId: \"build_id\",\n storyId: \"story_id\",\n storyName: \"story_name\",\n storyTitle: \"story_title\",\n storyImportPath: \"story_import_path\",\n viewportName: \"viewport_name\",\n viewportWidth: \"viewport_width\",\n viewportHeight: \"viewport_height\",\n screenshotPath: \"screenshot_path\",\n diffPath: \"diff_path\",\n diffPixels: \"diff_pixels\",\n diffRatio: \"diff_ratio\",\n diffPassed: \"diff_passed\",\n status: \"status\",\n reviewedBy: \"reviewed_by\",\n reviewedAt: \"reviewed_at\",\n designUrl: \"design_url\",\n infraHash: \"infra_hash\",\n envChange: \"env_change\",\n inherited: \"inherited\",\n baselineId: \"baseline_id\",\n baselineVersion: \"baseline_version\",\n mode: \"mode\",\n browser: \"browser\",\n createdAt: \"created_at\",\n updatedAt: \"updated_at\",\n});\n\nconst baselines = defineTable(\"baselines\", {\n id: \"id\",\n projectId: \"project_id\",\n storyId: \"story_id\",\n viewportName: \"viewport_name\",\n branch: \"branch\",\n snapshotId: \"snapshot_id\",\n screenshotPath: \"screenshot_path\",\n infraHash: \"infra_hash\",\n fingerprint: \"fingerprint\",\n mode: \"mode\",\n browser: \"browser\",\n createdAt: \"created_at\",\n updatedAt: \"updated_at\",\n});\n\nconst comments = defineTable(\"comments\", {\n id: \"id\",\n projectId: \"project_id\",\n buildId: \"build_id\",\n snapshotId: \"snapshot_id\",\n userId: \"user_id\",\n body: \"body\",\n parentId: \"parent_id\",\n resolved: \"resolved\",\n createdAt: \"created_at\",\n updatedAt: \"updated_at\",\n storyId: \"story_id\",\n});\n\nconst labelTypes = defineTable(\"label_types\", {\n id: \"id\",\n projectId: \"project_id\",\n key: \"key\",\n name: \"name\",\n linkTemplate: \"link_template\",\n color: \"color\",\n createdAt: \"created_at\",\n});\n\nconst buildLabels = defineTable(\"build_labels\", {\n id: \"id\",\n projectId: \"project_id\",\n buildId: \"build_id\",\n typeKey: \"type_key\",\n value: \"value\",\n createdAt: \"created_at\",\n});\n\nconst projectLinks = defineTable(\"project_links\", {\n id: \"id\",\n downstreamId: \"downstream_id\",\n upstreamId: \"upstream_id\",\n packageName: \"package_name\",\n createdAt: \"created_at\",\n});\n\nconst buildPackageUsage = defineTable(\"build_package_usage\", {\n id: \"id\",\n projectId: \"project_id\",\n buildId: \"build_id\",\n storyImportPath: \"story_import_path\",\n packageName: \"package_name\",\n modulePath: \"module_path\",\n version: \"version\",\n createdAt: \"created_at\",\n});\n\nconst tokens = defineTable(\"tokens\", {\n id: \"id\",\n projectId: \"project_id\",\n name: \"name\",\n hash: \"hash\",\n userId: \"user_id\",\n lastUsedAt: \"last_used_at\",\n createdAt: \"created_at\",\n});\n\nconst webhooks = defineTable(\"webhooks\", {\n id: \"id\",\n projectId: \"project_id\",\n url: \"url\",\n secretEncrypted: \"secret_encrypted\",\n events: \"events\",\n createdAt: \"created_at\",\n updatedAt: \"updated_at\",\n});\n\nconst users = defineTable(\"users\", {\n id: \"id\",\n email: \"email\",\n name: \"name\",\n avatarUrl: \"avatar_url\",\n role: \"role\",\n lastLoginAt: \"last_login_at\",\n createdAt: \"created_at\",\n passwordHash: \"password_hash\",\n displayNameOverride: \"display_name_override\",\n authProvider: \"auth_provider\",\n disabled: \"disabled\",\n});\n\nconst userInviteTokens = defineTable(\"user_invite_tokens\", {\n id: \"id\",\n userId: \"user_id\",\n tokenHash: \"token_hash\",\n expiresAt: \"expires_at\",\n usedAt: \"used_at\",\n createdAt: \"created_at\",\n});\n\nconst projectMembers = defineTable(\"project_members\", {\n id: \"id\",\n projectId: \"project_id\",\n userId: \"user_id\",\n role: \"role\",\n source: \"source\",\n createdAt: \"created_at\",\n});\n\nconst projectGroupMappings = defineTable(\"project_group_mappings\", {\n id: \"id\",\n projectId: \"project_id\",\n groupName: \"group_name\",\n role: \"role\",\n createdAt: \"created_at\",\n});\n\nconst insights = defineTable(\"insights\", {\n id: \"id\",\n projectId: \"project_id\",\n buildId: \"build_id\",\n kind: \"kind\",\n windowKey: \"window_key\",\n inputHash: \"input_hash\",\n status: \"status\",\n profile: \"profile\",\n model: \"model\",\n promptVersion: \"prompt_version\",\n verdict: \"verdict\",\n summary: \"summary\",\n result: \"result\",\n errorCode: \"error_code\",\n createdAt: \"created_at\",\n startedAt: \"started_at\",\n finishedAt: \"finished_at\",\n});\n\nconst aiUsage = defineTable(\"ai_usage\", {\n id: \"id\",\n insightId: \"insight_id\",\n projectId: \"project_id\",\n profile: \"profile\",\n task: \"task\",\n model: \"model\",\n inputTokens: \"input_tokens\",\n outputTokens: \"output_tokens\",\n estimated: \"estimated\",\n images: \"images\",\n status: \"status\",\n createdAt: \"created_at\",\n});\n\nconst aiBudgetAlerts = defineTable(\"ai_budget_alerts\", {\n id: \"id\",\n day: \"day\",\n threshold: \"threshold\",\n createdAt: \"created_at\",\n});\n\nconst notificationChannels = defineTable(\"notification_channels\", {\n id: \"id\",\n projectId: \"project_id\",\n provider: \"provider\",\n config: \"config\",\n secretEncrypted: \"secret_encrypted\",\n events: \"events\",\n enabled: \"enabled\",\n lastError: \"last_error\",\n lastErrorAt: \"last_error_at\",\n createdAt: \"created_at\",\n updatedAt: \"updated_at\",\n});\n\nconst notificationSubscriptions = defineTable(\"notification_subscriptions\", {\n id: \"id\",\n projectId: \"project_id\",\n userId: \"user_id\",\n events: \"events\",\n via: \"via\",\n enabled: \"enabled\",\n createdAt: \"created_at\",\n});\n\nconst contentRefs = defineTable(\"content_refs\", {\n hash: \"hash\",\n refCount: \"ref_count\",\n lastSeenAt: \"last_seen_at\",\n createdAt: \"created_at\",\n});\n\n/** Stub schema bundled into the `Tables` map every fake serves. */\nexport const fakeSchema: Tables = {\n projects,\n builds,\n captureAttempts,\n captureLogs,\n captureShards,\n captureJobs,\n buildComponents,\n buildReviews,\n siteSettings,\n snapshots,\n baselines,\n comments,\n labelTypes,\n buildLabels,\n projectLinks,\n designLinks,\n designCredentials,\n userConnections,\n designNodes,\n buildPackageUsage,\n tokens,\n webhooks,\n users,\n userInviteTokens,\n projectMembers,\n projectGroupMappings,\n insights,\n aiUsage,\n aiBudgetAlerts,\n notificationChannels,\n notificationSubscriptions,\n contentRefs,\n};\n"],"mappings":"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"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import __tsdown_shims_path from 'node:path';
|
|
2
|
+
import __tsdown_shims_url from 'node:url';
|
|
3
|
+
//#region src/test-helpers/manual-clock.d.ts
|
|
4
|
+
/**
|
|
5
|
+
* A manual clock with its own timers, for lease, poll-cadence and cancel tests that must not sleep.
|
|
6
|
+
* `advance` moves time forward and fires every timer that falls due, in order, letting promise
|
|
7
|
+
* chains settle between timers, so code under test behaves as it would with real time.
|
|
8
|
+
*/
|
|
9
|
+
/** Manual clock: `now` for injected clocks, `timers` for injected `setTimeout`/`clearTimeout`. */
|
|
10
|
+
interface ManualClock {
|
|
11
|
+
now: () => number;
|
|
12
|
+
timers: {
|
|
13
|
+
setTimeout(callback: () => void, ms: number): unknown;
|
|
14
|
+
clearTimeout(handle: unknown): void;
|
|
15
|
+
};
|
|
16
|
+
/** Move time forward by `ms`, firing due timers in order. */
|
|
17
|
+
advance(ms: number): Promise<void>;
|
|
18
|
+
/** Let pending promise chains run without moving time. */
|
|
19
|
+
flush(): Promise<void>;
|
|
20
|
+
/** Timers currently scheduled. */
|
|
21
|
+
readonly pending: number;
|
|
22
|
+
}
|
|
23
|
+
/** Create a manual clock starting at `start` (epoch ms). */
|
|
24
|
+
declare function createManualClock(start?: number): ManualClock;
|
|
25
|
+
//#endregion
|
|
26
|
+
export { ManualClock, createManualClock };
|
|
27
|
+
//# sourceMappingURL=manual-clock.d.mts.map
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import "node:path";
|
|
2
|
+
import "node:url";
|
|
3
|
+
import.meta.url;
|
|
4
|
+
//#region src/test-helpers/manual-clock.ts
|
|
5
|
+
/** Let queued promise jobs and I/O callbacks run (a few macrotask turns). */
|
|
6
|
+
async function settle() {
|
|
7
|
+
for (let turn = 0; turn < 5; turn += 1) await new Promise((resolve) => {
|
|
8
|
+
setImmediate(resolve);
|
|
9
|
+
});
|
|
10
|
+
}
|
|
11
|
+
/** Create a manual clock starting at `start` (epoch ms). */
|
|
12
|
+
function createManualClock(start = Date.parse("2026-01-01T00:00:00.000Z")) {
|
|
13
|
+
let current = start;
|
|
14
|
+
let nextId = 1;
|
|
15
|
+
const timers = [];
|
|
16
|
+
const due = (until) => timers.filter((timer) => timer.at <= until).toSorted((a, b) => a.at - b.at || a.id - b.id)[0];
|
|
17
|
+
return {
|
|
18
|
+
now: () => current,
|
|
19
|
+
timers: {
|
|
20
|
+
setTimeout: (callback, ms) => {
|
|
21
|
+
const timer = {
|
|
22
|
+
id: nextId,
|
|
23
|
+
at: current + Math.max(0, ms),
|
|
24
|
+
callback
|
|
25
|
+
};
|
|
26
|
+
nextId += 1;
|
|
27
|
+
timers.push(timer);
|
|
28
|
+
return timer.id;
|
|
29
|
+
},
|
|
30
|
+
clearTimeout: (handle) => {
|
|
31
|
+
const index = timers.findIndex((timer) => timer.id === handle);
|
|
32
|
+
if (index !== -1) timers.splice(index, 1);
|
|
33
|
+
}
|
|
34
|
+
},
|
|
35
|
+
advance: async (ms) => {
|
|
36
|
+
const until = current + ms;
|
|
37
|
+
await settle();
|
|
38
|
+
for (let timer = due(until); timer !== void 0; timer = due(until)) {
|
|
39
|
+
timers.splice(timers.indexOf(timer), 1);
|
|
40
|
+
current = Math.max(current, timer.at);
|
|
41
|
+
timer.callback();
|
|
42
|
+
await settle();
|
|
43
|
+
}
|
|
44
|
+
current = until;
|
|
45
|
+
await settle();
|
|
46
|
+
},
|
|
47
|
+
flush: settle,
|
|
48
|
+
get pending() {
|
|
49
|
+
return timers.length;
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
//#endregion
|
|
54
|
+
export { createManualClock };
|
|
55
|
+
|
|
56
|
+
//# sourceMappingURL=manual-clock.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manual-clock.mjs","names":[],"sources":["../../src/test-helpers/manual-clock.ts"],"sourcesContent":["/**\n * A manual clock with its own timers, for lease, poll-cadence and cancel tests that must not sleep.\n * `advance` moves time forward and fires every timer that falls due, in order, letting promise\n * chains settle between timers, so code under test behaves as it would with real time.\n */\n\n/** A scheduled callback. */\ninterface PendingTimer {\n id: number;\n at: number;\n callback: () => void;\n}\n\n/** Manual clock: `now` for injected clocks, `timers` for injected `setTimeout`/`clearTimeout`. */\nexport interface ManualClock {\n now: () => number;\n timers: {\n setTimeout(callback: () => void, ms: number): unknown;\n clearTimeout(handle: unknown): void;\n };\n /** Move time forward by `ms`, firing due timers in order. */\n advance(ms: number): Promise<void>;\n /** Let pending promise chains run without moving time. */\n flush(): Promise<void>;\n /** Timers currently scheduled. */\n readonly pending: number;\n}\n\n/** Let queued promise jobs and I/O callbacks run (a few macrotask turns). */\nasync function settle(): Promise<void> {\n for (let turn = 0; turn < 5; turn += 1) {\n // oxlint-disable-next-line eslint/no-await-in-loop -- each turn drains one round of callbacks\n await new Promise((resolve) => {\n setImmediate(resolve);\n });\n }\n}\n\n/** Create a manual clock starting at `start` (epoch ms). */\nexport function createManualClock(start = Date.parse(\"2026-01-01T00:00:00.000Z\")): ManualClock {\n let current = start;\n let nextId = 1;\n const timers: PendingTimer[] = [];\n const due = (until: number): PendingTimer | undefined =>\n timers.filter((timer) => timer.at <= until).toSorted((a, b) => a.at - b.at || a.id - b.id)[0];\n return {\n now: () => current,\n timers: {\n setTimeout: (callback, ms) => {\n const timer = { id: nextId, at: current + Math.max(0, ms), callback };\n nextId += 1;\n timers.push(timer);\n return timer.id;\n },\n clearTimeout: (handle) => {\n const index = timers.findIndex((timer) => timer.id === handle);\n if (index !== -1) {\n timers.splice(index, 1);\n }\n },\n },\n advance: async (ms) => {\n const until = current + ms;\n await settle();\n for (let timer = due(until); timer !== undefined; timer = due(until)) {\n timers.splice(timers.indexOf(timer), 1);\n current = Math.max(current, timer.at);\n timer.callback();\n // oxlint-disable-next-line eslint/no-await-in-loop -- let the callback's promises settle\n await settle();\n }\n current = until;\n await settle();\n },\n flush: settle,\n get pending() {\n return timers.length;\n },\n };\n}\n"],"mappings":";;;;;AA6BA,eAAe,SAAwB;CACrC,KAAK,IAAI,OAAO,GAAG,OAAO,GAAG,QAAQ,GAEnC,MAAM,IAAI,SAAS,YAAY;EAC7B,aAAa,OAAO;CACtB,CAAC;AAEL;;AAGA,SAAgB,kBAAkB,QAAQ,KAAK,MAAM,0BAA0B,GAAgB;CAC7F,IAAI,UAAU;CACd,IAAI,SAAS;CACb,MAAM,SAAyB,CAAC;CAChC,MAAM,OAAO,UACX,OAAO,QAAQ,UAAU,MAAM,MAAM,KAAK,CAAC,CAAC,UAAU,GAAG,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC;CAC7F,OAAO;EACL,WAAW;EACX,QAAQ;GACN,aAAa,UAAU,OAAO;IAC5B,MAAM,QAAQ;KAAE,IAAI;KAAQ,IAAI,UAAU,KAAK,IAAI,GAAG,EAAE;KAAG;IAAS;IACpE,UAAU;IACV,OAAO,KAAK,KAAK;IACjB,OAAO,MAAM;GACf;GACA,eAAe,WAAW;IACxB,MAAM,QAAQ,OAAO,WAAW,UAAU,MAAM,OAAO,MAAM;IAC7D,IAAI,UAAU,IACZ,OAAO,OAAO,OAAO,CAAC;GAE1B;EACF;EACA,SAAS,OAAO,OAAO;GACrB,MAAM,QAAQ,UAAU;GACxB,MAAM,OAAO;GACb,KAAK,IAAI,QAAQ,IAAI,KAAK,GAAG,UAAU,KAAA,GAAW,QAAQ,IAAI,KAAK,GAAG;IACpE,OAAO,OAAO,OAAO,QAAQ,KAAK,GAAG,CAAC;IACtC,UAAU,KAAK,IAAI,SAAS,MAAM,EAAE;IACpC,MAAM,SAAS;IAEf,MAAM,OAAO;GACf;GACA,UAAU;GACV,MAAM,OAAO;EACf;EACA,OAAO;EACP,IAAI,UAAU;GACZ,OAAO,OAAO;EAChB;CACF;AACF"}
|
|
@@ -6,6 +6,12 @@ import { NotifierProvider } from "../adapters/notifier/provider.mjs";
|
|
|
6
6
|
type NotifierFactory = () => NotifierProvider | Promise<NotifierProvider>;
|
|
7
7
|
/** Run the notifier contract against a factory. */
|
|
8
8
|
declare function notifierContractSuite(label: string, make: NotifierFactory): void;
|
|
9
|
+
/**
|
|
10
|
+
* Run the `state` delivery contract against a factory: the provider declares
|
|
11
|
+
* `delivery: "state"`, binds a valid `config` to an adapter that can `setState`,
|
|
12
|
+
* and rejects an invalid config at `create`.
|
|
13
|
+
*/
|
|
14
|
+
declare function stateNotifierContractSuite(label: string, make: NotifierFactory, validConfig: unknown): void;
|
|
9
15
|
//#endregion
|
|
10
|
-
export { NotifierFactory, notifierContractSuite };
|
|
16
|
+
export { NotifierFactory, notifierContractSuite, stateNotifierContractSuite };
|
|
11
17
|
//# sourceMappingURL=notifier-contract.d.mts.map
|
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
import "node:path";
|
|
2
2
|
import "node:url";
|
|
3
3
|
import.meta.url;
|
|
4
|
+
import { isStateProvider } from "../adapters/notifier/provider.mjs";
|
|
4
5
|
import { describe, expect, it } from "vitest";
|
|
5
6
|
//#region src/test-helpers/notifier-contract.ts
|
|
6
7
|
/**
|
|
7
|
-
* Published notifier contract
|
|
8
|
+
* Published notifier contract suites for first- and third-party providers.
|
|
8
9
|
*
|
|
9
10
|
* Structural conformance (identity, descriptor, config schema). Message
|
|
10
|
-
* delivery
|
|
11
|
+
* and state delivery stay per-package behind faked transports.
|
|
11
12
|
*/
|
|
12
13
|
/** Run the notifier contract against a factory. */
|
|
13
14
|
function notifierContractSuite(label, make) {
|
|
@@ -28,7 +29,35 @@ function notifierContractSuite(label, make) {
|
|
|
28
29
|
});
|
|
29
30
|
});
|
|
30
31
|
}
|
|
32
|
+
/**
|
|
33
|
+
* Run the `state` delivery contract against a factory: the provider declares
|
|
34
|
+
* `delivery: "state"`, binds a valid `config` to an adapter that can `setState`,
|
|
35
|
+
* and rejects an invalid config at `create`.
|
|
36
|
+
*/
|
|
37
|
+
function stateNotifierContractSuite(label, make, validConfig) {
|
|
38
|
+
notifierContractSuite(label, make);
|
|
39
|
+
describe(`state notifier contract: ${label}`, () => {
|
|
40
|
+
it("declares state delivery", async () => {
|
|
41
|
+
const provider = await make();
|
|
42
|
+
expect(isStateProvider(provider)).toBe(true);
|
|
43
|
+
});
|
|
44
|
+
it("binds a valid config to an adapter that can set state", async () => {
|
|
45
|
+
const adapter = (await make()).create({
|
|
46
|
+
config: validConfig,
|
|
47
|
+
secret: "token"
|
|
48
|
+
});
|
|
49
|
+
expect("setState" in adapter && typeof adapter.setState === "function").toBe(true);
|
|
50
|
+
});
|
|
51
|
+
it("rejects an invalid config at create", async () => {
|
|
52
|
+
const provider = await make();
|
|
53
|
+
expect(() => provider.create({
|
|
54
|
+
config: {},
|
|
55
|
+
secret: "token"
|
|
56
|
+
})).toThrow();
|
|
57
|
+
});
|
|
58
|
+
});
|
|
59
|
+
}
|
|
31
60
|
//#endregion
|
|
32
|
-
export { notifierContractSuite };
|
|
61
|
+
export { notifierContractSuite, stateNotifierContractSuite };
|
|
33
62
|
|
|
34
63
|
//# sourceMappingURL=notifier-contract.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"notifier-contract.mjs","names":[],"sources":["../../src/test-helpers/notifier-contract.ts"],"sourcesContent":["/**\n * Published notifier contract
|
|
1
|
+
{"version":3,"file":"notifier-contract.mjs","names":[],"sources":["../../src/test-helpers/notifier-contract.ts"],"sourcesContent":["/**\n * Published notifier contract suites for first- and third-party providers.\n *\n * Structural conformance (identity, descriptor, config schema). Message\n * and state delivery stay per-package behind faked transports.\n */\nimport { describe, expect, it } from \"vitest\";\nimport type { NotifierProvider } from \"../adapters/notifier/provider.ts\";\nimport { isStateProvider } from \"../adapters/notifier/provider.ts\";\n\n/** Build the provider under test (sync or async factories both work). */\nexport type NotifierFactory = () => NotifierProvider | Promise<NotifierProvider>;\n\n/** Run the notifier contract against a factory. */\nexport function notifierContractSuite(label: string, make: NotifierFactory): void {\n describe(`notifier contract: ${label}`, () => {\n it(\"exposes notifier metadata with a config schema\", async () => {\n const provider = await make();\n expect(provider.metadata.category).toBe(\"notifier\");\n expect(provider.metadata.kind.length).toBeGreaterThan(0);\n expect(typeof provider.metadata.schema.parse).toBe(\"function\");\n });\n\n it(\"exposes the create descriptor\", async () => {\n const provider = await make();\n expect(typeof provider.create).toBe(\"function\");\n });\n\n it(\"validates channel config through a real schema\", async () => {\n const provider = await make();\n const result = provider.metadata.schema.safeParse({});\n expect(typeof result.success).toBe(\"boolean\");\n });\n });\n}\n\n/**\n * Run the `state` delivery contract against a factory: the provider declares\n * `delivery: \"state\"`, binds a valid `config` to an adapter that can `setState`,\n * and rejects an invalid config at `create`.\n */\nexport function stateNotifierContractSuite(\n label: string,\n make: NotifierFactory,\n validConfig: unknown,\n): void {\n notifierContractSuite(label, make);\n describe(`state notifier contract: ${label}`, () => {\n it(\"declares state delivery\", async () => {\n const provider = await make();\n expect(isStateProvider(provider)).toBe(true);\n });\n\n it(\"binds a valid config to an adapter that can set state\", async () => {\n const provider = await make();\n const adapter = provider.create({ config: validConfig, secret: \"token\" });\n expect(\"setState\" in adapter && typeof adapter.setState === \"function\").toBe(true);\n });\n\n it(\"rejects an invalid config at create\", async () => {\n const provider = await make();\n expect(() => provider.create({ config: {}, secret: \"token\" })).toThrow();\n });\n });\n}\n"],"mappings":";;;;;;;;;;;;;AAcA,SAAgB,sBAAsB,OAAe,MAA6B;CAChF,SAAS,sBAAsB,eAAe;EAC5C,GAAG,kDAAkD,YAAY;GAC/D,MAAM,WAAW,MAAM,KAAK;GAC5B,OAAO,SAAS,SAAS,QAAQ,CAAC,CAAC,KAAK,UAAU;GAClD,OAAO,SAAS,SAAS,KAAK,MAAM,CAAC,CAAC,gBAAgB,CAAC;GACvD,OAAO,OAAO,SAAS,SAAS,OAAO,KAAK,CAAC,CAAC,KAAK,UAAU;EAC/D,CAAC;EAED,GAAG,iCAAiC,YAAY;GAC9C,MAAM,WAAW,MAAM,KAAK;GAC5B,OAAO,OAAO,SAAS,MAAM,CAAC,CAAC,KAAK,UAAU;EAChD,CAAC;EAED,GAAG,kDAAkD,YAAY;GAE/D,MAAM,UAAS,MADQ,KAAK,EAAA,CACJ,SAAS,OAAO,UAAU,CAAC,CAAC;GACpD,OAAO,OAAO,OAAO,OAAO,CAAC,CAAC,KAAK,SAAS;EAC9C,CAAC;CACH,CAAC;AACH;;;;;;AAOA,SAAgB,2BACd,OACA,MACA,aACM;CACN,sBAAsB,OAAO,IAAI;CACjC,SAAS,4BAA4B,eAAe;EAClD,GAAG,2BAA2B,YAAY;GACxC,MAAM,WAAW,MAAM,KAAK;GAC5B,OAAO,gBAAgB,QAAQ,CAAC,CAAC,CAAC,KAAK,IAAI;EAC7C,CAAC;EAED,GAAG,yDAAyD,YAAY;GAEtE,MAAM,WAAU,MADO,KAAK,EAAA,CACH,OAAO;IAAE,QAAQ;IAAa,QAAQ;GAAQ,CAAC;GACxE,OAAO,cAAc,WAAW,OAAO,QAAQ,aAAa,UAAU,CAAC,CAAC,KAAK,IAAI;EACnF,CAAC;EAED,GAAG,uCAAuC,YAAY;GACpD,MAAM,WAAW,MAAM,KAAK;GAC5B,aAAa,SAAS,OAAO;IAAE,QAAQ,CAAC;IAAG,QAAQ;GAAQ,CAAC,CAAC,CAAC,CAAC,QAAQ;EACzE,CAAC;CACH,CAAC;AACH"}
|
|
@@ -4,8 +4,22 @@ import { CaptureQueue } from "../adapter/capture-queue.mjs";
|
|
|
4
4
|
//#region src/test-helpers/queue-contract.d.ts
|
|
5
5
|
/** Build the adapter under test (sync or async factories both work). */
|
|
6
6
|
type QueueFactory = () => CaptureQueue | Promise<CaptureQueue>;
|
|
7
|
+
/** Options of {@link queueContractSuite}. */
|
|
8
|
+
interface QueueContractOptions {
|
|
9
|
+
/** Run the delivery cases; the factory must then return a `PollableCaptureQueue`. */
|
|
10
|
+
pollable?: PollableContractOptions;
|
|
11
|
+
}
|
|
12
|
+
/** What the harness tells the delivery cases about the queue it builds. */
|
|
13
|
+
interface PollableContractOptions {
|
|
14
|
+
/** Move the queue's clock forward by `ms` (fake timers or an injected clock). */
|
|
15
|
+
advance?: (ms: number) => void | Promise<void>;
|
|
16
|
+
/** Lease the factory grants per delivery; with `advance`, enables the redelivery cases. */
|
|
17
|
+
leaseMs?: number;
|
|
18
|
+
/** Retries the factory allows after the first delivery; enables the exhaustion case. */
|
|
19
|
+
retries?: number;
|
|
20
|
+
}
|
|
7
21
|
/** Run the queue contract against a factory. */
|
|
8
|
-
declare function queueContractSuite(label: string, make: QueueFactory): void;
|
|
22
|
+
declare function queueContractSuite(label: string, make: QueueFactory, options?: QueueContractOptions): void;
|
|
9
23
|
//#endregion
|
|
10
|
-
export { QueueFactory, queueContractSuite };
|
|
24
|
+
export { PollableContractOptions, QueueContractOptions, QueueFactory, queueContractSuite };
|
|
11
25
|
//# sourceMappingURL=queue-contract.d.mts.map
|
|
@@ -16,9 +16,21 @@ import { describe, expect, it } from "vitest";
|
|
|
16
16
|
* Behavioral cases (enqueue/status/active/recent) need a fake transport that
|
|
17
17
|
* answers realistically; structural cases (poll extension rule) run against
|
|
18
18
|
* any factory.
|
|
19
|
+
*
|
|
20
|
+
* Pollable queues opt in to the delivery cases (poll, ack, nack, extend, redelivery, at-most-one
|
|
21
|
+
* claim, cancel) with `options.pollable`. Time-dependent cases (delayed nack, lease expiry) run only
|
|
22
|
+
* when the harness can move the queue's clock (`advance`), and retry exhaustion only when it says
|
|
23
|
+
* how many retries the queue allows; queues without `extend`, `inspect` or `cancel` skip those
|
|
24
|
+
* checks, so the suite stays backward compatible.
|
|
19
25
|
*/
|
|
26
|
+
let sequence = 0;
|
|
27
|
+
/** A build id no other case (or earlier run on a shared backend) uses. */
|
|
28
|
+
function freshId(tag) {
|
|
29
|
+
sequence += 1;
|
|
30
|
+
return `b-contract-${tag}-${String(Date.now())}-${String(sequence)}`;
|
|
31
|
+
}
|
|
20
32
|
/** Run the queue contract against a factory. */
|
|
21
|
-
function queueContractSuite(label, make) {
|
|
33
|
+
function queueContractSuite(label, make, options = {}) {
|
|
22
34
|
describe(`queue contract: ${label}`, () => {
|
|
23
35
|
it("exposes capture-queue metadata", async () => {
|
|
24
36
|
const queue = await make();
|
|
@@ -56,6 +68,188 @@ function queueContractSuite(label, make) {
|
|
|
56
68
|
await queue.lifecycle.teardown();
|
|
57
69
|
await expect(queue.lifecycle.teardown()).resolves.toBeUndefined();
|
|
58
70
|
});
|
|
71
|
+
if (options.pollable !== void 0) pollableCases(make, options.pollable);
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
async function makePollable(make) {
|
|
75
|
+
const queue = await make();
|
|
76
|
+
expect(typeof queue.poll).toBe("function");
|
|
77
|
+
return queue;
|
|
78
|
+
}
|
|
79
|
+
/** Poll until the job for `buildId` comes up (other cases' leftovers on a shared backend are skipped). */
|
|
80
|
+
async function pollFor(queue, buildId, tries = 20) {
|
|
81
|
+
for (let attempt = 0; attempt < tries; attempt += 1) {
|
|
82
|
+
const job = await queue.poll();
|
|
83
|
+
if (job === null || job.buildId === buildId) return job;
|
|
84
|
+
await queue.ack(job);
|
|
85
|
+
}
|
|
86
|
+
return null;
|
|
87
|
+
}
|
|
88
|
+
function pollableCases(make, options) {
|
|
89
|
+
describe("delivery", () => {
|
|
90
|
+
deliveryCases(make);
|
|
91
|
+
retryCases(make, options);
|
|
92
|
+
if (options.advance !== void 0 && options.leaseMs !== void 0) leaseCases(make, options.advance, options.leaseMs);
|
|
93
|
+
cancelCases(make);
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
function deliveryCases(make) {
|
|
97
|
+
it("delivers an enqueued job once, with its fields, as a first attempt", async () => {
|
|
98
|
+
const queue = await makePollable(make);
|
|
99
|
+
const buildId = freshId("deliver");
|
|
100
|
+
await queue.enqueue({
|
|
101
|
+
buildId,
|
|
102
|
+
reqId: "req-1",
|
|
103
|
+
traceparent: "00-abc-def-01",
|
|
104
|
+
shard: "s-1"
|
|
105
|
+
});
|
|
106
|
+
const job = await pollFor(queue, buildId);
|
|
107
|
+
expect(job).toMatchObject({
|
|
108
|
+
buildId,
|
|
109
|
+
reqId: "req-1",
|
|
110
|
+
traceparent: "00-abc-def-01",
|
|
111
|
+
shard: "s-1"
|
|
112
|
+
});
|
|
113
|
+
expect(job?.attempts ?? 0).toBe(0);
|
|
114
|
+
expect(await pollFor(queue, buildId)).toBeNull();
|
|
115
|
+
await queue.ack(job);
|
|
116
|
+
});
|
|
117
|
+
it("lets at most one of many concurrent polls claim a job", async () => {
|
|
118
|
+
const queue = await makePollable(make);
|
|
119
|
+
const buildId = freshId("race");
|
|
120
|
+
await queue.enqueue({ buildId });
|
|
121
|
+
const results = await Promise.all(Array.from({ length: 6 }, async () => await queue.poll()));
|
|
122
|
+
const claimed = results.filter((job) => job?.buildId === buildId);
|
|
123
|
+
expect(claimed).toHaveLength(1);
|
|
124
|
+
await Promise.all(results.flatMap((job) => job === null ? [] : [queue.ack(job)]));
|
|
125
|
+
});
|
|
126
|
+
it("does not redeliver an acked job and reports it completed", async () => {
|
|
127
|
+
const queue = await makePollable(make);
|
|
128
|
+
const buildId = freshId("ack");
|
|
129
|
+
await queue.enqueue({ buildId });
|
|
130
|
+
const job = await pollFor(queue, buildId);
|
|
131
|
+
await queue.ack(job);
|
|
132
|
+
expect(await pollFor(queue, buildId)).toBeNull();
|
|
133
|
+
expect((await queue.status(buildId))?.status).toBe("completed");
|
|
134
|
+
});
|
|
135
|
+
it("renews the holder's lease while it owns the job", async () => {
|
|
136
|
+
const queue = await makePollable(make);
|
|
137
|
+
const buildId = freshId("extend");
|
|
138
|
+
await queue.enqueue({ buildId });
|
|
139
|
+
const job = await pollFor(queue, buildId);
|
|
140
|
+
if (queue.extend !== void 0) expect(await queue.extend(job)).toBe("ok");
|
|
141
|
+
if (queue.inspect !== void 0) expect(await queue.inspect(job)).toBe("ok");
|
|
142
|
+
await queue.ack(job);
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
function retryCases(make, options) {
|
|
146
|
+
it("redelivers a nacked job as the next attempt", async () => {
|
|
147
|
+
const queue = await makePollable(make);
|
|
148
|
+
const buildId = freshId("nack");
|
|
149
|
+
await queue.enqueue({ buildId });
|
|
150
|
+
const first = await pollFor(queue, buildId);
|
|
151
|
+
await queue.nack(first, {
|
|
152
|
+
requeue: true,
|
|
153
|
+
error: "boom"
|
|
154
|
+
});
|
|
155
|
+
const second = await pollFor(queue, buildId);
|
|
156
|
+
expect(second?.buildId).toBe(buildId);
|
|
157
|
+
expect(second?.attempts ?? 0).toBeGreaterThan(first?.attempts ?? 0);
|
|
158
|
+
await queue.ack(second);
|
|
159
|
+
});
|
|
160
|
+
it("drops a job nacked with requeue: false and reports it failed", async () => {
|
|
161
|
+
const queue = await makePollable(make);
|
|
162
|
+
const buildId = freshId("drop");
|
|
163
|
+
await queue.enqueue({ buildId });
|
|
164
|
+
const job = await pollFor(queue, buildId);
|
|
165
|
+
await queue.nack(job, {
|
|
166
|
+
requeue: false,
|
|
167
|
+
error: "fatal"
|
|
168
|
+
});
|
|
169
|
+
expect(await pollFor(queue, buildId)).toBeNull();
|
|
170
|
+
const entry = await queue.status(buildId);
|
|
171
|
+
expect(entry?.status).toBe("failed");
|
|
172
|
+
expect(entry?.error).toBe("fatal");
|
|
173
|
+
});
|
|
174
|
+
if (options.advance !== void 0) {
|
|
175
|
+
const { advance } = options;
|
|
176
|
+
it("hides a job nacked with a delay until the delay passes", async () => {
|
|
177
|
+
const queue = await makePollable(make);
|
|
178
|
+
const buildId = freshId("delay");
|
|
179
|
+
await queue.enqueue({ buildId });
|
|
180
|
+
const job = await pollFor(queue, buildId);
|
|
181
|
+
await queue.nack(job, {
|
|
182
|
+
requeue: true,
|
|
183
|
+
delayMs: 1e4
|
|
184
|
+
});
|
|
185
|
+
expect(await pollFor(queue, buildId)).toBeNull();
|
|
186
|
+
await advance(10001);
|
|
187
|
+
const again = await pollFor(queue, buildId);
|
|
188
|
+
expect(again?.buildId).toBe(buildId);
|
|
189
|
+
await queue.ack(again);
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
if (options.retries !== void 0) {
|
|
193
|
+
const { retries } = options;
|
|
194
|
+
it("fails a job once its retries are spent", async () => {
|
|
195
|
+
const queue = await makePollable(make);
|
|
196
|
+
const buildId = freshId("exhaust");
|
|
197
|
+
await queue.enqueue({ buildId });
|
|
198
|
+
for (let attempt = 0; attempt <= retries; attempt += 1) {
|
|
199
|
+
const job = await pollFor(queue, buildId);
|
|
200
|
+
expect(job?.buildId).toBe(buildId);
|
|
201
|
+
await queue.nack(job, {
|
|
202
|
+
requeue: true,
|
|
203
|
+
error: `attempt ${String(attempt)}`
|
|
204
|
+
});
|
|
205
|
+
}
|
|
206
|
+
expect(await pollFor(queue, buildId)).toBeNull();
|
|
207
|
+
expect((await queue.status(buildId))?.status).toBe("failed");
|
|
208
|
+
});
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
function leaseCases(make, advance, leaseMs) {
|
|
212
|
+
it("redelivers a job whose lease expired, and the stale holder learns it lost", async () => {
|
|
213
|
+
const queue = await makePollable(make);
|
|
214
|
+
const buildId = freshId("expire");
|
|
215
|
+
await queue.enqueue({ buildId });
|
|
216
|
+
const stale = await pollFor(queue, buildId);
|
|
217
|
+
expect(await pollFor(queue, buildId)).toBeNull();
|
|
218
|
+
await advance(leaseMs + 1);
|
|
219
|
+
const fresh = await pollFor(queue, buildId);
|
|
220
|
+
expect(fresh?.buildId).toBe(buildId);
|
|
221
|
+
expect(fresh?.attempts ?? 0).toBeGreaterThan(stale?.attempts ?? 0);
|
|
222
|
+
if (queue.extend !== void 0) {
|
|
223
|
+
expect(await queue.extend(stale)).toBe("lost");
|
|
224
|
+
expect(await queue.extend(fresh)).toBe("ok");
|
|
225
|
+
}
|
|
226
|
+
await queue.ack(fresh);
|
|
227
|
+
});
|
|
228
|
+
}
|
|
229
|
+
function cancelCases(make) {
|
|
230
|
+
it("cancels a queued job at once and flags a running one", async () => {
|
|
231
|
+
const queue = await makePollable(make);
|
|
232
|
+
if (queue.cancel === void 0) {
|
|
233
|
+
expect(queue.cancel).toBeUndefined();
|
|
234
|
+
return;
|
|
235
|
+
}
|
|
236
|
+
const queued = freshId("cancel-queued");
|
|
237
|
+
const running = freshId("cancel-running");
|
|
238
|
+
await queue.enqueue({ buildId: queued });
|
|
239
|
+
expect(await queue.cancel(queued)).toBe(true);
|
|
240
|
+
expect((await queue.status(queued))?.status).toBe("cancelled");
|
|
241
|
+
await queue.enqueue({ buildId: running });
|
|
242
|
+
const job = await pollFor(queue, running);
|
|
243
|
+
expect(job?.buildId).toBe(running);
|
|
244
|
+
expect(await queue.cancel(running)).toBe(true);
|
|
245
|
+
const seen = await (queue.inspect ?? queue.extend)?.(job);
|
|
246
|
+
expect(seen ?? "cancelled").toBe("cancelled");
|
|
247
|
+
await queue.nack(job, {
|
|
248
|
+
requeue: false,
|
|
249
|
+
error: "cancelled"
|
|
250
|
+
});
|
|
251
|
+
expect((await queue.status(running))?.status).toBe("cancelled");
|
|
252
|
+
expect(await queue.cancel("b-contract-unknown")).toBe(false);
|
|
59
253
|
});
|
|
60
254
|
}
|
|
61
255
|
//#endregion
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"queue-contract.mjs","names":[],"sources":["../../src/test-helpers/queue-contract.ts"],"sourcesContent":["/**\n * Published queue contract suite for first- and third-party adapters.\n *\n * A package proves conformance in one line from its own vitest file:\n *\n * ```ts\n * import { queueContractSuite } from \"@storyshelf/core/test-helpers\";\n * queueContractSuite(\"sqs\", () => createSqsCaptureQueue({ queueUrl, client: fake }));\n * ```\n *\n * Behavioral cases (enqueue/status/active/recent) need a fake transport that\n * answers realistically; structural cases (poll extension rule) run against\n * any factory.\n */\nimport { describe, expect, it } from \"vitest\";\nimport type { CaptureQueue } from \"../adapters/capture-queue.ts\";\n\n/** Build the adapter under test (sync or async factories both work). */\nexport type QueueFactory = () => CaptureQueue | Promise<CaptureQueue>;\n\n/** Run the queue contract against a factory. */\nexport function queueContractSuite(label: string, make: QueueFactory): void {\n describe(`queue contract: ${label}`, () => {\n it(\"exposes capture-queue metadata\", async () => {\n const queue = await make();\n expect(queue.metadata.category).toBe(\"capture-queue\");\n expect(queue.metadata.kind.length).toBeGreaterThan(0);\n });\n\n it(\"keeps the poll extension all-or-nothing\", async () => {\n const queue = await make();\n const record = queue as unknown as Record<string, unknown>;\n const present = [\"poll\", \"ack\", \"nack\"].filter((method) => record[method] !== undefined);\n expect([0, 3]).toContain(present.length);\n for (const method of present) {\n expect(typeof record[method]).toBe(\"function\");\n }\n });\n\n it(\"tracks an enqueued build through status/active/recent\", async () => {\n const queue = await make();\n await queue.enqueue({ buildId: \"b-contract-1\" });\n const entry = await queue.status(\"b-contract-1\");\n expect(entry?.buildId).toBe(\"b-contract-1\");\n // Remote transports report \"queued\" until a worker polls; in-process\n // queues may already report \"running\".\n expect([\"queued\", \"running\"]).toContain(entry?.status);\n expect((await queue.active()).map((job) => job.buildId)).toContain(\"b-contract-1\");\n expect((await queue.recent(10)).map((job) => job.buildId)).toContain(\"b-contract-1\");\n expect(await queue.status(\"b-missing\")).toBeNull();\n });\n\n it(\"keeps lifecycle idempotent when present\", async () => {\n const queue = await make();\n if (queue.lifecycle === undefined) {\n expect(queue.lifecycle).toBeUndefined();\n return;\n }\n await queue.lifecycle.setup({} as never);\n await queue.lifecycle.setup({} as never);\n await queue.lifecycle.teardown();\n await expect(queue.lifecycle.teardown()).resolves.toBeUndefined();\n });\n });\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAqBA,SAAgB,mBAAmB,OAAe,MAA0B;CAC1E,SAAS,mBAAmB,eAAe;EACzC,GAAG,kCAAkC,YAAY;GAC/C,MAAM,QAAQ,MAAM,KAAK;GACzB,OAAO,MAAM,SAAS,QAAQ,CAAC,CAAC,KAAK,eAAe;GACpD,OAAO,MAAM,SAAS,KAAK,MAAM,CAAC,CAAC,gBAAgB,CAAC;EACtD,CAAC;EAED,GAAG,2CAA2C,YAAY;GAExD,MAAM,SAAS,MADK,KAAK;GAEzB,MAAM,UAAU;IAAC;IAAQ;IAAO;GAAM,CAAC,CAAC,QAAQ,WAAW,OAAO,YAAY,KAAA,CAAS;GACvF,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,UAAU,QAAQ,MAAM;GACvC,KAAK,MAAM,UAAU,SACnB,OAAO,OAAO,OAAO,OAAO,CAAC,CAAC,KAAK,UAAU;EAEjD,CAAC;EAED,GAAG,yDAAyD,YAAY;GACtE,MAAM,QAAQ,MAAM,KAAK;GACzB,MAAM,MAAM,QAAQ,EAAE,SAAS,eAAe,CAAC;GAC/C,MAAM,QAAQ,MAAM,MAAM,OAAO,cAAc;GAC/C,OAAO,OAAO,OAAO,CAAC,CAAC,KAAK,cAAc;GAG1C,OAAO,CAAC,UAAU,SAAS,CAAC,CAAC,CAAC,UAAU,OAAO,MAAM;GACrD,QAAQ,MAAM,MAAM,OAAO,EAAA,CAAG,KAAK,QAAQ,IAAI,OAAO,CAAC,CAAC,CAAC,UAAU,cAAc;GACjF,QAAQ,MAAM,MAAM,OAAO,EAAE,EAAA,CAAG,KAAK,QAAQ,IAAI,OAAO,CAAC,CAAC,CAAC,UAAU,cAAc;GACnF,OAAO,MAAM,MAAM,OAAO,WAAW,CAAC,CAAC,CAAC,SAAS;EACnD,CAAC;EAED,GAAG,2CAA2C,YAAY;GACxD,MAAM,QAAQ,MAAM,KAAK;GACzB,IAAI,MAAM,cAAc,KAAA,GAAW;IACjC,OAAO,MAAM,SAAS,CAAC,CAAC,cAAc;IACtC;GACF;GACA,MAAM,MAAM,UAAU,MAAM,CAAC,CAAU;GACvC,MAAM,MAAM,UAAU,MAAM,CAAC,CAAU;GACvC,MAAM,MAAM,UAAU,SAAS;GAC/B,MAAM,OAAO,MAAM,UAAU,SAAS,CAAC,CAAC,CAAC,SAAS,cAAc;EAClE,CAAC;CACH,CAAC;AACH"}
|
|
1
|
+
{"version":3,"file":"queue-contract.mjs","names":[],"sources":["../../src/test-helpers/queue-contract.ts"],"sourcesContent":["/**\n * Published queue contract suite for first- and third-party adapters.\n *\n * A package proves conformance in one line from its own vitest file:\n *\n * ```ts\n * import { queueContractSuite } from \"@storyshelf/core/test-helpers\";\n * queueContractSuite(\"sqs\", () => createSqsCaptureQueue({ queueUrl, client: fake }));\n * ```\n *\n * Behavioral cases (enqueue/status/active/recent) need a fake transport that\n * answers realistically; structural cases (poll extension rule) run against\n * any factory.\n *\n * Pollable queues opt in to the delivery cases (poll, ack, nack, extend, redelivery, at-most-one\n * claim, cancel) with `options.pollable`. Time-dependent cases (delayed nack, lease expiry) run only\n * when the harness can move the queue's clock (`advance`), and retry exhaustion only when it says\n * how many retries the queue allows; queues without `extend`, `inspect` or `cancel` skip those\n * checks, so the suite stays backward compatible.\n */\nimport { describe, expect, it } from \"vitest\";\nimport type { CaptureQueue, PollableCaptureQueue, PollableJob } from \"../adapters/capture-queue.ts\";\n\n/** Build the adapter under test (sync or async factories both work). */\nexport type QueueFactory = () => CaptureQueue | Promise<CaptureQueue>;\n\n/** Options of {@link queueContractSuite}. */\nexport interface QueueContractOptions {\n /** Run the delivery cases; the factory must then return a `PollableCaptureQueue`. */\n pollable?: PollableContractOptions;\n}\n\n/** What the harness tells the delivery cases about the queue it builds. */\nexport interface PollableContractOptions {\n /** Move the queue's clock forward by `ms` (fake timers or an injected clock). */\n advance?: (ms: number) => void | Promise<void>;\n /** Lease the factory grants per delivery; with `advance`, enables the redelivery cases. */\n leaseMs?: number;\n /** Retries the factory allows after the first delivery; enables the exhaustion case. */\n retries?: number;\n}\n\nlet sequence = 0;\n\n/** A build id no other case (or earlier run on a shared backend) uses. */\nfunction freshId(tag: string): string {\n sequence += 1;\n return `b-contract-${tag}-${String(Date.now())}-${String(sequence)}`;\n}\n\n/** Run the queue contract against a factory. */\nexport function queueContractSuite(\n label: string,\n make: QueueFactory,\n options: QueueContractOptions = {},\n): void {\n describe(`queue contract: ${label}`, () => {\n it(\"exposes capture-queue metadata\", async () => {\n const queue = await make();\n expect(queue.metadata.category).toBe(\"capture-queue\");\n expect(queue.metadata.kind.length).toBeGreaterThan(0);\n });\n\n it(\"keeps the poll extension all-or-nothing\", async () => {\n const queue = await make();\n const record = queue as unknown as Record<string, unknown>;\n const present = [\"poll\", \"ack\", \"nack\"].filter((method) => record[method] !== undefined);\n expect([0, 3]).toContain(present.length);\n for (const method of present) {\n expect(typeof record[method]).toBe(\"function\");\n }\n });\n\n it(\"tracks an enqueued build through status/active/recent\", async () => {\n const queue = await make();\n await queue.enqueue({ buildId: \"b-contract-1\" });\n const entry = await queue.status(\"b-contract-1\");\n expect(entry?.buildId).toBe(\"b-contract-1\");\n // Remote transports report \"queued\" until a worker polls; in-process\n // queues may already report \"running\".\n expect([\"queued\", \"running\"]).toContain(entry?.status);\n expect((await queue.active()).map((job) => job.buildId)).toContain(\"b-contract-1\");\n expect((await queue.recent(10)).map((job) => job.buildId)).toContain(\"b-contract-1\");\n expect(await queue.status(\"b-missing\")).toBeNull();\n });\n\n it(\"keeps lifecycle idempotent when present\", async () => {\n const queue = await make();\n if (queue.lifecycle === undefined) {\n expect(queue.lifecycle).toBeUndefined();\n return;\n }\n await queue.lifecycle.setup({} as never);\n await queue.lifecycle.setup({} as never);\n await queue.lifecycle.teardown();\n await expect(queue.lifecycle.teardown()).resolves.toBeUndefined();\n });\n\n if (options.pollable !== undefined) {\n pollableCases(make, options.pollable);\n }\n });\n}\n\nasync function makePollable(make: QueueFactory): Promise<PollableCaptureQueue> {\n const queue = (await make()) as PollableCaptureQueue;\n expect(typeof queue.poll).toBe(\"function\");\n return queue;\n}\n\n/** Poll until the job for `buildId` comes up (other cases' leftovers on a shared backend are skipped). */\nasync function pollFor(\n queue: PollableCaptureQueue,\n buildId: string,\n tries = 20,\n): Promise<PollableJob | null> {\n for (let attempt = 0; attempt < tries; attempt += 1) {\n // oxlint-disable-next-line eslint/no-await-in-loop -- sequential polls are the point\n const job = await queue.poll();\n if (job === null || job.buildId === buildId) {\n return job;\n }\n // oxlint-disable-next-line eslint/no-await-in-loop -- settle someone else's job and keep looking\n await queue.ack(job);\n }\n return null;\n}\n\nfunction pollableCases(make: QueueFactory, options: PollableContractOptions): void {\n describe(\"delivery\", () => {\n deliveryCases(make);\n retryCases(make, options);\n if (options.advance !== undefined && options.leaseMs !== undefined) {\n leaseCases(make, options.advance, options.leaseMs);\n }\n cancelCases(make);\n });\n}\n\nfunction deliveryCases(make: QueueFactory): void {\n it(\"delivers an enqueued job once, with its fields, as a first attempt\", async () => {\n const queue = await makePollable(make);\n const buildId = freshId(\"deliver\");\n await queue.enqueue({ buildId, reqId: \"req-1\", traceparent: \"00-abc-def-01\", shard: \"s-1\" });\n const job = await pollFor(queue, buildId);\n expect(job).toMatchObject({\n buildId,\n reqId: \"req-1\",\n traceparent: \"00-abc-def-01\",\n shard: \"s-1\",\n });\n expect(job?.attempts ?? 0).toBe(0);\n expect(await pollFor(queue, buildId)).toBeNull();\n await queue.ack(job!);\n });\n\n it(\"lets at most one of many concurrent polls claim a job\", async () => {\n const queue = await makePollable(make);\n const buildId = freshId(\"race\");\n await queue.enqueue({ buildId });\n const results = await Promise.all(Array.from({ length: 6 }, async () => await queue.poll()));\n const claimed = results.filter((job) => job?.buildId === buildId);\n expect(claimed).toHaveLength(1);\n await Promise.all(results.flatMap((job) => (job === null ? [] : [queue.ack(job)])));\n });\n\n it(\"does not redeliver an acked job and reports it completed\", async () => {\n const queue = await makePollable(make);\n const buildId = freshId(\"ack\");\n await queue.enqueue({ buildId });\n const job = await pollFor(queue, buildId);\n await queue.ack(job!);\n expect(await pollFor(queue, buildId)).toBeNull();\n expect((await queue.status(buildId))?.status).toBe(\"completed\");\n });\n\n it(\"renews the holder's lease while it owns the job\", async () => {\n const queue = await makePollable(make);\n const buildId = freshId(\"extend\");\n await queue.enqueue({ buildId });\n const job = await pollFor(queue, buildId);\n if (queue.extend !== undefined) {\n expect(await queue.extend(job!)).toBe(\"ok\");\n }\n if (queue.inspect !== undefined) {\n expect(await queue.inspect(job!)).toBe(\"ok\");\n }\n await queue.ack(job!);\n });\n}\n\nfunction retryCases(make: QueueFactory, options: PollableContractOptions): void {\n it(\"redelivers a nacked job as the next attempt\", async () => {\n const queue = await makePollable(make);\n const buildId = freshId(\"nack\");\n await queue.enqueue({ buildId });\n const first = await pollFor(queue, buildId);\n await queue.nack(first!, { requeue: true, error: \"boom\" });\n const second = await pollFor(queue, buildId);\n expect(second?.buildId).toBe(buildId);\n expect(second?.attempts ?? 0).toBeGreaterThan(first?.attempts ?? 0);\n await queue.ack(second!);\n });\n\n it(\"drops a job nacked with requeue: false and reports it failed\", async () => {\n const queue = await makePollable(make);\n const buildId = freshId(\"drop\");\n await queue.enqueue({ buildId });\n const job = await pollFor(queue, buildId);\n await queue.nack(job!, { requeue: false, error: \"fatal\" });\n expect(await pollFor(queue, buildId)).toBeNull();\n const entry = await queue.status(buildId);\n expect(entry?.status).toBe(\"failed\");\n expect(entry?.error).toBe(\"fatal\");\n });\n\n if (options.advance !== undefined) {\n const { advance } = options;\n it(\"hides a job nacked with a delay until the delay passes\", async () => {\n const queue = await makePollable(make);\n const buildId = freshId(\"delay\");\n await queue.enqueue({ buildId });\n const job = await pollFor(queue, buildId);\n await queue.nack(job!, { requeue: true, delayMs: 10_000 });\n expect(await pollFor(queue, buildId)).toBeNull();\n await advance(10_001);\n const again = await pollFor(queue, buildId);\n expect(again?.buildId).toBe(buildId);\n await queue.ack(again!);\n });\n }\n\n if (options.retries !== undefined) {\n const { retries } = options;\n it(\"fails a job once its retries are spent\", async () => {\n const queue = await makePollable(make);\n const buildId = freshId(\"exhaust\");\n await queue.enqueue({ buildId });\n for (let attempt = 0; attempt <= retries; attempt += 1) {\n // oxlint-disable-next-line eslint/no-await-in-loop -- attempts are sequential\n const job = await pollFor(queue, buildId);\n expect(job?.buildId).toBe(buildId);\n // oxlint-disable-next-line eslint/no-await-in-loop -- see above\n await queue.nack(job!, { requeue: true, error: `attempt ${String(attempt)}` });\n }\n expect(await pollFor(queue, buildId)).toBeNull();\n expect((await queue.status(buildId))?.status).toBe(\"failed\");\n });\n }\n}\n\nfunction leaseCases(\n make: QueueFactory,\n advance: (ms: number) => void | Promise<void>,\n leaseMs: number,\n): void {\n it(\"redelivers a job whose lease expired, and the stale holder learns it lost\", async () => {\n const queue = await makePollable(make);\n const buildId = freshId(\"expire\");\n await queue.enqueue({ buildId });\n const stale = await pollFor(queue, buildId);\n expect(await pollFor(queue, buildId)).toBeNull();\n await advance(leaseMs + 1);\n const fresh = await pollFor(queue, buildId);\n expect(fresh?.buildId).toBe(buildId);\n expect(fresh?.attempts ?? 0).toBeGreaterThan(stale?.attempts ?? 0);\n if (queue.extend !== undefined) {\n expect(await queue.extend(stale!)).toBe(\"lost\");\n expect(await queue.extend(fresh!)).toBe(\"ok\");\n }\n await queue.ack(fresh!);\n });\n}\n\nfunction cancelCases(make: QueueFactory): void {\n it(\"cancels a queued job at once and flags a running one\", async () => {\n const queue = await makePollable(make);\n if (queue.cancel === undefined) {\n expect(queue.cancel).toBeUndefined();\n return;\n }\n const queued = freshId(\"cancel-queued\");\n const running = freshId(\"cancel-running\");\n await queue.enqueue({ buildId: queued });\n expect(await queue.cancel(queued)).toBe(true);\n expect((await queue.status(queued))?.status).toBe(\"cancelled\");\n await queue.enqueue({ buildId: running });\n const job = await pollFor(queue, running);\n expect(job?.buildId).toBe(running);\n expect(await queue.cancel(running)).toBe(true);\n const seen = await (queue.inspect ?? queue.extend)?.(job!);\n expect(seen ?? \"cancelled\").toBe(\"cancelled\");\n await queue.nack(job!, { requeue: false, error: \"cancelled\" });\n expect((await queue.status(running))?.status).toBe(\"cancelled\");\n expect(await queue.cancel(\"b-contract-unknown\")).toBe(false);\n });\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import __tsdown_shims_path from 'node:path';
|
|
2
|
+
import __tsdown_shims_url from 'node:url';
|
|
3
|
+
import { DatabaseAdapter } from "../adapter/database.mjs";
|
|
4
|
+
//#region src/test-helpers/queue-multi-instance.d.ts
|
|
5
|
+
/** A set-up database the instances of one case share. */
|
|
6
|
+
type SharedDatabaseFactory = () => DatabaseAdapter | Promise<DatabaseAdapter>;
|
|
7
|
+
/** Options of {@link databaseQueueMultiInstanceSuite}. */
|
|
8
|
+
interface MultiInstanceOptions {
|
|
9
|
+
/** Queue instances sharing the database (default 4). */
|
|
10
|
+
instances?: number;
|
|
11
|
+
/** Jobs in the exactly-once case (default 24). */
|
|
12
|
+
jobs?: number;
|
|
13
|
+
/** Per-case timeout in ms, for slow remote databases (default vitest's). */
|
|
14
|
+
timeoutMs?: number;
|
|
15
|
+
}
|
|
16
|
+
/** Run the multi-instance suite against databases from `makeDb`. */
|
|
17
|
+
declare function databaseQueueMultiInstanceSuite(label: string, makeDb: SharedDatabaseFactory, options?: MultiInstanceOptions): void;
|
|
18
|
+
//#endregion
|
|
19
|
+
export { MultiInstanceOptions, SharedDatabaseFactory, databaseQueueMultiInstanceSuite };
|
|
20
|
+
//# sourceMappingURL=queue-multi-instance.d.mts.map
|