@systemfsoftware/stryker-js 12.0.0 → 12.1.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.
@@ -1,4 +1,4 @@
1
- import { A as Plugin_exports, D as VerdictReached, E as SkippedReported, F as ErrorText_exports, I as Format_exports, L as Instrument_exports, M as Reporter_exports, N as TestRunner_exports, O as Checker_exports, P as Trace_exports$1, R as Mutant_exports, _ as PluginsReported, b as RunFailed$1, c as Heartbeat, f as OutputMode, i as FormatRegistryResolved, j as Report_exports, k as Options_exports, l as HelpRendered, m as PlanKnown, n as StageError, p as PhaseEntered, t as PrepareError, u as ModeSignal, w as RunStarted, x as RunMutantTested, y as RunEvent } from "./Run.schema-BxsyHwHr.mjs";
1
+ import { A as Plugin_exports, D as VerdictReached, E as SkippedReported, F as ErrorText_exports, I as Format_exports, L as Instrument_exports, M as Reporter_exports, N as TestRunner_exports, O as Checker_exports, P as Trace_exports$1, R as Mutant_exports, _ as PluginsReported, b as RunFailed$1, c as Heartbeat, f as OutputMode, i as FormatRegistryResolved, j as Report_exports, k as Options_exports, l as HelpRendered, m as PlanKnown, n as StageError, p as PhaseEntered, t as PrepareError, u as ModeSignal, w as RunStarted, x as RunMutantTested, y as RunEvent } from "./Run.schema-BaK_pxuK.mjs";
2
2
  import { t as mergeConfig } from "./merge-config-ByZJPeQZ.mjs";
3
3
  import { Blueprint, Cell, Handle, Sandwich, Workflow } from "@systemfsoftware/effect-cell-types";
4
4
  import * as Boolean$1 from "effect/Boolean";
@@ -61,13 +61,13 @@ import * as NodeFileSystem$1 from "@effect/platform-node-shared/NodeFileSystem";
61
61
  import * as NodePath$1 from "@effect/platform-node-shared/NodePath";
62
62
  import { badArgument } from "effect/PlatformError";
63
63
  import * as Equivalence from "effect/Equivalence";
64
- import { Session } from "@systemfsoftware/stryker-vm-harness";
65
64
  import * as Console from "effect/Console";
66
65
  import * as Formatter from "effect/Formatter";
67
66
  import * as Runtime from "effect/Runtime";
68
67
  import * as Order from "effect/Order";
69
68
  import * as CliError from "effect/unstable/cli/CliError";
70
69
  import { sha256 } from "@noble/hashes/sha2.js";
70
+ import "effect/Deferred";
71
71
  import * as Pool from "effect/Pool";
72
72
  import * as Semaphore from "effect/Semaphore";
73
73
  //#region src/admit-checker-answer.workflow.ts
@@ -178,14 +178,14 @@ var WorkerBootTimeoutError = class extends Schema.TaggedError()("WorkerBootTimeo
178
178
  };
179
179
  //#endregion
180
180
  //#region src/Checker/Checker.handle.ts
181
- const TypeId$11 = Symbol.for("~systemfsoftware/stryker-js/Checker");
181
+ const TypeId$10 = Symbol.for("~systemfsoftware/stryker-js/Checker");
182
182
  const checkerDuration = Metric.timer("stryker.checker.duration", { description: "Checker worker RPC duration in milliseconds" });
183
183
  const checkerMutantsChecked = Metric.counter("stryker.checker.mutants.checked", { description: "Total number of mutants a checker worker answered for" });
184
184
  const checkerRpcFailures = Metric.counter("stryker.checker.rpc_failures", {
185
185
  description: "Checker worker RPC calls that did not complete, excluding interruptions",
186
186
  incremental: true
187
187
  });
188
- const CheckerHandle = Handle.make()(TypeId$11);
188
+ const CheckerHandle = Handle.make()(TypeId$10);
189
189
  const isCheckerHandle = CheckerHandle.is;
