/** * Bridge between the Recipe layer and `scenarioLoad`. Lets a team * load-test their *entire verified-recipe library* without rewriting * each recipe as an imperative `defineScenario`. * * Two public entry points: * * - `recipeStoreScenario({ store, ... })` — builds a single * `Scenario` that, each iteration, picks one verified recipe * from the store and replays it (composition + templating * respected). * * - `scenarioLoadFromStore({ baseUrl, store, workers, ... })` — * thin wrapper that calls `scenarioLoad` with the scenario above. * * Selection strategies (`selection`): * - `"uniform"` (default) — equal probability across candidates * - `"by-success-rate"` — weighted by `successCount / total`, with * a small floor so brand-new candidates aren't starved * - custom: `(candidates, rng) => ActionRecipe` for full control * * Per-worker / per-iteration variables flow through `vars`: * `vars: (workerIndex, iteration) => ({ email: ... })` */ import { type Scenario } from "../load/index.js"; import type { DurationInput, ScenarioLoadOptions, ScenarioLoadResult, ThinkTime } from "../load/index.js"; import { type RecipeRunStats } from "./recipe-driver.js"; import type { RecipeStore } from "./store.js"; import type { RecipeVars } from "./templating.js"; import type { ActionRecipe } from "./types.js"; export type RecipeSelection = "uniform" | "by-success-rate" | ((candidates: ReadonlyArray, ctx: SelectionContext) => ActionRecipe); export interface SelectionContext { workerIndex: number; iteration: number; } export interface RecipeStoreScenarioOptions { store: RecipeStore; /** * Filter applied on top of `status: "verified"`. Default: every * verified recipe is eligible. */ filter?: (recipe: ActionRecipe) => boolean; /** Default: `"uniform"`. */ selection?: RecipeSelection; /** * When true (default), each recipe's `requires` chain is resolved * automatically (matching `recipeDriver`'s default semantics). */ chainRequires?: boolean; /** * Variables passed to every replay. A function form receives the * worker index + iteration so e.g. each iteration can use a fresh * email or user fixture. */ vars?: RecipeVars | ((ctx: SelectionContext) => RecipeVars); /** Scenario name shown in `LoadReport.scenarios[]`. Default: `"recipe-mix"`. */ scenarioName?: string; /** Optional per-iteration think time. Forwarded to `defineScenario`. */ thinkTime?: ThinkTime; } /** * Result shape returned by `recipeStoreScenarioWithStats`. The * scenario is what scenarioLoad wants; `getRunStats()` is the * issue #92 observability hook for callers that want to know "which * recipes fired during this load run." * * `recipeStoreScenario` (no `WithStats`) is retained as the legacy * scenario-only entry point. */ export interface RecipeStoreScenarioBundle { scenario: Scenario; getRunStats(): RecipeRunStats[]; } /** * Builds a single `Scenario` whose only step picks a verified recipe * from the store and replays it. Designed to be passed to * `scenarioLoad({ scenarios: [{ scenario, workers }] })`. */ export declare function recipeStoreScenario(opts: RecipeStoreScenarioOptions): Scenario; /** * Same as `recipeStoreScenario` but also exposes a `getRunStats()` * accessor that returns per-recipe firing counts accumulated over * the bundle's lifetime. Pair with `scenarioLoad` directly when you * need stats; `scenarioLoadFromStore` does the wiring for you. */ export declare function recipeStoreScenarioWithStats(opts: RecipeStoreScenarioOptions): RecipeStoreScenarioBundle; export interface ScenarioLoadFromStoreOptions extends RecipeStoreScenarioOptions { baseUrl: string; workers: number; duration?: DurationInput; rampUp?: DurationInput; faultInjection?: ScenarioLoadOptions["faultInjection"]; runtimeFaults?: ScenarioLoadOptions["runtimeFaults"]; invariants?: ScenarioLoadOptions["invariants"]; headless?: boolean; timelineBucketMs?: number; maxIterationsPerWorker?: number; viewport?: ScenarioLoadOptions["viewport"]; storageState?: string | ((workerIndex: number) => string | undefined); } export interface ScenarioLoadFromStoreResult extends ScenarioLoadResult { /** Per-recipe firing counts for the run (issue #92). */ recipes: RecipeRunStats[]; } /** * Top-level convenience: builds the scenario from the store and runs * `scenarioLoad` with the given concurrency / duration. Returns the * usual `ScenarioLoadResult` — chaos / SLO / timeline / fault stats * all work as normal — plus a per-recipe firing summary (issue #92). */ export declare function scenarioLoadFromStore(opts: ScenarioLoadFromStoreOptions): Promise; //# sourceMappingURL=load-bridge.d.ts.map