(
fixtures: Fixture[],
options?: MockServerOptions,
mounts?: Array<{ path: string; handler: Mountable }>,
serviceFixtures?: ServiceFixtures,
)
| 1108 | // (e.g. LLMock) may mutate it after the server starts and changes will |
| 1109 | // be visible immediately. This is intentional — do not copy the array. |
| 1110 | export async function createServer( |
| 1111 | fixtures: Fixture[], |
| 1112 | options?: MockServerOptions, |
| 1113 | mounts?: Array<{ path: string; handler: Mountable }>, |
| 1114 | serviceFixtures?: ServiceFixtures, |
| 1115 | ): Promise<ServerInstance> { |
| 1116 | const host = options?.host ?? "127.0.0.1"; |
| 1117 | const port = options?.port ?? 0; |
| 1118 | const logger = new Logger(options?.logLevel ?? "silent"); |
| 1119 | const registry = options?.metrics ? createMetricsRegistry() : undefined; |
| 1120 | const serverOptions = options ?? {}; |
| 1121 | const defaults = { |
| 1122 | latency: serverOptions.latency ?? 0, |
| 1123 | chunkSize: Math.max(1, serverOptions.chunkSize ?? DEFAULT_CHUNK_SIZE), |
| 1124 | replaySpeed: serverOptions.replaySpeed ?? 1.0, |
| 1125 | logger, |
| 1126 | get chaos() { |
| 1127 | return serverOptions.chaos; |
| 1128 | }, |
| 1129 | registry, |
| 1130 | get record() { |
| 1131 | return serverOptions.record; |
| 1132 | }, |
| 1133 | get strict() { |
| 1134 | return serverOptions.strict; |
| 1135 | }, |
| 1136 | get requestTransform() { |
| 1137 | return serverOptions.requestTransform; |
| 1138 | }, |
| 1139 | get falQueue() { |
| 1140 | return serverOptions.falQueue; |
| 1141 | }, |
| 1142 | get openRouterVideo() { |
| 1143 | return serverOptions.openRouterVideo; |
| 1144 | }, |
| 1145 | get veoVideo() { |
| 1146 | return serverOptions.veoVideo; |
| 1147 | }, |
| 1148 | get grokVideo() { |
| 1149 | return serverOptions.grokVideo; |
| 1150 | }, |
| 1151 | }; |
| 1152 | |
| 1153 | // Validate chaos config rates |
| 1154 | if (options?.chaos) { |
| 1155 | const chaosRates = [ |
| 1156 | { name: "dropRate", value: options.chaos.dropRate }, |
| 1157 | { name: "malformedRate", value: options.chaos.malformedRate }, |
| 1158 | { name: "disconnectRate", value: options.chaos.disconnectRate }, |
| 1159 | ]; |
| 1160 | for (const { name, value } of chaosRates) { |
| 1161 | if (value !== undefined && (value < 0 || value > 1)) { |
| 1162 | logger.warn(`Chaos ${name} (${value}) is outside 0-1 range — will be clamped at runtime`); |
| 1163 | } |
| 1164 | } |
| 1165 | } |
| 1166 | |
| 1167 | // Validate poll-progression thresholds (resolveProgression treats |
searching dependent graphs…