190
190
  const connectionCrashed = (cause) => ChildProcessCrashedError.make({
191
191
  pid: 0,
@@ -418,7 +418,7 @@ const checkCell = Sandwich.named("stryker.checker.check_plans")(readCheckCommand
418
418
  CheckerSkippedRequested: (breach) => Effect$1.fail(CheckerSkippedRequested.make(breach)),
419
419
  CommandRejected: ({ issue }, raw) => Effect$1.fail(commandFailed(issue, raw))
420
420
  });
421
- const checkGroupedCell = Sandwich.named("stryker.checker.group_plans")(readGroupCommand).decide(admitCheckerAnswer).write({
421
+ const groupCell = Sandwich.named("stryker.checker.group_plans")(readGroupCommand).decide(admitCheckerAnswer).write({
422
422
  CheckGroupDecision: ({ groups }, raw) => writeDecidedGroups({
423
423
  plans: raw.plans,
424
424
  checkerName: raw.checkerName,
@@ -432,16 +432,20 @@ const checkGroupedCell = Sandwich.named("stryker.checker.group_plans")(readGroup
432
432
  CheckerAnsweredUnrequested: (breach) => Effect$1.fail(CheckerAnsweredUnrequested.make(breach)),
433
433
  CheckerSkippedRequested: (breach) => Effect$1.fail(CheckerSkippedRequested.make(breach)),
434
434
  CommandRejected: ({ issue }, raw) => Effect$1.fail(commandFailed(issue, raw))
435
- }).pipe(Cell.flatMap((groups) => Cell.mapInput(Cell.collect(checkCell, (perGroup) => perGroup.flat()), (input) => groups.map((group) => ({
435
+ });
436
+ const checkGroupedCell = groupCell.pipe(Cell.flatMap((groups) => Cell.mapInput(Cell.collect(checkCell, (perGroup) => perGroup.flat()), (input) => groups.map((group) => ({
436
437
  ...input,
437
438
  plans: group
438
439
  })))));
439
- const checkGroupedPlans = dual(3, (checker, checkerName, plans) => checkGroupedCell.run({
440
+ const checkRequestOf = (checker, checkerName, plans) => ({
440
441
  checker,
441
442
  checkerName,
442
443
  plans,
443
444
  lookup: lookupOf(partitionMutantsForWire(plans))
444
- }));
445
+ });
446
+ const groupPlans = dual(3, (checker, checkerName, plans) => groupCell.run(checkRequestOf(checker, checkerName, plans)));
447
+ const checkPlans = dual(3, (checker, checkerName, plans) => checkCell.run(checkRequestOf(checker, checkerName, plans)));
448
+ const checkGroupedPlans = dual(3, (checker, checkerName, plans) => checkGroupedCell.run(checkRequestOf(checker, checkerName, plans)));
445
449
  //#endregion
446
450
  //#region src/Config.schema.ts
447
451
  const ConfigDocumentSchema = S.Record(S.String, S.Unknown);
@@ -718,8 +722,8 @@ const interpretDryRunResult = Workflow.make({
718
722
  });
719
723
  //#endregion
720
724
  //#region src/pooled-test-runner.handle.ts
721
- const TypeId$10 = Symbol.for("~systemfsoftware/stryker-js/PooledTestRunner");
722
- const PooledTestRunner = Handle.make()(TypeId$10);
725
+ const TypeId$9 = Symbol.for("~systemfsoftware/stryker-js/PooledTestRunner");
726
+ const PooledTestRunner = Handle.make()(TypeId$9);
723
727
  PooledTestRunner.is;
724
728
  const make$3 = (runner) => PooledTestRunner.make({
725
729
  capabilities: runner.capabilities,
@@ -820,7 +824,7 @@ const withEnvironmentReload = dual(2, (inner, retire) => Effect$1.gen(function*
820
824
  }));
821
825
  //#endregion
822
826
  //#region src/command-runner.blueprint.ts
823
- const TypeId$9 = Symbol.for("~systemfsoftware/stryker-js/CommandRunner");
827
+ const TypeId$8 = Symbol.for("~systemfsoftware/stryker-js/CommandRunner");
824
828
  const ALL_TESTS_NAME = "All tests";
825
829
  const isCommandRunner = (name) => typeof name === "string" && name.toLowerCase() === "command";
826
830
  const commandRunnerCapabilities = { reloadEnvironment: true };
@@ -881,7 +885,7 @@ const pooledRunnerOf = (config, spawner) => {
881
885
  mutantRun: (options) => commandRunnerMutantRun(config, options).pipe(provided)
882
886
  });
883
887
  };
884
- const CommandRunners = Blueprint.make()(TypeId$9).steps({
888
+ const CommandRunners = Blueprint.make()(TypeId$8).steps({
885
889
  steps: {},
886
890
  targets: { runner: (spec) => (spawner) => pooledRunnerOf({
887
891
  workingDir: spec.workingDir,
@@ -1036,7 +1040,7 @@ const resolveConfig = Workflow.make({
1036
1040
  const ExitDecisionTypeId = Symbol.for("@systemfsoftware/stryker-js/ExitDecision");
1037
1041
  var ClassifyExitCommand = class extends S.TaggedClass()("ClassifyExitCommand", {
1038
1042
  pending: S.Array(Plugin_exports.ExitClass),
1039
- score: S.NullOr(S.Finite),
1043
+ score: Report_exports.MutationScore,
1040
1044
  breakingThreshold: S.NullOr(S.Finite)
1041
1045
  }) {
1042
1046
  static [Workflow.InstrumentationBrand] = {};
@@ -1071,9 +1075,12 @@ const PRECEDENCE = [
1071
1075
  ];
1072
1076
  const precedenceOf = (pending) => Arr.findFirst(PRECEDENCE, (candidate) => pending.includes(candidate));
1073
1077
  const decisionOf$1 = (exitClass) => Match.value(exitClass).pipe(Match.when("VerdictFail", () => ExitVerdictFailed.make({})), Match.when("ConfigError", () => ExitConfigErrored.make({})), Match.when("RuntimeError", () => ExitRuntimeErrored.make({})), Match.when("InternalError", () => ExitInternalErrored.make({})), Match.exhaustive);
1074
- const verdictExitClass = (score, breakingThreshold) => Option$1.match(Option$1.all([Option$1.fromNullishOr(score), Option$1.fromNullishOr(breakingThreshold)]), {
1075
- onNone: () => null,
1076
- onSome: ([actual, threshold]) => Match.value(actual < threshold).pipe(Match.when(true, () => "VerdictFail"), Match.when(false, () => null), Match.exhaustive)
1078
+ const verdictExitClass = (score, breakingThreshold) => Match.valueTags(score, {
1079
+ Unscored: () => null,
1080
+ Scored: ({ percentage }) => Option$1.match(Option$1.fromNullishOr(breakingThreshold), {
1081
+ onNone: () => null,
1082
+ onSome: (threshold) => Match.value(percentage < threshold).pipe(Match.when(true, () => "VerdictFail"), Match.when(false, () => null), Match.exhaustive)
1083
+ })
1077
1084
  });
1078
1085
  const decide$9 = (command) => Option$1.match(Option$1.fromNullishOr(verdictExitClass(command.score, command.breakingThreshold)), {
1079
1086
  onNone: () => Option$1.match(precedenceOf(command.pending), {
@@ -1266,13 +1273,13 @@ const restrictSocket = (address) => Match.value(address).pipe(Match.tag("UnixPat
1266
1273
  onTrue: () => Effect$1.void,
1267
1274
  onFalse: () => Effect$1.flatMap(FileSystem.FileSystem, (fs) => fs.chmod(path, 384))
1268
1275
  })), Match.orElse(() => Effect$1.void));
1269
- const TypeId$8 = Symbol.for("~systemfsoftware/stryker-js-plugin-runtime/WorkerServer");
1276
+ const TypeId$7 = Symbol.for("~systemfsoftware/stryker-js-plugin-runtime/WorkerServer");
1270
1277
  const workerServerLayerOf = (params) => Layer.unwrap(Effect$1.gen(function* () {
1271
1278
  const socket = yield* SocketServer.SocketServer;
1272
1279
  yield* restrictSocket(socket.address);
1273
1280
  return RpcServer.layer(params.rpcs).pipe(Layer.provide(params.handlers), Layer.provide(params.schemaServices), Layer.provide(RpcServer.layerProtocolSocketServer), Layer.provide(RpcSerialization.layerNdjson), Layer.provide(traceContextServer));
1274
1281
  }));
1275
- Blueprint.make()(TypeId$8).steps({
1282
+ Blueprint.make()(TypeId$7).steps({
1276
1283
  steps: {},
1277
1284
  targets: { layer: workerServerLayerOf }
1278
1285
  }).is;
@@ -1320,8 +1327,8 @@ var Worker_exports = /* @__PURE__ */ __exportAll$1({
1320
1327
  });
1321
1328
  //#endregion
1322
1329
  //#region src/spawned-socket-worker.handle.ts
1323
- const TypeId$7 = Symbol.for("~systemfsoftware/stryker-js/SpawnedSocketWorker");
1324
- const SpawnedSocketWorker = Handle.make()(TypeId$7);
1330
+ const TypeId$6 = Symbol.for("~systemfsoftware/stryker-js/SpawnedSocketWorker");
1331
+ const SpawnedSocketWorker = Handle.make()(TypeId$6);
1325
1332
  SpawnedSocketWorker.is;
1326
1333
  const make$2 = (worker) => SpawnedSocketWorker.make({
1327
1334
  pid: worker.pid,
@@ -1333,9 +1340,9 @@ const clientLayer = (self) => SpawnedSocketWorker.slot(self).clientLayer;
1333
1340
  var WorkerLauncher = class extends Context.Service()("@systemfsoftware/stryker-js/WorkerLauncher.service/WorkerLauncher") {};
1334
1341
  //#endregion
1335
1342
  //#region src/worker-client.blueprint.ts
1336
- const TypeId$6 = Symbol.for("~systemfsoftware/stryker-js/WorkerClient");
1343
+ const TypeId$5 = Symbol.for("~systemfsoftware/stryker-js/WorkerClient");
1337
1344
  const connectRetry = Schedule.max([Schedule.spaced(50), Schedule.recurs(100)]);
1338
- const scopedOf$2 = (params) => Effect$1.gen(function* () {
1345
+ const scopedOf$1 = (params) => Effect$1.gen(function* () {
1339
1346
  const launcher = yield* WorkerLauncher;
1340
1347
  const optionsJson = yield* S.encodeEffect(Worker_exports.WorkerOptionsWire)(params.options).pipe(Effect$1.orDie);
1341
1348
  const worker = yield* launcher.spawn({
@@ -1350,9 +1357,9 @@ const scopedOf$2 = (params) => Effect$1.gen(function* () {
1350
1357
  const traceContext = yield* Layer.build(Trace_exports.layerTraceContextClient);
1351
1358
  return yield* RpcClient.make(params.rpcs).pipe(Effect$1.provideContext(Context.merge(protocol, traceContext)));
1352
1359
  });
1353
- const WorkerClients = () => Blueprint.make()(TypeId$6).steps({
1360
+ const WorkerClients = () => Blueprint.make()(TypeId$5).steps({
1354
1361
  steps: {},
1355
- targets: { scoped: scopedOf$2 }
1362
+ targets: { scoped: scopedOf$1 }
1356
1363
  });
1357
1364
  const makeWorkerClient = (params) => WorkerClients().of(params).scoped;
1358
1365
  const ReporterStageTypeId = Symbol.for("@systemfsoftware/stryker-js/ReporterStage");
@@ -1702,7 +1709,10 @@ var VerdictEnvelope = class VerdictEnvelope extends S.Class("VerdictEnvelope")({
1702
1709
  runId,
1703
1710
  mode,
1704
1711
  signal,
1705
- score: Option$1.getOrNull(Option$1.filter(Option$1.some(metrics.mutationScore), (score) => metrics.totalMutants > 0 && Number.isFinite(score))),
1712
+ score: Report_exports.MutationScore.match(metrics.mutationScore, {
1713
+ Scored: ({ percentage }) => percentage,
1714
+ Unscored: () => null
1715
+ }),
1706
1716
  thresholds: {
1707
1717
  high: report.thresholds.high,
1708
1718
  low: report.thresholds.low,
@@ -1740,7 +1750,7 @@ var RunEvents = class extends Context.Service()("@systemfsoftware/stryker-js/run
1740
1750
  var RunIdentity = class extends Context.Service()("@systemfsoftware/stryker-js/run-events.service/RunIdentity") {};
1741
1751
  //#endregion
1742
1752
  //#region package.json
1743
- var version = "12.0.0";
1753
+ var version = "12.1.0";
1744
1754
  //#endregion
1745
1755
  //#region src/stryker-package.schema.ts
1746
1756
  var StrykerPackage = class extends S.Class("StrykerPackage")({
@@ -2032,22 +2042,28 @@ const mutationTestReport = (deps, input) => (results) => Effect$1.gen(function*
2032
2042
  identities
2033
2043
  };
2034
2044
  });
2035
- const determineExitCode = (input) => (metrics) => Effect$1.gen(function* () {
2036
- const { mutationScore } = metrics.metrics;
2045
+ const determineExitCode = (input) => (metrics) => {
2037
2046
  const breaking = input.options.thresholds.break;
2038
- const formattedScore = mutationScore.toFixed(2);
2039
- return yield* Option$1.match(Option$1.fromNullishOr(Result.match(classifyExit(ClassifyExitCommand.make({
2047
+ const score = metrics.metrics.mutationScore;
2048
+ const failure = Option$1.fromNullishOr(Result.match(classifyExit(ClassifyExitCommand.make({
2040
2049
  pending: [],
2041
- score: mutationScore,
2050
+ score,
2042
2051
  breakingThreshold: breaking
2043
2052
  })), {
2044
2053
  onFailure: (refused) => refused,
2045
2054
  onSuccess: (decision) => Match.value(decision).pipe(Match.tag("ExitVerdictFailed", () => "VerdictFail"), Match.orElse(() => null))
2046
- })), {
2047
- onNone: () => Effect$1.map(Match.value(breaking).pipe(Match.when(null, () => Effect$1.logDebug("No breaking threshold configured. Won't fail the build no matter how low your mutation score is. Set `thresholds.break` to change this behavior.")), Match.orElse((threshold) => Effect$1.logInfo(`Final mutation score of ${formattedScore} is greater than or equal to break threshold ${String(threshold)}`))), () => null),
2048
- onSome: (failure) => Effect$1.map(Effect$1.andThen(Effect$1.logError(`Final mutation score ${formattedScore} under breaking threshold ${String(breaking)}, setting exit code to 1 (failure).`), Effect$1.logInfo("(improve mutation score or set `thresholds.break = null` to prevent this error in the future)")), () => failure)
2055
+ }));
2056
+ return Report_exports.MutationScore.match(score, {
2057
+ Scored: ({ percentage }) => Option$1.match(failure, {
2058
+ onNone: () => Effect$1.as(logScoredPass(breaking, percentage), null),
2059
+ onSome: (exitClass) => Effect$1.as(logBroken(breaking, percentage), exitClass)
2060
+ }),
2061
+ Unscored: () => Effect$1.as(logUnscored(breaking), Option$1.getOrNull(failure))
2049
2062
  });
2050
- });
2063
+ };
2064
+ const logScoredPass = (breaking, percentage) => Match.value(breaking).pipe(Match.when(null, () => Effect$1.logDebug("No breaking threshold configured. Won't fail the build no matter how low your mutation score is. Set `thresholds.break` to change this behavior.")), Match.orElse((threshold) => Effect$1.logInfo(`Final mutation score of ${percentage.toFixed(2)} is greater than or equal to break threshold ${String(threshold)}`)));
2065
+ const logUnscored = (breaking) => Match.value(breaking).pipe(Match.when(null, () => Effect$1.void), Match.orElse((threshold) => Effect$1.logInfo(`No valid mutant was tested, so there is no mutation score to hold against break threshold ${String(threshold)}`)));
2066
+ const logBroken = (breaking, percentage) => Effect$1.andThen(Effect$1.logError(`Final mutation score ${percentage.toFixed(2)} under breaking threshold ${String(breaking)}, setting exit code to 1 (failure).`), Effect$1.logInfo("(improve mutation score or set `thresholds.break = null` to prevent this error in the future)"));
2051
2067
  const emitVerdict = (deps, input) => (report) => Effect$1.gen(function* () {
2052
2068
  const envelope = VerdictEnvelope.build(report, input.resolvedMode.mode, input.resolvedMode.signal, input.runId, input.basePath, deps.path);
2053
2069
  yield* Queue.offer(deps.events, VerdictReached.make({
@@ -2079,7 +2095,7 @@ const reportAll = (deps, input) => Effect$1.gen(function* () {
2079
2095
  const verdict = yield* determineExitCode(input)(metrics);
2080
2096
  const finalVerdict = Result.match(classifyExit(ClassifyExitCommand.make({
2081
2097
  pending: [verdict, terminalDrain].filter((candidate) => candidate !== null),
2082
- score: null,
2098
+ score: Report_exports.MutationScore.cases.Unscored.make({}),
2083
2099
  breakingThreshold: null
2084
2100
  })), {
2085
2101
  onFailure: (refused) => refused,
@@ -2431,8 +2447,12 @@ const mutantReportSection = (report, metrics, render) => Boolean$1.match(render.
2431
2447
  },
2432
2448
  onFalse: () => EMPTY_SECTIONS
2433
2449
  });
2450
+ const hasFullScore = (metrics) => Match.valueTags(metrics.mutationScore, {
2451
+ Scored: ({ percentage }) => percentage === 100,
2452
+ Unscored: () => false
2453
+ });
2434
2454
  const partialScoresVisible = (metrics, render) => Boolean$1.match(render.skipFull, {
2435
- onTrue: () => metrics.childResults.some((child) => child.metrics.mutationScore !== 100),
2455
+ onTrue: () => metrics.childResults.some((child) => !hasFullScore(child.metrics)),
2436
2456
  onFalse: () => true
2437
2457
  });
2438
2458
  const drawsScoreTable = (metrics, render) => Boolean$1.match(render.reportScoreTable, {
@@ -2440,14 +2460,14 @@ const drawsScoreTable = (metrics, render) => Boolean$1.match(render.reportScoreT
2440
2460
  onFalse: () => false
2441
2461
  });
2442
2462
  const mutationScoreOf = (scoreType, metrics) => Match.value(scoreType).pipe(Match.when("total", () => metrics.mutationScore), Match.when("covered", () => metrics.mutationScoreBasedOnCoveredCode), Match.exhaustive);
2443
- const scoreText = (scoreType, row) => {
2444
- const score = mutationScoreOf(scoreType, row.metrics);
2445
- return Boolean$1.match(Number.isNaN(score), {
2446
- onTrue: () => "n/a",
2447
- onFalse: () => score.toFixed(2)
2448
- });
2449
- };
2450
- const thresholdTone = (thresholds, score) => Match.value(score).pipe(Match.when((present) => Number.isNaN(present), () => "muted"), Match.when((present) => present >= thresholds.high, () => "positive"), Match.when((present) => present >= thresholds.low, () => "warning"), Match.orElse(() => "negative"));
2463
+ const scoreText = (scoreType, row) => Match.valueTags(mutationScoreOf(scoreType, row.metrics), {
2464
+ Scored: ({ percentage }) => percentage.toFixed(2),
2465
+ Unscored: () => "n/a"
2466
+ });
2467
+ const thresholdTone = (thresholds, score) => Match.valueTags(score, {
2468
+ Scored: ({ percentage }) => Match.value(percentage).pipe(Match.when((value) => value >= thresholds.high, () => "positive"), Match.when((value) => value >= thresholds.low, () => "warning"), Match.orElse(() => "negative")),
2469
+ Unscored: () => "muted"
2470
+ });
2451
2471
  const scoreTone = (thresholds, scoreType, allowColor) => Boolean$1.match(allowColor, {
2452
2472
  onTrue: () => (row) => thresholdTone(thresholds, mutationScoreOf(scoreType, row.metrics)),
2453
2473
  onFalse: () => () => "plain"
@@ -2544,7 +2564,7 @@ const createColumns = (metricsResult, render) => [
2544
2564
  const leafRules = (columns) => columns.flatMap((column) => column.leaves.map((leaf) => [rule("-", slotWidthOf(leaf))]));
2545
2565
  const leafHeaders = (columns) => columns.flatMap((column) => column.leaves.map((leaf) => placedLine(leaf.header, leaf.style, leaf.netWidth)));
2546
2566
  const fullRowVisible = (render, row) => Boolean$1.match(render.skipFull, {
2547
- onTrue: () => row.metrics.mutationScore !== 100,
2567
+ onTrue: () => !hasFullScore(row.metrics),
2548
2568
  onFalse: () => true
2549
2569
  });
2550
2570
  const bodyRow = (columns, row, ancestorCount) => rowOfLines(columns.flatMap((column) => column.leaves.map((leaf) => [placedCell(leaf.cell(row, ancestorCount), leaf.style, leaf.netWidth, leaf.tone(row))])));
@@ -3697,7 +3717,7 @@ const classifyWorkerExit = Workflow.make({
3697
3717
  });
3698
3718
  //#endregion
3699
3719
  //#region src/worker-protocol.blueprint.ts
3700
- const TypeId$5 = Symbol.for("~systemfsoftware/stryker-js/WorkerProtocol");
3720
+ const TypeId$4 = Symbol.for("~systemfsoftware/stryker-js/WorkerProtocol");
3701
3721
  const droppedConnection = RpcClientError.make({ reason: Socket.SocketReadError.make({ cause: /* @__PURE__ */ new Error("worker connection dropped with the request in flight") }) });
3702
3722
  const layerOf = (socket) => Layer.effect(RpcClient.Protocol, Effect$1.gen(function* () {
3703
3723
  const handlers = MutableHashMap.empty();
@@ -3738,7 +3758,7 @@ const layerOf = (socket) => Layer.effect(RpcClient.Protocol, Effect$1.gen(functi
3738
3758
  send: (clientId, request, transferables) => track(clientId, request).pipe(Effect$1.andThen(inner.send(clientId, request, transferables)))
3739
3759
  });
3740
3760
  }));
3741
- const WorkerProtocol = Blueprint.make()(TypeId$5).steps({
3761
+ const WorkerProtocol = Blueprint.make()(TypeId$4).steps({
3742
3762
  steps: {},
3743
3763
  targets: { layer: (spec) => layerOf(spec.socket) }
3744
3764
  });
@@ -3746,7 +3766,7 @@ const layerWorkerProtocol = (socket) => WorkerProtocol.of({ socket }).layer;
3746
3766
  //#endregion
3747
3767
  //#region src/drivers/node.ts
3748
3768
  const restrictToOwnerOrWarn = (fs, file) => fs.chmod(file, 384).pipe(Effect$1.tapError((cause) => Effect$1.logWarning(`Could not restrict "${file}" to its owner; the worker directory's own mode still protects it.`).pipe(Effect$1.annotateLogs("cause", cause))), Effect$1.catchTag("PlatformError", () => Effect$1.void));
3749
- const nodeWorkerLauncherLayer = Layer.effect(WorkerLauncher, Effect$1.gen(function* () {
3769
+ const nodeWorkerLauncherLayer = (childEnv) => Layer.effect(WorkerLauncher, Effect$1.gen(function* () {
3750
3770
  const crypto = yield* Crypto.Crypto;
3751
3771
  const fs = yield* FileSystem.FileSystem;
3752
3772
  const path = yield* Path.Path;
@@ -3765,6 +3785,7 @@ const nodeWorkerLauncherLayer = Layer.effect(WorkerLauncher, Effect$1.gen(functi
3765
3785
  env: {
3766
3786
  STRYKER_WORKER_DIR: workerDir,
3767
3787
  STRYKER_SOCKET: socketPath,
3788
+ ...childEnv,
3768
3789
  ...params.env
3769
3790
  },
3770
3791
  stderr: "inherit"
@@ -3804,7 +3825,8 @@ const nodeWorkerLauncherLayer = Layer.effect(WorkerLauncher, Effect$1.gen(functi
3804
3825
  const nodeFsPathLayer$1 = Layer.mergeAll(NodeFileSystem.layer, NodePath.layer);
3805
3826
  const nodeSpawnerLayer = NodeChildProcessSpawner.layer.pipe(Layer.provide(nodeFsPathLayer$1));
3806
3827
  const nodeBase = Layer.mergeAll(nodeFsPathLayer$1, nodeSpawnerLayer, NodeStdio.layer);
3807
- const nodePlatformLayer = Layer.mergeAll(nodeWorkerLauncherLayer.pipe(Layer.provide(Layer.merge(nodeBase, NodeCrypto.layer))), nodeBase);
3828
+ const makeNodePlatformLayer = (options) => Layer.mergeAll(nodeWorkerLauncherLayer(options.childEnv).pipe(Layer.provide(Layer.merge(nodeBase, NodeCrypto.layer))), nodeBase);
3829
+ const nodePlatformLayer = makeNodePlatformLayer({ childEnv: {} });
3808
3830
  //#endregion
3809
3831
  //#region src/IncrementalDiff.schema.ts
3810
3832
  const PositionSchema$1 = S.Struct({
@@ -4146,138 +4168,6 @@ const admitIncrementalReport = Workflow.make({
4146
4168
  decide: (command) => Result.succeed(decide$6(command))
4147
4169
  });
4148
4170
  //#endregion
4149
- //#region src/VmRunner.blueprint.ts
4150
- const TypeId$4 = Symbol.for("~systemfsoftware/stryker-js/VmTestRunner");
4151
- const isVmRunner = (name) => typeof name === "string" && name.toLowerCase() === "vm";
4152
- const vmRunnerCapabilities = { reloadEnvironment: true };
4153
- const HOST_TIMEOUT_SLACK_MS = 1e3;
4154
- const messageOf$1 = (cause) => cause instanceof Error ? cause.message : new Error("the vm test runner failed", { cause }).message;
4155
- const testResultOf = (test) => {
4156
- const base = {
4157
- id: test.id,
4158
- name: test.name,
4159
- timeSpentMs: test.timeSpentMs
4160
- };
4161
- return Match.value(test.status).pipe(Match.when("failed", () => ({
4162
- ...base,
4163
- status: "failed",
4164
- failureMessage: test.failureMessage ?? ""
4165
- })), Match.when("skipped", () => ({
4166
- ...base,
4167
- status: "skipped"
4168
- })), Match.orElse(() => ({
4169
- ...base,
4170
- status: "success"
4171
- })));
4172
- };
4173
- const dryRunResultOf = (response) => {
4174
- const tests = response.tests.map(testResultOf);
4175
- return Option$1.match(Option$1.fromUndefinedOr(response.mutantCoverage), {
4176
- onNone: () => ({
4177
- status: "complete",
4178
- tests
4179
- }),
4180
- onSome: (mutantCoverage) => ({
4181
- status: "complete",
4182
- tests,
4183
- mutantCoverage
4184
- })
4185
- });
4186
- };
4187
- const respond = (response) => Match.value(response).pipe(Match.discriminator("status")("init-failed", (failed) => Effect$1.fail(TestRunner_exports.TestRunnerFailed.make({
4188
- runnerName: "vm",
4189
- phase: "init",
4190
- cause: failed.message
4191
- }))), Match.discriminator("status")("timeout", () => Effect$1.succeed({ status: "timeout" })), Match.discriminator("status")("error", (errored) => Effect$1.succeed({
4192
- status: "error",
4193
- errorMessage: errored.errorMessage
4194
- })), Match.discriminator("status")("complete", (complete) => Effect$1.succeed(dryRunResultOf(complete))), Match.exhaustive);
4195
- const pooledVmRunner = (config, scope) => {
4196
- let client;
4197
- let sessionTestFiles = config.testFiles;
4198
- const sessionOptions = () => ({
4199
- sandboxWorkingDirectory: config.sandboxWorkingDirectory,
4200
- testFiles: sessionTestFiles
4201
- });
4202
- const spawnClient = Effect$1.try({
4203
- try: () => {
4204
- const spawned = Session.createVmWorkerClient(sessionOptions(), { onExit: () => {
4205
- if (client === spawned) client = void 0;
4206
- } });
4207
- return spawned;
4208
- },
4209
- catch: (cause) => TestRunner_exports.TestRunnerFailed.make({
4210
- runnerName: "vm",
4211
- phase: "init",
4212
- cause: `the vm test runner could not start its worker: ${messageOf$1(cause)}`
4213
- })
4214
- });
4215
- const dropClient = Effect$1.suspend(() => {
4216
- const current = client;
4217
- client = void 0;
4218
- return current === void 0 ? Effect$1.void : Effect$1.promise(() => current.terminate());
4219
- });
4220
- const run = (request) => Effect$1.gen(function* () {
4221
- if (client === void 0) {
4222
- const spawned = yield* spawnClient;
4223
- yield* Scope.addFinalizer(scope, Effect$1.promise(() => spawned.terminate()));
4224
- client = spawned;
4225
- }
4226
- const current = client;
4227
- const answer = yield* Effect$1.tryPromise({
4228
- try: () => current.run(request),
4229
- catch: (cause) => ({
4230
- status: "error",
4231
- errorMessage: messageOf$1(cause)
4232
- })
4233
- }).pipe(Effect$1.catch((failed) => Effect$1.succeed(failed)), Effect$1.timeoutOrElse({
4234
- duration: request.timeoutMs + HOST_TIMEOUT_SLACK_MS,
4235
- orElse: () => dropClient.pipe(Effect$1.as({ status: "timeout" }))
4236
- }));
4237
- return yield* respond(answer);
4238
- }).pipe(Effect$1.onInterrupt(() => dropClient));
4239
- const shouldAdoptTestFiles = () => config.testFiles.length === 0 && client === void 0;
4240
- const adoptedTestFiles = (testFiles) => testFiles ?? [];
4241
- const testFilterFieldOf = (testFilter) => testFilter === void 0 ? {} : { testFilter: [...testFilter] };
4242
- const hitLimitFieldOf = (hitLimit) => hitLimit === void 0 ? {} : { hitLimit };
4243
- const mutantRequestOf = (options) => ({
4244
- kind: "mutant",
4245
- timeoutMs: options.timeout,
4246
- activeMutantId: String(options.activeMutant.id),
4247
- ...testFilterFieldOf(options.testFilter),
4248
- ...hitLimitFieldOf(options.hitLimit),
4249
- reloadEnvironment: options.reloadEnvironment
4250
- });
4251
- return make$3({
4252
- capabilities: Effect$1.succeed(vmRunnerCapabilities),
4253
- init: Effect$1.void,
4254
- dryRun: (options) => {
4255
- if (shouldAdoptTestFiles()) sessionTestFiles = adoptedTestFiles(options.testFiles);
4256
- return run({
4257
- kind: "dry",
4258
- timeoutMs: options.timeout,
4259
- reloadEnvironment: true
4260
- });
4261
- },
4262
- mutantRun: (options) => run(mutantRequestOf(options)).pipe(Effect$1.map((dryRunResult) => interpretDryRunResult(InterpretDryRunResultCommand.make({ dryRunResult }))), Effect$1.flatMap((decided) => Result.match(decided, {
4263
- onFailure: (failure) => Effect$1.fail(failure),
4264
- onSuccess: (decision) => Effect$1.succeed(decision.asResult)
4265
- })), Effect$1.catchTag("TestRunnerFailed", (failure) => Effect$1.succeed({
4266
- status: "error",
4267
- errorMessage: failure.cause
4268
- })))
4269
- });
4270
- };
4271
- const scopedOf$1 = (config) => Effect$1.gen(function* () {
4272
- const scope = yield* Effect$1.scope;
4273
- return pooledVmRunner(config, scope);
4274
- });
4275
- const VmRunners = Blueprint.make()(TypeId$4).steps({
4276
- steps: {},
4277
- targets: { scoped: scopedOf$1 }
4278
- });
4279
- const vmTestRunner = (config) => VmRunners.of(config).scoped;
4280
- //#endregion
4281
4171
  //#region src/read-project.parts.ts
4282
4172
  const ALWAYS_IGNORE = Object.freeze([
4283
4173
  "node_modules",
@@ -4290,23 +4180,9 @@ const ALWAYS_IGNORE = Object.freeze([
4290
4180
  ]);
4291
4181
  const IGNORE_PATTERN_CHARACTER = "!";
4292
4182
  const DEFAULT_GLOB = "**/*.{js,ts,jsx,tsx,html,vue,mjs,mts,cts,cjs}";
4293
- const VITEST_DEFAULT_TEST_FILE_PATTERNS = ["**/*.{test,spec}.{js,jsx,ts,tsx,cjs,cjsx,cts,ctsx,mjs,mjsx,mts,mtsx}"];
4294
- const defaultTestFileIgnores = (tempDirName) => [
4295
- "**/node_modules/**",
4296
- "**/dist/**",
4297
- "**/.{idea,git,cache,output,temp}/**",
4298
- `**/${tempDirName}/**`
4299
- ];
4300
- const shouldDiscoverTestFiles = (options) => options.testFiles.length === 0 && isVmRunner(options.testRunner);
4301
- const testFileSelectionOf = (options) => Boolean.match(shouldDiscoverTestFiles(options), {
4302
- onTrue: () => ({
4303
- testFilePatterns: VITEST_DEFAULT_TEST_FILE_PATTERNS,
4304
- testFileIgnores: defaultTestFileIgnores(options.tempDirName)
4305
- }),
4306
- onFalse: () => ({
4307
- testFilePatterns: options.testFiles,
4308
- testFileIgnores: []
4309
- })
4183
+ const testFileSelectionOf = (options) => ({
4184
+ testFilePatterns: options.testFiles,
4185
+ testFileIgnores: []
4310
4186
  });
4311
4187
  const normalizeFileName = (value) => value.replace(/\\/g, "/");
4312
4188
  const escapeRegExp = (value) => value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
@@ -4818,8 +4694,11 @@ const formatTotal = (total) => Option$1.match(Option$1.fromNullishOr(total), {
4818
4694
  onSome: (val) => String(val)
4819
4695
  });
4820
4696
  const formatStderrEvent = (event) => Match.value(event).pipe(Match.tag("plan", (e) => `plan ${e.total} mutants`), Match.tag("phase", (e) => `phase ${e.phase}`), Match.tag("tick", (e) => `${e.completed}/${formatTotal(e.total)} elapsed ${e.elapsedMs}ms`), Match.tag("verdict", (e) => `score ${formatScore(e.score)} killed ${e.counts.killed} survived ${e.counts.survived}`), Match.tag("error", (e) => `error ${e.error}`), Match.tag("stream", () => null), Match.tag("mutant", () => null), Match.tag("help", () => null), Match.tag("plugins", () => null), Match.tag("formats", () => null), Match.tag("skipped", () => null), Match.exhaustive);
4821
- const stderrLineFor = (state, event) => Match.value(state.terminalSeen).pipe(Match.when(true, () => null), Match.when(false, () => formatStderrEvent(event)), Match.exhaustive);
4822
- const shouldFrame = (state) => Match.value(state.mode).pipe(Match.when("machine", () => !state.terminalSeen), Match.when("human", () => false), Match.exhaustive);
4697
+ const stderrLineFor = (state, event) => Boolean$1.match(Boolean$1.and(state.mode === "human", !state.terminalSeen), {
4698
+ onTrue: () => formatStderrEvent(event),
4699
+ onFalse: () => null
4700
+ });
4701
+ const shouldFrame = (state) => !state.terminalSeen;
4823
4702
  const decideFrame = (command) => {
4824
4703
  const nextState = noteState(command.state, command.event);
4825
4704
  const stderrLine = stderrLineFor(command.state, command.event);
@@ -4878,7 +4757,10 @@ const formatTemplate = (template, args) => {
4878
4757
  };
4879
4758
  const headOf = (args) => Option$1.fromNullishOr(args[0]);
4880
4759
  const formatArgs = (args) => Option$1.match(Option$1.filter(headOf(args), Predicate$1.isString), {
4881
- onSome: (first) => formatTemplate(first, args.slice(1)),
4760
+ onSome: (first) => Boolean$1.match(args.length === 1, {
4761
+ onTrue: () => first,
4762
+ onFalse: () => formatTemplate(first, args.slice(1))
4763
+ }),
4882
4764
  onNone: () => args.map(inspectValue).join(" ")
4883
4765
  });
4884
4766
  const DEFAULT_CONSOLE_LABEL = "default";
@@ -5530,7 +5412,7 @@ var RunEventDrain = class RunEventDrain extends Context.Service()("@systemfsoftw
5530
5412
  static layer = Layer.effect(RunEventDrain, Effect$1.gen(function* () {
5531
5413
  const stdio = yield* Stdio.Stdio;
5532
5414
  return RunEventDrain.of({
5533
- drainFramed: (framed) => drainOf(stdio, framed),
5415
+ drainFramed: (framed, toStdout) => drainOf(stdio, framed, toStdout),
5534
5416
  setProgressStreamFile: () => Effect$1.void
5535
5417
  });
5536
5418
  }));
@@ -5543,25 +5425,29 @@ var RunEventDrain = class RunEventDrain extends Context.Service()("@systemfsoftw
5543
5425
  };
5544
5426
  const RunEventDrainLive = RunEventDrain.layer;
5545
5427
  const encodeUtf8 = (line) => new TextEncoder().encode(line);
5546
- const drainStdoutAndFile = (fs, path, stdio, fileName, framed) => Effect$1.gen(function* () {
5428
+ const runToSink = (stdio, lines, toStdout) => Boolean$1.match(toStdout, {
5429
+ onTrue: () => Stream.run(lines, stdio.stdout({ endOnDone: true })),
5430
+ onFalse: () => Stream.runDrain(lines)
5431
+ });
5432
+ const drainToSinks = (fs, path, stdio, fileName, toStdout, framed) => Effect$1.gen(function* () {
5547
5433
  yield* fs.makeDirectory(path.dirname(fileName), { recursive: true });
5548
5434
  yield* Effect$1.scoped(Effect$1.gen(function* () {
5549
5435
  const handle = yield* fs.open(fileName, { flag: "w" });
5550
5436
  const withFile = framed.pipe(Stream.tap((line) => handle.writeAll(encodeUtf8(line)).pipe(Effect$1.flatMap(() => handle.sync))));
5551
- yield* Stream.run(withFile, stdio.stdout({ endOnDone: true })).pipe(Effect$1.ignore);
5437
+ yield* runToSink(stdio, withFile, toStdout).pipe(Effect$1.ignore);
5552
5438
  }));
5553
5439
  }).pipe(Effect$1.orDie);
5554
5440
  const drainFileOf = (stdio, fs, path) => Effect$1.gen(function* () {
5555
5441
  const fileNameRef = yield* Ref.make(DEFAULT_PROGRESS_STREAM_FILE);
5556
5442
  return RunEventDrain.of({
5557
- drainFramed: (framed) => Effect$1.gen(function* () {
5443
+ drainFramed: (framed, toStdout) => Effect$1.gen(function* () {
5558
5444
  const fileName = yield* Ref.get(fileNameRef);
5559
- yield* drainStdoutAndFile(fs, path, stdio, fileName, framed);
5445
+ yield* drainToSinks(fs, path, stdio, fileName, toStdout, framed);
5560
5446
  }).pipe(Effect$1.tapCause((cause) => Effect$1.logError("stryker.output.drain_file_failed", cause)), Effect$1.ignoreCause),
5561
5447
  setProgressStreamFile: (fileName) => Ref.set(fileNameRef, fileName)
5562
5448
  });
5563
5449
  });
5564
- const drainOf = (stdio, framed) => Stream.run(framed, stdio.stdout({ endOnDone: true })).pipe(Effect$1.withSpan("stryker.output.drain"), Effect$1.tapCause((cause) => Effect$1.logError("stryker.output.drain_failed", cause)), Effect$1.ignoreCause);
5450
+ const drainOf = (stdio, framed, toStdout) => runToSink(stdio, framed, toStdout).pipe(Effect$1.withSpan("stryker.output.drain"), Effect$1.tapCause((cause) => Effect$1.logError("stryker.output.drain_failed", cause)), Effect$1.ignoreCause);
5565
5451
  const writeStderr = (stdio, line) => Stream.run(Stream.succeed(`${line}\n`), stdio.stderr({ endOnDone: false })).pipe(Effect$1.ignore);
5566
5452
  const emitNullScoreVerdict = (params) => {
5567
5453
  const { stream, mode, thresholds, basePath, pathService } = params;
@@ -5708,7 +5594,8 @@ const makeRunEventStream = (resolved) => Effect$1.gen(function* () {
5708
5594
  open: Effect$1.gen(function* () {
5709
5595
  yield* Option$1.match(yield* Ref.get(drainFiberRef), {
5710
5596
  onNone: () => Effect$1.gen(function* () {
5711
- const drainFiber = yield* drain.drainFramed(framed).pipe(Effect$1.forkDetach);
5597
+ const mode = (yield* Ref.get(stateRef)).mode;
5598
+ const drainFiber = yield* drain.drainFramed(framed, mode === "machine").pipe(Effect$1.forkDetach);
5712
5599
  yield* Ref.set(drainFiberRef, Option$1.some(drainFiber));
5713
5600
  }),
5714
5601
  onSome: () => Effect$1.void
@@ -5730,7 +5617,11 @@ const makeRunEventStream = (resolved) => Effect$1.gen(function* () {
5730
5617
  var DryRunError = class extends S.TaggedError()("DryRunError", {
5731
5618
  stage: S.Literals(["dryRun", "dryRunNoTests"]),
5732
5619
  reason: S.String
5733
- }) {};
5620
+ }) {
5621
+ get message() {
5622
+ return this.reason;
5623
+ }
5624
+ };
5734
5625
  var FailedTestSummary = class extends S.Class("FailedTestSummary")({
5735
5626
  name: S.String,
5736
5627
  failureMessage: S.String
@@ -5865,6 +5756,15 @@ const originalFileFor = dual(2, (self, sandboxFileName) => {
5865
5756
  const slot = SandboxHandle.slot(self);
5866
5757
  return originalFileNameOf(sandboxFileName, self.workingDirectory, slot.basePath, slot.pathService);
5867
5758
  });
5759
+ const VM_RUNNER_SPECIFIER = "@systemfsoftware/stryker-js-vm-runner";
5760
+ const vmRunnerOptions = { pool: "threads" };
5761
+ const vmRunnerPluginUrl = () => import.meta.resolve(VM_RUNNER_SPECIFIER);
5762
+ const isVmRunner = (name) => typeof name === "string" && name.toLowerCase() === "vm";
5763
+ const vmTestRunnerConfig = () => ({
5764
+ plugin: vmRunnerPluginUrl(),
5765
+ options: { ...vmRunnerOptions }
5766
+ });
5767
+ const testRunnerConfigOf = (configured) => Match.value(configured).pipe(Match.when(isVmRunner, vmTestRunnerConfig), Match.orElse((unchanged) => unchanged));
5868
5768
  //#endregion
5869
5769
  //#region src/TestRunner.blueprint.ts
5870
5770
  const TypeId$2 = Symbol.for("~systemfsoftware/stryker-js/TestRunner");
@@ -5891,11 +5791,15 @@ const toRunnerFailure = (runnerName, phase) => (error) => Match.value(error).pip
5891
5791
  * can see.
5892
5792
  */
5893
5793
  const scopedOf = (params) => Effect$1.gen(function* () {
5894
- const runnerName = Match.value(params.options.testRunner).pipe(Match.when(Options_exports.isCustomTestRunner, (runner) => runner.plugin), Match.orElse((name) => name));
5895
- const execArgv = Match.value(params.options.testRunner).pipe(Match.when(Options_exports.isCustomTestRunner, (runner) => Match.value(runner.nodeArgs).pipe(Match.when(Match.undefined, () => params.options.testRunnerNodeArgs), Match.orElse((args) => args))), Match.orElse(() => params.options.testRunnerNodeArgs));
5794
+ const options = {
5795
+ ...params.options,
5796
+ testRunner: testRunnerConfigOf(params.options.testRunner)
5797
+ };
5798
+ const runnerName = Match.value(options.testRunner).pipe(Match.when(Options_exports.isCustomTestRunner, (runner) => runner.plugin), Match.orElse((name) => name));
5799
+ const execArgv = Match.value(options.testRunner).pipe(Match.when(Options_exports.isCustomTestRunner, (runner) => Match.value(runner.nodeArgs).pipe(Match.when(Match.undefined, () => options.testRunnerNodeArgs), Match.orElse((args) => args))), Match.orElse(() => options.testRunnerNodeArgs));
5896
5800
  const client = yield* makeWorkerClient({
5897
5801
  rpcs: Plugin_exports.TestRunnerRpcs,
5898
- options: params.options,
5802
+ options,
5899
5803
  entrypoint: params.workerEntrypoint,
5900
5804
  workingDirectory: params.sandboxWorkingDirectory,
5901
5805
  execArgv: [...execArgv],
@@ -5919,10 +5823,7 @@ const TestRunners = Blueprint.make()(TypeId$2).steps({
5919
5823
  });
5920
5824
  const makeChildProcessTestRunner = (params) => TestRunners.of(params).scoped;
5921
5825
  const commandRunnerEffect = (context) => ChildProcessSpawner.ChildProcessSpawner.pipe(Effect$1.map((spawner) => commandRunner(context, spawner).pipe(withTimeout, withRetry)));
5922
- const inProcessRunner = (context) => Match.value(context.options.testRunner).pipe(Match.when(isCommandRunner, () => Option$1.some(commandRunnerEffect(context))), Match.when(isVmRunner, () => Option$1.some(vmTestRunner({
5923
- testFiles: context.testFiles,
5924
- sandboxWorkingDirectory: context.sandboxWorkingDirectory
5925
- }))), Match.orElse(() => Option$1.none()));
5826
+ const inProcessRunner = (context) => Match.value(context.options.testRunner).pipe(Match.when(isCommandRunner, () => Option$1.some(commandRunnerEffect(context))), Match.orElse(() => Option$1.none()));
5926
5827
  const buildTestRunner = dual(2, (context, childProcessRunner) => Option$1.match(inProcessRunner(context), {
5927
5828
  onSome: (inProcess) => inProcess,
5928
5829
  onNone: () => Effect$1.gen(function* () {
@@ -6081,7 +5982,7 @@ const resolveConfiguredPlugin = Workflow.make({
6081
5982
  //#endregion
6082
5983
  //#region src/run/dry-run.parts.ts
6083
5984
  const sandboxPathsOf = (sandbox, fileNames) => Result.all(fileNames.map((fileName) => sandboxFileFor(sandbox, fileName)));
6084
- const configuredPluginOf$1 = (configured) => Match.value(configured).pipe(Match.when(Options_exports.isCustomTestRunner, (custom) => ConfiguredPluginModulePath.make({ modulePath: custom.plugin })), Match.orElse((name) => ConfiguredPluginName.make({ name })));
5985
+ const configuredPluginOf$1 = (configured) => Match.value(testRunnerConfigOf(configured)).pipe(Match.when(Options_exports.isCustomTestRunner, (custom) => ConfiguredPluginModulePath.make({ modulePath: custom.plugin })), Match.orElse((name) => ConfiguredPluginName.make({ name })));
6085
5986
  const workerSpawnOf$1 = (stage, loaded, kind, configured) => Effect$1.mapError(Effect$1.fromResult(resolveConfiguredPlugin(WorkerSpawnCommand.make({
6086
5987
  sources: loaded.pluginSources,
6087
5988
  kind,
@@ -6095,7 +5996,11 @@ const optionalSandboxPathsOf = (command) => Boolean$1.match(command.options.test
6095
5996
  onTrue: () => Result.succeed(void 0),
6096
5997
  onFalse: () => sandboxPathsOf(command.sandbox, command.project.testFiles)
6097
5998
  });
6098
- const buildDryRunFiles = (command) => Result.flatMap(sandboxPathsOf(command.sandbox, [...MutableHashMap.keys(command.project.filesToMutate)]), (files) => Result.map(optionalSandboxPathsOf(command), (testFiles) => ({
5999
+ const mutatedFileNamesOf = (command) => {
6000
+ const mutated = MutableHashSet.fromIterable(command.mutants.map((mutant) => mutant.fileName));
6001
+ return [...MutableHashMap.keys(command.project.filesToMutate)].filter((name) => MutableHashSet.has(mutated, name));
6002
+ };
6003
+ const buildDryRunFiles = (command) => Result.flatMap(sandboxPathsOf(command.sandbox, mutatedFileNamesOf(command)), (files) => Result.map(optionalSandboxPathsOf(command), (testFiles) => ({
6099
6004
  files,
6100
6005
  testFiles
6101
6006
  })));
@@ -6326,14 +6231,11 @@ const dryRunCell = Sandwich.named("stryker.dry_run")(readDryRun).decide(dryRun).
6326
6231
  });
6327
6232
  //#endregion
6328
6233
  //#region src/plan-instrumentation.workflow.ts
6329
- var InstrumentError = class extends S.TaggedError()("InstrumentError", {
6330
- stage: S.Literal("instrument"),
6331
- reason: S.String
6332
- }) {};
6234
+ const Count = S.Int.check(S.isGreaterThanOrEqualTo(0));
6333
6235
  var InstrumentCommand = class extends S.TaggedClass()("InstrumentCommand", {
6334
- fileCount: S.Finite,
6236
+ fileCount: Count,
6335
6237
  inPlace: S.Boolean,
6336
- pluginCount: S.Finite
6238
+ pluginCount: Count
6337
6239
  }) {
6338
6240
  static [Workflow.InstrumentationBrand] = {
6339
6241
  fileCount: "stryker.instrument.file_count",
@@ -6344,32 +6246,28 @@ const InstrumentDecisionTypeId = Symbol.for("@systemfsoftware/stryker-js/Instrum
6344
6246
  var InPlaceInstrument = class extends S.TaggedClass()("InPlaceInstrument", {
6345
6247
  workingDirectoryHint: S.String,
6346
6248
  backupDirectoryHint: S.String,
6347
- fileCount: S.Finite
6249
+ fileCount: Count
6348
6250
  }) {
6349
6251
  [InstrumentDecisionTypeId] = InstrumentDecisionTypeId;
6350
6252
  };
6351
6253
  var EphemeralInstrument = class extends S.TaggedClass()("EphemeralInstrument", {
6352
6254
  workingDirectoryHint: S.String,
6353
- fileCount: S.Finite
6255
+ fileCount: Count
6354
6256
  }) {
6355
6257
  [InstrumentDecisionTypeId] = InstrumentDecisionTypeId;
6356
6258
  };
6357
- const commandShape = (command) => Match.value(command.fileCount === 0).pipe(Match.when(true, () => "empty"), Match.when(false, () => Match.value(command.inPlace).pipe(Match.when(true, () => "inPlace"), Match.when(false, () => "ephemeral"), Match.exhaustive)), Match.exhaustive);
6358
- const decide$3 = (command) => Match.value(commandShape(command)).pipe(Match.when("empty", () => Result.fail(InstrumentError.make({
6359
- stage: "instrument",
6360
- reason: "No files to instrument."
6361
- }))), Match.when("inPlace", () => Result.succeed(InPlaceInstrument.make({
6259
+ const decide$3 = (command) => Match.value(command.inPlace).pipe(Match.when(true, () => Result.succeed(InPlaceInstrument.make({
6362
6260
  workingDirectoryHint: "inPlace",
6363
6261
  backupDirectoryHint: "backup",
6364
6262
  fileCount: command.fileCount
6365
- }))), Match.when("ephemeral", () => Result.succeed(EphemeralInstrument.make({
6263
+ }))), Match.when(false, () => Result.succeed(EphemeralInstrument.make({
6366
6264
  workingDirectoryHint: "temp",
6367
6265
  fileCount: command.fileCount
6368
6266
  }))), Match.exhaustive);
6369
6267
  const planInstrumentation = Workflow.make({
6370
6268
  command: InstrumentCommand,
6371
6269
  decision: S.Union([InPlaceInstrument, EphemeralInstrument]),
6372
- error: InstrumentError,
6270
+ error: S.Never,
6373
6271
  decide: decide$3
6374
6272
  });
6375
6273
  //#endregion
@@ -7117,14 +7015,6 @@ const instrumentCell = Sandwich.named("stryker.instrument")((command) => Effect$
7117
7015
  })).decide(planInstrumentation).write({
7118
7016
  InPlaceInstrument: (_decision, raw) => writeInstrument(raw),
7119
7017
  EphemeralInstrument: (_decision, raw) => writeInstrument(raw),
7120
- InstrumentError: ({ stage, reason }, raw) => enteringInstrumentPhase(raw, Effect$1.fail(StageError.make({
7121
- stage,
7122
- reason,
7123
- cause: InstrumentError.make({
7124
- stage,
7125
- reason
7126
- })
7127
- }))),
7128
7018
  CommandRejected: ({ issue }) => Effect$1.fail(StageError.make({
7129
7019
  stage: "instrument",
7130
7020
  reason: issue
@@ -7149,7 +7039,11 @@ var MutationTestCommand = class extends S.TaggedClass()("MutationTestCommand", {
7149
7039
  var MutationTestError = class extends S.TaggedError()("MutationTestError", {
7150
7040
  stage: S.Literal("mutationTest"),
7151
7041
  reason: S.String
7152
- }) {};
7042
+ }) {
7043
+ get message() {
7044
+ return this.reason;
7045
+ }
7046
+ };
7153
7047
  const MutationTestDecisionTypeId = Symbol.for("@systemfsoftware/stryker-js/MutationTestDecision");
7154
7048
  var MutationTestProceed = class extends S.TaggedClass()("MutationTestProceed", {}) {
7155
7049
  [MutationTestDecisionTypeId] = MutationTestDecisionTypeId;
@@ -7586,8 +7480,9 @@ const toReportedMutant = (mutant) => Object.assign(mutant, {
7586
7480
  static: mutant.static
7587
7481
  });
7588
7482
  const CHECKER_ACQUIRE_RETRIES = 2;
7483
+ const TEST_RUNNER_POOL_IDLE_TIME_TO_LIVE = Duration.minutes(1);
7589
7484
  const isCheckerCrash = (error) => Match.value(error).pipe(Match.tag("ChildProcessCrashedError", "OutOfMemoryError", () => true), Match.orElse(() => false));
7590
- const configuredPluginOf = (configured) => Match.value(configured).pipe(Match.when(Options_exports.isCustomTestRunner, (custom) => ConfiguredPluginModulePath.make({ modulePath: custom.plugin })), Match.orElse((name) => ConfiguredPluginName.make({ name })));
7485
+ const configuredPluginOf = (configured) => Match.value(testRunnerConfigOf(configured)).pipe(Match.when(Options_exports.isCustomTestRunner, (custom) => ConfiguredPluginModulePath.make({ modulePath: custom.plugin })), Match.orElse((name) => ConfiguredPluginName.make({ name })));
7591
7486
  const workerSpawnOf = (stage, loaded, kind, configured) => Effect$1.mapError(Effect$1.fromResult(resolveConfiguredPlugin(WorkerSpawnCommand.make({
7592
7487
  sources: loaded.pluginSources,
7593
7488
  kind,
@@ -7781,13 +7676,17 @@ const checkerBreachToStageError = (error) => Match.value(error).pipe(Match.tag("
7781
7676
  cause: breach
7782
7677
  })), Match.exhaustive);
7783
7678
  const invalidateSlot = (pool, slot, error) => Effect$1.flatMap(Pool.invalidate(pool, slot), () => Effect$1.fail(error));
7784
- const checkSlotPlans = (pool, slot, checker, checkerName, currentPlans) => checkGroupedPlans(checker, checkerName, currentPlans).pipe(Effect$1.catchTags({
7785
- OutOfMemoryError: (error) => invalidateSlot(pool, slot, error),
7786
- ChildProcessCrashedError: (error) => invalidateSlot(pool, slot, error),
7787
- CheckerFailed: (error) => error.pipe(checkerBreachToStageError, Effect$1.fail),
7788
- CheckerAnsweredUnrequested: (error) => error.pipe(checkerBreachToStageError, Effect$1.fail),
7789
- CheckerSkippedRequested: (error) => error.pipe(checkerBreachToStageError, Effect$1.fail)
7679
+ const onCheckerSlot = (pool, checkerIndex, run) => Pool.use(pool, (slot) => Option$1.match(Option$1.fromUndefinedOr(slot[checkerIndex]), {
7680
+ onNone: () => Effect$1.die(/* @__PURE__ */ new Error(`checker slot has no entry at index ${checkerIndex}`)),
7681
+ onSome: ({ checker }) => run(checker).pipe(Effect$1.catchTags({
7682
+ OutOfMemoryError: (error) => invalidateSlot(pool, slot, error),
7683
+ ChildProcessCrashedError: (error) => invalidateSlot(pool, slot, error),
7684
+ CheckerFailed: (error) => error.pipe(checkerBreachToStageError, Effect$1.fail),
7685
+ CheckerAnsweredUnrequested: (error) => error.pipe(checkerBreachToStageError, Effect$1.fail),
7686
+ CheckerSkippedRequested: (error) => error.pipe(checkerBreachToStageError, Effect$1.fail)
7687
+ }))
7790
7688
  }));
7689
+ const checkGroupsConcurrently = (pool, checkerIndex, checkerName, currentPlans) => Effect$1.flatMap(onCheckerSlot(pool, checkerIndex, (checker) => groupPlans(checker, checkerName, currentPlans)), (groups) => Effect$1.map(Effect$1.forEach(groups, (group) => onCheckerSlot(pool, checkerIndex, (checker) => checkPlans(checker, checkerName, group)), { concurrency: "unbounded" }), (perGroup) => perGroup.flat()));
7791
7690
  const isFailedCheck = (check) => check[1].status !== "passed";
7792
7691
  const splitCheckedPlans = (checked, reporting) => {
7793
7692
  const failures = checked.filter(isFailedCheck);
@@ -7797,18 +7696,15 @@ const splitCheckedPlans = (checked, reporting) => {
7797
7696
  results
7798
7697
  }));
7799
7698
  };
7800
- const stepOneChecker = (pool, slot, checker, checkerName, currentPlans, reporting) => checkSlotPlans(pool, slot, checker, checkerName, currentPlans).pipe(Effect$1.flatMap((checked) => splitCheckedPlans(checked, reporting)));
7699
+ const stepOneChecker = (pool, checkerIndex, checkerName, currentPlans, reporting) => checkGroupsConcurrently(pool, checkerIndex, checkerName, currentPlans).pipe(Effect$1.flatMap((checked) => splitCheckedPlans(checked, reporting)));
7801
7700
  const emptyRunResults = [];
7802
- const runConfiguredCheckers = (pool, plans, reporting) => Effect$1.scoped(Effect$1.gen(function* () {
7803
- const slot = yield* Pool.get(pool);
7804
- return yield* Effect$1.reduce(slot, () => ({
7805
- passedPlans: plans,
7806
- checkerResults: emptyRunResults
7807
- }), (acc, { checkerName, checker }) => Effect$1.map(stepOneChecker(pool, slot, checker, checkerName, acc.passedPlans, reporting), (split) => ({
7808
- passedPlans: split.passed,
7809
- checkerResults: [...acc.checkerResults, ...split.results]
7810
- })));
7811
- }));
7701
+ const runConfiguredCheckers = (pool, plans, reporting) => Effect$1.flatMap(Pool.use(pool, (slot) => Effect$1.succeed(slot.map(({ checkerName }) => checkerName))), (checkerNames) => Effect$1.reduce(checkerNames, () => ({
7702
+ passedPlans: plans,
7703
+ checkerResults: emptyRunResults
7704
+ }), (acc, checkerName, checkerIndex) => Effect$1.map(stepOneChecker(pool, checkerIndex, checkerName, acc.passedPlans, reporting), (split) => ({
7705
+ passedPlans: split.passed,
7706
+ checkerResults: [...acc.checkerResults, ...split.results]
7707
+ }))));
7812
7708
  const checkPlansWithConfiguredCheckers = (checkerPool, plans, reporting) => Option$1.match(Option$1.fromNullishOr(checkerPool), {
7813
7709
  onNone: () => Effect$1.succeed({
7814
7710
  passedPlans: plans,
@@ -7816,6 +7712,14 @@ const checkPlansWithConfiguredCheckers = (checkerPool, plans, reporting) => Opti
7816
7712
  }),
7817
7713
  onSome: (pool) => runConfiguredCheckers(pool, plans, reporting)
7818
7714
  });
7715
+ const checkerResourcesInOwnScope = (acquire) => Effect$1.gen(function* () {
7716
+ const checkerScope = yield* Scope.make();
7717
+ yield* Effect$1.addFinalizer(() => Scope.close(checkerScope, Exit.void));
7718
+ return {
7719
+ resources: yield* acquire.pipe(Scope.provide(checkerScope)),
7720
+ releaseInBackground: Scope.close(checkerScope, Exit.void).pipe(Effect$1.forkScoped({ uninterruptible: true }))
7721
+ };
7722
+ });
7819
7723
  const isPlannable = (mutant) => Result.isSuccess(S.decodeResult(CheckerMutantFromMutant)(mutant));
7820
7724
  const DROPPED_IDS_IN_WARNING = 5;
7821
7725
  const configuredTestFilesOf = (run) => run.options.testFiles.length === 0 ? [] : run.project.testFiles;
@@ -7861,14 +7765,15 @@ const writeMutationTestDryRunOnly = Effect$1.gen(function* () {
7861
7765
  });
7862
7766
  const writeMutationTestProceed = (raw) => Effect$1.gen(function* () {
7863
7767
  const prev = raw.prev;
7768
+ const testRunnerCapacity = prev.concurrency.testRunners + prev.concurrency.checkers;
7864
7769
  const { dropped, plannable: plannableMutants } = partitionPlannable(prev.mutants);
7865
7770
  yield* reportDroppedMutants(dropped);
7866
7771
  yield* phaseEntered("mutation-test");
7867
7772
  const idGenerator = yield* IdGenerator;
7868
7773
  const env = yield* RunEnvironment;
7869
- const checkerPool = yield* makeCheckerPool(prev, env.basePath);
7774
+ const scopedCheckers = yield* checkerResourcesInOwnScope(makeCheckerPool(prev, env.basePath));
7870
7775
  const testFiles = yield* Effect$1.map(sandboxFilesOf(prev.sandbox, configuredTestFilesOf(prev)), (pairs) => pairs.map(([, sandboxFileName]) => sandboxFileName));
7871
- const testRunnerPool = yield* Pool.make({
7776
+ const testRunnerPool = yield* Pool.makeWithTTL({
7872
7777
  acquire: buildTestRunner({
7873
7778
  options: prev.options,
7874
7779
  fileDescriptions: prev.project.fileDescriptions,
@@ -7886,7 +7791,9 @@ const writeMutationTestProceed = (raw) => Effect$1.gen(function* () {
7886
7791
  idGenerator
7887
7792
  })));
7888
7793
  })),
7889
- size: prev.concurrency.testRunners
7794
+ min: prev.concurrency.testRunners,
7795
+ max: testRunnerCapacity,
7796
+ timeToLive: TEST_RUNNER_POOL_IDLE_TIME_TO_LIVE
7890
7797
  });
7891
7798
  const reporting = yield* MutationReporting;
7892
7799
  const sandboxFileByName = Object.fromEntries(yield* sandboxFilesOf(prev.sandbox, [...MutableHashMap.keys(prev.project.filesToMutate)]));
@@ -7929,7 +7836,8 @@ const writeMutationTestProceed = (raw) => Effect$1.gen(function* () {
7929
7836
  })).pipe(Effect$1.ignoreCause);
7930
7837
  const progressQueue = yield* RunEvents;
7931
7838
  yield* Queue.offer(progressQueue, PlanKnown.make({ total: allPlansForReporter.length + noCoverageResults.length }));
7932
- const { passedPlans, checkerResults } = yield* checkPlansWithConfiguredCheckers(checkerPool, sortedPlans, reporting);
7839
+ const { passedPlans, checkerResults } = yield* checkPlansWithConfiguredCheckers(scopedCheckers.resources, sortedPlans, reporting);
7840
+ const checkerRelease = yield* scopedCheckers.releaseInBackground;
7933
7841
  const testRunnerStream = Stream.fromIterable(passedPlans);
7934
7842
  const plannedTotal = sortedPlans.length + noCoverageResults.length + rememberedResults.length;
7935
7843
  const completedRef = yield* Ref.make(0);
@@ -8030,7 +7938,7 @@ const writeMutationTestProceed = (raw) => Effect$1.gen(function* () {
8030
7938
  yield* offerStreamTested(reported, finished, prepared);
8031
7939
  yield* persist(reported);
8032
7940
  return reported;
8033
- })), { concurrency: Math.max(1, prev.concurrency.testRunners) }).pipe(Stream.runCollect, Effect$1.map((chunk) => [...chunk])));
7941
+ })), { concurrency: Math.max(1, testRunnerCapacity) }).pipe(Stream.runCollect, Effect$1.map((chunk) => [...chunk])));
8034
7942
  const allResults = [
8035
7943
  ...rememberedResults,
8036
7944
  ...noCoverageResults,
@@ -8038,6 +7946,7 @@ const writeMutationTestProceed = (raw) => Effect$1.gen(function* () {
8038
7946
  ...runResults
8039
7947
  ];
8040
7948
  const outcomeResult = yield* reporting.reportAll(reportingInputOf(prev, env, allResults));
7949
+ yield* Fiber.await(checkerRelease);
8041
7950
  const doneNow = yield* Clock.currentTimeMillis;
8042
7951
  const elapsed = Duration.millis(doneNow - env.runStartedAt);
8043
7952
  yield* Effect$1.logInfo(`Done in ${Duration.format(elapsed)}.`);
@@ -8517,7 +8426,7 @@ const pluginUrlsFromOptions = (options) => [
8517
8426
  ...options.plugins,
8518
8427
  ...options.appendPlugins,
8519
8428
  ...options.ignorers,
8520
- ...Match.value(options.testRunner).pipe(Match.when(Options_exports.isCustomTestRunner, (runner) => [runner.plugin]), Match.orElse(() => [])),
8429
+ ...Match.value(options.testRunner).pipe(Match.when(Options_exports.isCustomTestRunner, (runner) => [runner.plugin]), Match.when(isVmRunner, () => [vmRunnerPluginUrl()]), Match.orElse(() => [])),
8521
8430
  ...options.checkers.map((checker) => checker.plugin)
8522
8431
  ];
8523
8432
  //#endregion
@@ -8817,4 +8726,4 @@ const strykerCell = dual((args) => Predicate$1.isObject(args[0]), (options, targ
8817
8726
  })
8818
8727
  })), Effect$1.scoped));
8819
8728
  //#endregion
8820
- export { ExtendsStepResolve as $, VerdictMutant as A, FileMatcher as B, mergeConfigs as C, RunEvents as D, IdGenerator as E, makeWorkerClient as F, ConfigFileUnsupportedError as G, ConfigFileInvalidError as H, WorkerLauncher as I, ConfigDocumentSchema as J, createDefaultOptions as K, make$2 as L, MetricsResultFromReport as M, reporterWorkerFactory as N, RunIdentity as O, spawnReporterWorker as P, ExtendsStepRefused as Q, StrykerError as R, initialExtendsStepState as S, RunEnvironment as T, ConfigFileNotFoundError as U, ConfigError as V, ConfigFileUnreadableError as W, ExtendsStepDone as X, ExtendsStepDocumentSchema as Y, ExtendsStepRead as Z, readConfig as _, RunEventDrainLive as a, extendsPropertySchema as at, forkCoreSchema as b, isVmRunner as c, checkGroupedPlans as ct, nodePlatformLayer as d, WorkerBootTimeoutError as dt, ExtendsStepStateSchema as et, layerWorkerProtocol as f, CheckerAnsweredUnrequested as ft, loadConfigCell as g, classifyWorkerExit as h, RunEventDrain as i, ReadConfigCommand as it, VerdictThresholds as j, VerdictEnvelope as k, vmTestRunner as l, ChildProcessCrashedError as lt, ClassifyWorkerExitDecision as m, strykerCell as n, MergeCommand as nt, makeRunEventStream as o, forkOptionsSchema as ot, ClassifyWorkerExitCommand as p, CheckerSkippedRequested as pt, defaultOptions as q, buildTestRunner as r, MergeResult as rt, RunEventWireLine as s, survivorsPriorReport as st, mutationTestCell as t, ImportedModuleSchema as tt, IncrementalReportSchema as u, OutOfMemoryError as ut, decideExtendsStep as v, validateOptions as w, importModule as x, describeErrors as y, isCommandRunner as z };
8729
+ export { ExtendsStepDone as $, RunEvents as A, make$2 as B, forkCoreSchema as C, validateOptions as D, mergeConfigs as E, MetricsResultFromReport as F, ConfigFileInvalidError as G, isCommandRunner as H, reporterWorkerFactory as I, ConfigFileUnsupportedError as J, ConfigFileNotFoundError as K, spawnReporterWorker as L, VerdictEnvelope as M, VerdictMutant as N, RunEnvironment as O, VerdictThresholds as P, ExtendsStepDocumentSchema as Q, makeWorkerClient as R, describeErrors as S, initialExtendsStepState as T, FileMatcher as U, StrykerError as V, ConfigError as W, defaultOptions as X, createDefaultOptions as Y, ConfigDocumentSchema as Z, ClassifyWorkerExitDecision as _, isVmRunner as a, MergeCommand as at, readConfig as b, vmTestRunnerConfig as c, extendsPropertySchema as ct, makeRunEventStream as d, checkGroupedPlans as dt, ExtendsStepRead as et, RunEventWireLine as f, ChildProcessCrashedError as ft, ClassifyWorkerExitCommand as g, CheckerSkippedRequested as gt, layerWorkerProtocol as h, CheckerAnsweredUnrequested as ht, makeChildProcessTestRunner as i, ImportedModuleSchema as it, RunIdentity as j, IdGenerator as k, RunEventDrain as l, forkOptionsSchema as lt, nodePlatformLayer as m, WorkerBootTimeoutError as mt, strykerCell as n, ExtendsStepResolve as nt, testRunnerConfigOf as o, MergeResult as ot, IncrementalReportSchema as p, OutOfMemoryError as pt, ConfigFileUnreadableError as q, buildTestRunner as r, ExtendsStepStateSchema as rt, vmRunnerPluginUrl as s, ReadConfigCommand as st, mutationTestCell as t, ExtendsStepRefused as tt, RunEventDrainLive as u, survivorsPriorReport as ut, classifyWorkerExit as v, importModule as w, decideExtendsStep as x, loadConfigCell as y, WorkerLauncher as z };