@systemfsoftware/stryker-js 16.0.1 → 17.0.1

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 { i as mod_d_exports$5 } from "./index-DEphx668.mjs";
1
+ import { i as mod_d_exports$5 } from "./index-y-Pg3XgT.mjs";
2
2
  import * as S from "effect/Schema";
3
3
  //#region src/config/stryker-config.schema.d.ts
4
4
  type StrykerConfig = mod_d_exports$5.PartialStrykerOptions;
@@ -1032,6 +1032,9 @@ const MutantRunResultSchema = S.Union([
1032
1032
  errorMessage: S.String
1033
1033
  })
1034
1034
  ]);
1035
+ var MutantRunStarted = class extends S.TaggedClass()("MutantRunStarted", {}) {};
1036
+ var MutantRunSettled = class extends S.TaggedClass()("MutantRunSettled", { result: MutantRunResultSchema }) {};
1037
+ const MutantRunEventSchema = S.Union([MutantRunStarted, MutantRunSettled]);
1035
1038
  const CoverageAnalysisSchema = S.Literals([
1036
1039
  "off",
1037
1040
  "all",
@@ -1247,8 +1250,9 @@ const dryRun = Rpc.make("dryRun", {
1247
1250
  }).middleware(TraceContextMiddleware);
1248
1251
  const mutantRun = Rpc.make("mutantRun", {
1249
1252
  payload: TestRunnerMutantRunRequest,
1250
- success: MutantRunResultSchema,
1251
- error: TestRunnerFailed
1253
+ success: MutantRunEventSchema,
1254
+ error: TestRunnerFailed,
1255
+ stream: true
1252
1256
  }).middleware(TraceContextMiddleware);
1253
1257
  const check = Rpc.make("check", {
1254
1258
  payload: CheckerRequest,
@@ -1399,7 +1403,10 @@ var TestRunner_exports = /* @__PURE__ */ __exportAll({
1399
1403
  HitLimitReason: () => HitLimitReason,
1400
1404
  HitLimitReasonPrefix: () => HitLimitReasonPrefix,
1401
1405
  HitLimitReasonText: () => HitLimitReasonText,
1406
+ MutantRunEventSchema: () => MutantRunEventSchema,
1402
1407
  MutantRunResultSchema: () => MutantRunResultSchema,
1408
+ MutantRunSettled: () => MutantRunSettled,
1409
+ MutantRunStarted: () => MutantRunStarted,
1403
1410
  MutantRunStatus: () => MutantRunStatus,
1404
1411
  TestId: () => TestId,
1405
1412
  TestResultSchema: () => TestResultSchema,
@@ -1,5 +1,5 @@
1
- import { i as mod_d_exports$5 } from "./index-DEphx668.mjs";
2
- import { l as MutationTestDone } from "./RunEnvironment.service-F8LgeCqh.mjs";
1
+ import { i as mod_d_exports$5 } from "./index-y-Pg3XgT.mjs";
2
+ import { l as MutationTestDone } from "./RunEnvironment.service-Cluh-Bxt.mjs";
3
3
  //#region src/drivers/promise.d.ts
4
4
  export declare const run: ((targetMutatePatterns?: readonly string[]) => (options: mod_d_exports$5.PartialStrykerOptions) => Promise<MutationTestDone>) & ((options: mod_d_exports$5.PartialStrykerOptions, targetMutatePatterns?: readonly string[]) => Promise<MutationTestDone>);
5
5
  //#endregion
package/dist/promises.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { C as nodePlatformLayer, t as strykerCell } from "./run-stages-DYuRm353.mjs";
1
+ import { C as nodePlatformLayer, t as strykerCell } from "./run-stages-CpYiJ2Mz.mjs";
2
2
  import * as Effect from "effect/Effect";
3
3
  import { dual } from "effect/Function";
4
4
  //#region src/drivers/promise.ts
@@ -1,5 +1,5 @@
1
1
  import { t as __exportAll$4 } from "./rolldown-runtime-8H4AJuhK.mjs";
2
- import { a as MutatorCatalog_exports, c as Plugin_exports, d as TestRunner_exports, f as Trace_exports$1, i as Mutant_exports, l as Report_exports, n as mergeConfigs, o as MutatorProvider_exports, r as Checker_exports, s as Options_exports, t as mergeConfig, u as Reporter_exports } from "./merge-config-BYhhPA7r.mjs";
2
+ import { a as MutatorCatalog_exports, c as Plugin_exports, d as TestRunner_exports, f as Trace_exports$1, i as Mutant_exports, l as Report_exports, n as mergeConfigs, o as MutatorProvider_exports, r as Checker_exports, s as Options_exports, t as mergeConfig, u as Reporter_exports } from "./merge-config-ruui2TPS.mjs";
3
3
  import { n as StageError, t as PrepareError } from "./Run.schema-DuaneDGd.mjs";
4
4
  import { Blueprint, Cell, Handle, Sandwich, Workflow } from "@systemfsoftware/effect-cell-types";
5
5
  import * as S from "effect/Schema";
@@ -11346,7 +11346,7 @@ const strykerOutputFilesOf = (options) => [
11346
11346
  ];
11347
11347
  //#endregion
11348
11348
  //#region package.json
11349
- var version = "16.0.1";
11349
+ var version = "17.0.1";
11350
11350
  //#endregion
11351
11351
  //#region src/stryker-package.schema.ts
11352
11352
  var StrykerPackage = class extends S.Class("StrykerPackage")({
@@ -11835,7 +11835,7 @@ const writeIncrementalReport = Effect$1.fn(SpanTaxonomy_exports.Spans.mutationRe
11835
11835
  const runInputsDigest = yield* runInputsDigestOf(deps.fs, deps.path, input.basePath, input.options);
11836
11836
  const json = yield* S.encodeEffect(S.fromJsonString(S.Unknown, { space: 2 }))({
11837
11837
  incrementalVersion: "3",
11838
- verdictSemanticsVersion: 3,
11838
+ verdictSemanticsVersion: 4,
11839
11839
  mutantSetPolicy: input.options.mutator.mutantSetPolicy,
11840
11840
  runInputsDigest,
11841
11841
  ...report,
@@ -11885,7 +11885,7 @@ const slimIncrementalReport = Effect$1.fn(SpanTaxonomy_exports.Spans.mutationRep
11885
11885
  const runInputsDigest = yield* runInputsDigestOf(deps.fs, deps.path, input.basePath, input.options);
11886
11886
  return {
11887
11887
  incrementalVersion: "3",
11888
- verdictSemanticsVersion: 3,
11888
+ verdictSemanticsVersion: 4,
11889
11889
  mutantSetPolicy: input.options.mutator.mutantSetPolicy,
11890
11890
  runInputsDigest,
11891
11891
  schemaVersion: Report_exports.WrittenSchemaVersion.literal,
@@ -14873,7 +14873,7 @@ const readProject = Effect$1.fn(SpanTaxonomy_exports.Spans.projectReadFromDisk.n
14873
14873
  _tag: "AdmitIncrementalReportCommand",
14874
14874
  report: reportRead.report,
14875
14875
  expectedIncrementalVersion: "3",
14876
- verdictSemanticsVersion: 3,
14876
+ verdictSemanticsVersion: 4,
14877
14877
  mutantSetPolicy: options.mutator.mutantSetPolicy,
14878
14878
  runInputsDigest,
14879
14879
  options,
@@ -15926,6 +15926,43 @@ const make$1 = (runner) => PooledTestRunner.make({
15926
15926
  dryRun: runner.dryRun,
15927
15927
  mutantRun: runner.mutantRun
15928
15928
  });
15929
+ const wallClockTimeoutResult = {
15930
+ status: "timeout",
15931
+ reason: TestRunner_exports.WallClockTimeoutReason.literal
15932
+ };
15933
+ const endedWithoutResult = () => TestRunner_exports.TestRunnerFailed.make({
15934
+ runnerName: "test runner",
15935
+ phase: "mutantRun",
15936
+ cause: "the mutant run ended without reporting a result"
15937
+ });
15938
+ const deadlineArmedMutantRun = dual(2, (events, timeoutMs) => Effect$1.scoped(Effect$1.gen(function* () {
15939
+ const started = yield* Deferred.make();
15940
+ const settled = yield* Deferred.make();
15941
+ const pump = events.pipe(Stream.runForEach((event) => Match$1.value(event).pipe(Match$1.tag("MutantRunStarted", () => Deferred.succeed(started, void 0)), Match$1.tag("MutantRunSettled", ({ result }) => Deferred.succeed(settled, result)), Match$1.exhaustive, Effect$1.asVoid)), Effect$1.onExit((exit) => Exit.match(exit, {
15942
+ onFailure: (cause) => Deferred.failCause(settled, cause),
15943
+ onSuccess: () => Deferred.fail(settled, endedWithoutResult())
15944
+ }).pipe(Effect$1.asVoid)));
15945
+ yield* Effect$1.forkScoped(pump);
15946
+ const deadline = Effect$1.raceFirst(Deferred.await(started).pipe(Effect$1.as(true)), Deferred.await(settled).pipe(Effect$1.as(false))).pipe(Effect$1.timeoutOption(WORKER_BOOT_TIMEOUT), Effect$1.flatMap(Option$1.match({
15947
+ onNone: () => Effect$1.succeed(wallClockTimeoutResult),
15948
+ onSome: (began) => began ? Effect$1.sleep(Duration.millis(timeoutMs)).pipe(Effect$1.as(wallClockTimeoutResult)) : Deferred.await(settled)
15949
+ })));
15950
+ return yield* Effect$1.raceFirst(deadline, Deferred.await(settled));
15951
+ })));
15952
+ /**
15953
+ * The dry run keeps the configured absolute budget. A mutant run is bounded from
15954
+ * its own start by {@link deadlineArmedMutantRun}, so it is not wrapped here.
15955
+ */
15956
+ const withDryRunTimeout = (inner) => make$1({
15957
+ ...inner,
15958
+ dryRun: (options) => inner.dryRun(options).pipe(Effect$1.timeoutOrElse({
15959
+ duration: Duration.millis(options.timeout),
15960
+ orElse: () => Effect$1.succeed({
15961
+ status: "timeout",
15962
+ reason: TestRunner_exports.WallClockTimeoutReason.literal
15963
+ })
15964
+ }))
15965
+ });
15929
15966
  const withTimeout = (inner) => make$1({
15930
15967
  ...inner,
15931
15968
  dryRun: (options) => inner.dryRun(options).pipe(Effect$1.timeoutOrElse({
@@ -16148,7 +16185,7 @@ const scopedOf = Effect$1.fnUntraced(function* (params) {
16148
16185
  capabilities: client.capabilities().pipe(Effect$1.mapError(toRunnerFailure(runnerName, "capabilities"))),
16149
16186
  init: Effect$1.void,
16150
16187
  dryRun: (options) => client.dryRun({ options }).pipe(Effect$1.mapError(toRunnerFailure(runnerName, "dryRun"))),
16151
- mutantRun: (options) => client.mutantRun({ options }).pipe(Effect$1.mapError(toRunnerFailure(runnerName, "mutantRun")))
16188
+ mutantRun: (options) => deadlineArmedMutantRun(client.mutantRun({ options }).pipe(Stream.mapError(toRunnerFailure(runnerName, "mutantRun"))), options.timeout)
16152
16189
  });
16153
16190
  });
16154
16191
  const TestRunners = Blueprint.make()(TypeId$5).steps({
@@ -16160,7 +16197,7 @@ const commandRunnerEffect = (context) => ChildProcessSpawner.ChildProcessSpawner
16160
16197
  const inProcessRunner = (context) => Match$1.value(context.options.testRunner).pipe(Match$1.when(isCommandRunner, () => Option$1.some(commandRunnerEffect(context))), Match$1.orElse(() => Option$1.none()));
16161
16198
  const decorateChildRunner = Effect$1.fnUntraced(function* (context, childProcessRunner) {
16162
16199
  const base = yield* childProcessRunner;
16163
- const timed = withTimeout(base);
16200
+ const timed = withDryRunTimeout(base);
16164
16201
  const limited = yield* withMaxReuse(context.options, context.retire)(timed);
16165
16202
  const reloading = yield* withEnvironmentReload(context.retire)(limited);
16166
16203
  return withRetry(reloading);
@@ -17372,7 +17409,7 @@ const explainFileSkip = Workflow.make({
17372
17409
  decide: (command) => Match$1.value(skipKnownOrUnknownOf(explainedOf(command))).pipe(Match$1.tag("SkipKnownExplained", (known) => Result.succeed(known)), Match$1.tag("SkipUnknownExplained", (unknown) => Result.succeed(unknown)), Match$1.exhaustive)
17373
17410
  });
17374
17411
  //#endregion
17375
- //#region src/run/instrument.cell.ts
17412
+ //#region src/run/instrument.ts
17376
17413
  const reportSkippedFiles = Effect$1.fn(SpanTaxonomy_exports.Spans.instrumentReportSkips.name)(function* (input) {
17377
17414
  const files = input.skipped.map((skip) => Result.match(explainFileSkip(ExplainFileSkipCommand.make({
17378
17415
  extension: skip.extension,
@@ -17394,13 +17431,6 @@ const offerSkipsIfAny = Effect$1.fn(SpanTaxonomy_exports.Spans.instrumentOfferSk
17394
17431
  onFalse: () => reportSkippedFiles(input)
17395
17432
  });
17396
17433
  });
17397
- const sandboxDirectoriesOf = (input) => Option$1.getOrElse(Option$1.map(Option$1.filter(Option$1.some(input), () => input.command.options.inPlace), (inPlace) => ({
17398
- workingDirectory: inPlace.basePath,
17399
- backupDirectory: inPlace.command.temporaryDirectoryPath
17400
- })), () => ({
17401
- workingDirectory: input.command.temporaryDirectoryPath,
17402
- backupDirectory: ""
17403
- }));
17404
17434
  const mergeInstrumentedFile = (input) => {
17405
17435
  const files = MutableHashMap.fromIterable(input.project.files);
17406
17436
  MutableHashMap.set(files, input.file.name, input.file);
@@ -17415,20 +17445,6 @@ const mergeInstrumentedFile = (input) => {
17415
17445
  filesToMutate
17416
17446
  };
17417
17447
  };
17418
- const enteringInstrumentPhase = (raw, body) => withPhaseSpan(SpanTaxonomy_exports.Spans.instrumentPhase, { fileCount: raw.filesToMutate.length }, () => Effect$1.andThen(phaseEntered("instrument"), body));
17419
- const writeInstrument = (raw) => enteringInstrumentPhase(raw, Effect$1.as(offerSkipsIfAny({
17420
- skipped: raw.instrumentResult.skipped,
17421
- claimants: raw.prev.frameworkClaimants
17422
- }), {
17423
- ...raw.prev,
17424
- project: raw.instrumentedProject,
17425
- mutants: raw.instrumentResult.mutants,
17426
- sandbox: raw.sandbox,
17427
- concurrency: {
17428
- testRunners: raw.concurrency.testRunners,
17429
- checkers: raw.concurrency.checkers
17430
- }
17431
- }));
17432
17448
  const withInstrumentedFiles = (project, instrumented) => Arr.reduce([...instrumented], project, (current, { name, content }) => Option$1.getOrElse(Option$1.map(MutableHashMap.get(current.files, name), (existing) => mergeInstrumentedFile({
17433
17449
  project: current,
17434
17450
  file: {
@@ -17436,9 +17452,7 @@ const withInstrumentedFiles = (project, instrumented) => Arr.reduce([...instrume
17436
17452
  content
17437
17453
  }
17438
17454
  })), () => current));
17439
- const readInstrument = Effect$1.fn(SpanTaxonomy_exports.Spans.instrumentGather.name)(function* (command) {
17440
- yield* Scope.Scope;
17441
- const env = yield* RunEnvironment;
17455
+ const instrumentFiles = Effect$1.fnUntraced(function* (command) {
17442
17456
  const files = yield* ProjectFiles;
17443
17457
  const filesToMutate = yield* Effect$1.map(files.readAll(MutableHashMap.values(command.project.filesToMutate)), (readFiles) => readFiles.map(([file, content]) => ({
17444
17458
  content,
@@ -17460,7 +17474,39 @@ const readInstrument = Effect$1.fn(SpanTaxonomy_exports.Spans.instrumentGather.n
17460
17474
  reason: "Instrumenter failed",
17461
17475
  cause
17462
17476
  })));
17463
- const instrumentedProject = withInstrumentedFiles(command.project, instrumentResult.files);
17477
+ return {
17478
+ filesToMutate,
17479
+ instrumentResult,
17480
+ instrumentedProject: withInstrumentedFiles(command.project, instrumentResult.files)
17481
+ };
17482
+ });
17483
+ const enteringInstrumentPhase = dual(2, (fileCount, body) => withPhaseSpan(SpanTaxonomy_exports.Spans.instrumentPhase, { fileCount }, () => Effect$1.andThen(phaseEntered("instrument"), body)));
17484
+ //#endregion
17485
+ //#region src/run/instrument.cell.ts
17486
+ const sandboxDirectoriesOf = (input) => Option$1.getOrElse(Option$1.map(Option$1.filter(Option$1.some(input), () => input.command.options.inPlace), (inPlace) => ({
17487
+ workingDirectory: inPlace.basePath,
17488
+ backupDirectory: inPlace.command.temporaryDirectoryPath
17489
+ })), () => ({
17490
+ workingDirectory: input.command.temporaryDirectoryPath,
17491
+ backupDirectory: ""
17492
+ }));
17493
+ const writeInstrument = (raw) => enteringInstrumentPhase(raw.filesToMutate.length, Effect$1.as(offerSkipsIfAny({
17494
+ skipped: raw.instrumentResult.skipped,
17495
+ claimants: raw.prev.frameworkClaimants
17496
+ }), {
17497
+ ...raw.prev,
17498
+ project: raw.instrumentedProject,
17499
+ mutants: raw.instrumentResult.mutants,
17500
+ sandbox: raw.sandbox,
17501
+ concurrency: {
17502
+ testRunners: raw.concurrency.testRunners,
17503
+ checkers: raw.concurrency.checkers
17504
+ }
17505
+ }));
17506
+ const readInstrument = Effect$1.fn(SpanTaxonomy_exports.Spans.instrumentGather.name)(function* (command) {
17507
+ yield* Scope.Scope;
17508
+ const env = yield* RunEnvironment;
17509
+ const { filesToMutate, instrumentResult, instrumentedProject } = yield* instrumentFiles(command);
17464
17510
  const directories = sandboxDirectoriesOf({
17465
17511
  command,
17466
17512
  basePath: env.basePath
@@ -18137,7 +18183,7 @@ const closureAnalysisOf = (input) => Effect$1.option(analyzeImportClosure({
18137
18183
  rootDir: input.basePath,
18138
18184
  projectFiles: Arr.dedupe([...MutableHashMap.keys(input.project.files), ...input.project.testFiles]),
18139
18185
  testFiles: [...input.project.testFiles],
18140
- globalInputs: input.globalTestInputs.map((file) => originalFileFor(input.sandbox, file))
18186
+ globalInputs: input.globalTestInputs.map((file) => input.originalFileOf(file))
18141
18187
  }).pipe(Effect$1.tapCause((cause) => Effect$1.logWarning(`Import closure analysis failed; refusing to reuse prior verdicts: ${Cause.pretty(cause)}`))));
18142
18188
  const closureDigestsOf = (input) => Effect$1.map(closureAnalysisOf(input), (analysis) => Option$1.match(analysis, {
18143
18189
  onNone: () => ({
@@ -18162,7 +18208,7 @@ const readIncrementalReuseCommand = Effect$1.fn(SpanTaxonomy_exports.Spans.incre
18162
18208
  previousRecords: [...previousRecords],
18163
18209
  closureDigestsByMutantId: closures.digests,
18164
18210
  closureAnalysisFailed: closures.failed,
18165
- verdictSemanticsVersion: 3,
18211
+ verdictSemanticsVersion: 4,
18166
18212
  mutantSetPolicy: input.options.mutator.mutantSetPolicy,
18167
18213
  runInputsDigest,
18168
18214
  force: input.force,
@@ -19184,7 +19230,7 @@ const proceedPipeline = Effect$1.fnUntraced(function* (raw) {
19184
19230
  force: prev.options.force,
19185
19231
  options: prev.options,
19186
19232
  globalTestInputs: prev.dryRunResult.globalTestInputs ?? [],
19187
- sandbox: prev.sandbox
19233
+ originalFileOf: (file) => originalFileFor(prev.sandbox, file)
19188
19234
  });
19189
19235
  const rememberedResults = reuse.rememberedResults;
19190
19236
  yield* Queue.offer(progressQueue, RunEvent_exports.ReuseReported.make({
@@ -19339,6 +19385,156 @@ const mutationTestCell$1 = Sandwich.named(SpanTaxonomy_exports.Spans.mutationTes
19339
19385
  }))
19340
19386
  });
19341
19387
  //#endregion
19388
+ //#region src/reporter-wiring.service.ts
19389
+ const spawnPluginReporterFactory = Effect$1.fn(SpanTaxonomy_exports.Spans.reporterWiringSpawnPluginReporterFactory.name)(function* (name, loaded, projectBasePath, options) {
19390
+ const entry = yield* Effect$1.mapError(Effect$1.fromResult(resolveConfiguredPlugin(WorkerSpawnCommand.make({
19391
+ sources: loaded.pluginSources,
19392
+ kind: "Reporter",
19393
+ configured: ConfiguredPluginName.make({ name })
19394
+ }))), (missing) => StageError.make({
19395
+ stage: "prepare",
19396
+ reason: missing.reason,
19397
+ cause: PluginNotFoundError.make({ descriptor: missing.descriptor })
19398
+ }));
19399
+ const client = yield* spawnReporterWorker({
19400
+ entrypoint: entry.entrypoint,
19401
+ projectBasePath,
19402
+ execArgv: [],
19403
+ options,
19404
+ tempDirPrefix: "stryker-reporter-"
19405
+ }).pipe(Effect$1.mapError((cause) => StageError.make({
19406
+ stage: "prepare",
19407
+ reason: `Failed to start the reporter worker "${name}"`,
19408
+ cause
19409
+ })));
19410
+ return reporterWorkerFactory(client);
19411
+ });
19412
+ const selectReporterChoices = (names, choicesByName) => Arr.map(Arr.reduce(names, Arr.empty(), (chosen, name) => Option$1.match(HashMap.get(choicesByName, name.toLowerCase()), {
19413
+ onNone: () => chosen,
19414
+ onSome: (choice) => Option$1.match(Arr.findFirst(chosen, ([key]) => key === name.toLowerCase()), {
19415
+ onNone: () => [...chosen, [name.toLowerCase(), choice]],
19416
+ onSome: () => chosen
19417
+ })
19418
+ })), ([, choice]) => choice);
19419
+ const reporterInputsOf = dual(5, (names, choicesByName, loaded, projectBasePath, options) => Effect$1.forEach(selectReporterChoices(names, choicesByName), (choice) => Option$1.match(choice.builtinFactory, {
19420
+ onSome: (builtin) => Effect$1.succeed({
19421
+ name: choice.name,
19422
+ factory: builtin
19423
+ }),
19424
+ onNone: () => Effect$1.map(spawnPluginReporterFactory(choice.name, loaded, projectBasePath, options), (factory) => ({
19425
+ name: choice.name,
19426
+ factory
19427
+ }))
19428
+ }), { concurrency: 1 }));
19429
+ //#endregion
19430
+ //#region src/keep-temp-dir.workflow.ts
19431
+ const KeepTempDirTypeId = Symbol.for("@systemfsoftware/stryker-js/KeepTempDir");
19432
+ const CleanTempDirOption = S.Literals([
19433
+ "always",
19434
+ false,
19435
+ true
19436
+ ]);
19437
+ var TempDirKept = class extends S.TaggedClass()("TempDirKept", {}) {
19438
+ [KeepTempDirTypeId] = KeepTempDirTypeId;
19439
+ };
19440
+ var TempDirRemoved = class extends S.TaggedClass()("TempDirRemoved", {}) {
19441
+ [KeepTempDirTypeId] = KeepTempDirTypeId;
19442
+ };
19443
+ var KeepTempDirCommand = class extends S.TaggedClass()("KeepTempDirCommand", {
19444
+ cleanTempDir: CleanTempDirOption,
19445
+ failed: S.Boolean
19446
+ }) {
19447
+ static [Workflow.InstrumentationBrand] = {};
19448
+ };
19449
+ const keptIff = (kept) => Match$1.value(kept).pipe(Match$1.when(true, () => TempDirKept.make({})), Match$1.when(false, () => TempDirRemoved.make({})), Match$1.exhaustive);
19450
+ const decide$1 = (command) => Match$1.value(command.cleanTempDir).pipe(Match$1.when(false, () => TempDirKept.make({})), Match$1.when(true, () => keptIff(command.failed)), Match$1.when("always", () => TempDirRemoved.make({})), Match$1.exhaustive, Result.succeed);
19451
+ const keepTempDir = Workflow.make({
19452
+ command: KeepTempDirCommand,
19453
+ decision: S.Union([TempDirKept, TempDirRemoved]),
19454
+ error: S.Never,
19455
+ decide: decide$1
19456
+ });
19457
+ //#endregion
19458
+ //#region src/Sandbox.service.ts
19459
+ const removesTempDir = (exit, cleanTempDir) => Result.match(keepTempDir(KeepTempDirCommand.make({
19460
+ cleanTempDir,
19461
+ failed: Exit.isFailure(exit)
19462
+ })), {
19463
+ onFailure: () => false,
19464
+ onSuccess: (decision) => Match$1.value(decision).pipe(Match$1.tag("TempDirRemoved", () => true), Match$1.tag("TempDirKept", () => false), Match$1.exhaustive)
19465
+ });
19466
+ const removeEmptyParentDirectory = Effect$1.fn(SpanTaxonomy_exports.Spans.sandboxRemoveEmptyParent.name)(function* (parent, fs) {
19467
+ const siblings = yield* fs.readDirectory(parent);
19468
+ yield* Boolean$1.match(siblings.length === 0, {
19469
+ onTrue: () => fs.remove(parent, {
19470
+ recursive: true,
19471
+ force: true
19472
+ }),
19473
+ onFalse: () => Effect$1.void
19474
+ });
19475
+ });
19476
+ const removeTempDirectory = Effect$1.fn(SpanTaxonomy_exports.Spans.sandboxRemoveTempDir.name)(function* (tmp, parent, fs) {
19477
+ yield* Effect$1.logDebug(`Deleting stryker temp directory ${tmp}`);
19478
+ yield* fs.remove(tmp, {
19479
+ recursive: true,
19480
+ force: true
19481
+ });
19482
+ const parentExists = yield* fs.exists(parent);
19483
+ yield* Boolean$1.match(parentExists, {
19484
+ onTrue: () => removeEmptyParentDirectory(parent, fs),
19485
+ onFalse: () => Effect$1.void
19486
+ });
19487
+ });
19488
+ const makeTemporaryDirectory = Effect$1.fn(SpanTaxonomy_exports.Spans.sandboxMakeTempDir.name)(function* (options) {
19489
+ const fs = yield* FileSystem.FileSystem;
19490
+ const parent = (yield* Path.Path).resolve(options.tempDirName);
19491
+ yield* fs.makeDirectory(parent, { recursive: true });
19492
+ const prefix = Boolean$1.match(options.inPlace, {
19493
+ onTrue: () => "backup-",
19494
+ onFalse: () => "sandbox-"
19495
+ });
19496
+ const tmp = yield* fs.makeTempDirectory({
19497
+ directory: parent,
19498
+ prefix
19499
+ });
19500
+ yield* Effect$1.logDebug(`Using temp directory "${tmp}"`);
19501
+ yield* Effect$1.addFinalizer((exit) => Boolean$1.match(removesTempDir(exit, options.cleanTempDir), {
19502
+ onTrue: () => removeTempDirectory(tmp, parent, fs),
19503
+ onFalse: () => Effect$1.logDebug(`Keeping stryker temp directory ${tmp}`)
19504
+ }).pipe(Effect$1.orDie));
19505
+ return { path: tmp };
19506
+ });
19507
+ var TemporaryDirectory = class TemporaryDirectory extends Context.Service()("@systemfsoftware/stryker-js/Sandbox.service/TemporaryDirectory") {
19508
+ static layer(options) {
19509
+ return Layer.effect(TemporaryDirectory, makeTemporaryDirectory(options));
19510
+ }
19511
+ };
19512
+ //#endregion
19513
+ //#region src/run/plan-prepare.workflow.ts
19514
+ const PrepareDecisionTypeId = Symbol.for("@systemfsoftware/stryker-js/PrepareDecision");
19515
+ var PrepareDecoded = class extends S.Class("PrepareDecoded")({
19516
+ mode: S.Literals(["human", "machine"]),
19517
+ reporters: S.Array(S.String),
19518
+ fileCount: S.Finite
19519
+ }) {
19520
+ static [Workflow.InstrumentationBrand] = {
19521
+ mode: "stryker.prepare.mode",
19522
+ fileCount: "stryker.prepare.file_count"
19523
+ };
19524
+ };
19525
+ var HumanReporters$1 = class extends S.TaggedClass()("HumanReporters", { reporters: S.Array(S.String) }) {
19526
+ [PrepareDecisionTypeId] = PrepareDecisionTypeId;
19527
+ };
19528
+ var MachineReporters$1 = class extends S.TaggedClass()("MachineReporters", { reporters: S.Array(S.String) }) {
19529
+ [PrepareDecisionTypeId] = PrepareDecisionTypeId;
19530
+ };
19531
+ const planPrepare = Workflow.make({
19532
+ command: PrepareDecoded,
19533
+ decision: S.Union([HumanReporters$1, MachineReporters$1]),
19534
+ error: S.Never,
19535
+ decide: (decoded) => Match$1.value(decoded.mode).pipe(Match$1.when("human", () => Result.succeed(HumanReporters$1.make({ reporters: decoded.reporters }))), Match$1.when("machine", () => Result.succeed(MachineReporters$1.make({ reporters: decoded.reporters }))), Match$1.exhaustive)
19536
+ });
19537
+ //#endregion
19342
19538
  //#region src/plan-mutator-catalogs.workflow.ts
19343
19539
  const STOCK_NAMESPACE = "stryker";
19344
19540
  const CatalogEntrySchema = S.Struct({
@@ -19491,7 +19687,7 @@ const optInRefusalOf = (index, command) => Option$1.match(refusedNameIn(index.op
19491
19687
  name
19492
19688
  }))
19493
19689
  });
19494
- const decide$1 = (command) => {
19690
+ const decide = (command) => {
19495
19691
  const index = indexOf(command.catalogs);
19496
19692
  return Result.map(Result.flatMap(excludedRefusalOf(index, command), () => optInRefusalOf(index, command)), () => MutatorSelectionDecoded.make({
19497
19693
  excludedMutations: [...command.excludedMutations],
@@ -19502,7 +19698,7 @@ const decodeMutatorSelection = Workflow.make({
19502
19698
  command: DecodeMutatorSelectionCommand,
19503
19699
  decision: MutatorSelectionDecoded,
19504
19700
  error: MutatorSelectionRefused,
19505
- decide: decide$1
19701
+ decide
19506
19702
  });
19507
19703
  //#endregion
19508
19704
  //#region src/framework-claimant.service.ts
@@ -19975,131 +20171,6 @@ const pluginUrlsFromOptions = (options) => [
19975
20171
  ...options.checkers.map((checker) => checker.plugin)
19976
20172
  ];
19977
20173
  //#endregion
19978
- //#region src/reporter-wiring.service.ts
19979
- const spawnPluginReporterFactory = Effect$1.fn(SpanTaxonomy_exports.Spans.reporterWiringSpawnPluginReporterFactory.name)(function* (name, loaded, projectBasePath, options) {
19980
- const entry = yield* Effect$1.mapError(Effect$1.fromResult(resolveConfiguredPlugin(WorkerSpawnCommand.make({
19981
- sources: loaded.pluginSources,
19982
- kind: "Reporter",
19983
- configured: ConfiguredPluginName.make({ name })
19984
- }))), (missing) => StageError.make({
19985
- stage: "prepare",
19986
- reason: missing.reason,
19987
- cause: PluginNotFoundError.make({ descriptor: missing.descriptor })
19988
- }));
19989
- const client = yield* spawnReporterWorker({
19990
- entrypoint: entry.entrypoint,
19991
- projectBasePath,
19992
- execArgv: [],
19993
- options,
19994
- tempDirPrefix: "stryker-reporter-"
19995
- }).pipe(Effect$1.mapError((cause) => StageError.make({
19996
- stage: "prepare",
19997
- reason: `Failed to start the reporter worker "${name}"`,
19998
- cause
19999
- })));
20000
- return reporterWorkerFactory(client);
20001
- });
20002
- const selectReporterChoices = (names, choicesByName) => Arr.map(Arr.reduce(names, Arr.empty(), (chosen, name) => Option$1.match(HashMap.get(choicesByName, name.toLowerCase()), {
20003
- onNone: () => chosen,
20004
- onSome: (choice) => Option$1.match(Arr.findFirst(chosen, ([key]) => key === name.toLowerCase()), {
20005
- onNone: () => [...chosen, [name.toLowerCase(), choice]],
20006
- onSome: () => chosen
20007
- })
20008
- })), ([, choice]) => choice);
20009
- const reporterInputsOf = dual(5, (names, choicesByName, loaded, projectBasePath, options) => Effect$1.forEach(selectReporterChoices(names, choicesByName), (choice) => Option$1.match(choice.builtinFactory, {
20010
- onSome: (builtin) => Effect$1.succeed({
20011
- name: choice.name,
20012
- factory: builtin
20013
- }),
20014
- onNone: () => Effect$1.map(spawnPluginReporterFactory(choice.name, loaded, projectBasePath, options), (factory) => ({
20015
- name: choice.name,
20016
- factory
20017
- }))
20018
- }), { concurrency: 1 }));
20019
- //#endregion
20020
- //#region src/keep-temp-dir.workflow.ts
20021
- const KeepTempDirTypeId = Symbol.for("@systemfsoftware/stryker-js/KeepTempDir");
20022
- const CleanTempDirOption = S.Literals([
20023
- "always",
20024
- false,
20025
- true
20026
- ]);
20027
- var TempDirKept = class extends S.TaggedClass()("TempDirKept", {}) {
20028
- [KeepTempDirTypeId] = KeepTempDirTypeId;
20029
- };
20030
- var TempDirRemoved = class extends S.TaggedClass()("TempDirRemoved", {}) {
20031
- [KeepTempDirTypeId] = KeepTempDirTypeId;
20032
- };
20033
- var KeepTempDirCommand = class extends S.TaggedClass()("KeepTempDirCommand", {
20034
- cleanTempDir: CleanTempDirOption,
20035
- failed: S.Boolean
20036
- }) {
20037
- static [Workflow.InstrumentationBrand] = {};
20038
- };
20039
- const keptIff = (kept) => Match$1.value(kept).pipe(Match$1.when(true, () => TempDirKept.make({})), Match$1.when(false, () => TempDirRemoved.make({})), Match$1.exhaustive);
20040
- const decide = (command) => Match$1.value(command.cleanTempDir).pipe(Match$1.when(false, () => TempDirKept.make({})), Match$1.when(true, () => keptIff(command.failed)), Match$1.when("always", () => TempDirRemoved.make({})), Match$1.exhaustive, Result.succeed);
20041
- const keepTempDir = Workflow.make({
20042
- command: KeepTempDirCommand,
20043
- decision: S.Union([TempDirKept, TempDirRemoved]),
20044
- error: S.Never,
20045
- decide
20046
- });
20047
- //#endregion
20048
- //#region src/Sandbox.service.ts
20049
- const removesTempDir = (exit, cleanTempDir) => Result.match(keepTempDir(KeepTempDirCommand.make({
20050
- cleanTempDir,
20051
- failed: Exit.isFailure(exit)
20052
- })), {
20053
- onFailure: () => false,
20054
- onSuccess: (decision) => Match$1.value(decision).pipe(Match$1.tag("TempDirRemoved", () => true), Match$1.tag("TempDirKept", () => false), Match$1.exhaustive)
20055
- });
20056
- const removeEmptyParentDirectory = Effect$1.fn(SpanTaxonomy_exports.Spans.sandboxRemoveEmptyParent.name)(function* (parent, fs) {
20057
- const siblings = yield* fs.readDirectory(parent);
20058
- yield* Boolean$1.match(siblings.length === 0, {
20059
- onTrue: () => fs.remove(parent, {
20060
- recursive: true,
20061
- force: true
20062
- }),
20063
- onFalse: () => Effect$1.void
20064
- });
20065
- });
20066
- const removeTempDirectory = Effect$1.fn(SpanTaxonomy_exports.Spans.sandboxRemoveTempDir.name)(function* (tmp, parent, fs) {
20067
- yield* Effect$1.logDebug(`Deleting stryker temp directory ${tmp}`);
20068
- yield* fs.remove(tmp, {
20069
- recursive: true,
20070
- force: true
20071
- });
20072
- const parentExists = yield* fs.exists(parent);
20073
- yield* Boolean$1.match(parentExists, {
20074
- onTrue: () => removeEmptyParentDirectory(parent, fs),
20075
- onFalse: () => Effect$1.void
20076
- });
20077
- });
20078
- const makeTemporaryDirectory = Effect$1.fn(SpanTaxonomy_exports.Spans.sandboxMakeTempDir.name)(function* (options) {
20079
- const fs = yield* FileSystem.FileSystem;
20080
- const parent = (yield* Path.Path).resolve(options.tempDirName);
20081
- yield* fs.makeDirectory(parent, { recursive: true });
20082
- const prefix = Boolean$1.match(options.inPlace, {
20083
- onTrue: () => "backup-",
20084
- onFalse: () => "sandbox-"
20085
- });
20086
- const tmp = yield* fs.makeTempDirectory({
20087
- directory: parent,
20088
- prefix
20089
- });
20090
- yield* Effect$1.logDebug(`Using temp directory "${tmp}"`);
20091
- yield* Effect$1.addFinalizer((exit) => Boolean$1.match(removesTempDir(exit, options.cleanTempDir), {
20092
- onTrue: () => removeTempDirectory(tmp, parent, fs),
20093
- onFalse: () => Effect$1.logDebug(`Keeping stryker temp directory ${tmp}`)
20094
- }).pipe(Effect$1.orDie));
20095
- return { path: tmp };
20096
- });
20097
- var TemporaryDirectory = class TemporaryDirectory extends Context.Service()("@systemfsoftware/stryker-js/Sandbox.service/TemporaryDirectory") {
20098
- static layer(options) {
20099
- return Layer.effect(TemporaryDirectory, makeTemporaryDirectory(options));
20100
- }
20101
- };
20102
- //#endregion
20103
20174
  //#region src/run/admit-non-empty-project.workflow.ts
20104
20175
  const NonEmptyProjectTypeId = Symbol.for("@systemfsoftware/stryker-js/NonEmptyProjectDecision");
20105
20176
  var NonEmptyProjectCommand = class extends S.TaggedClass()("NonEmptyProjectCommand", { fileCount: S.Int }) {
@@ -20122,31 +20193,6 @@ const admitNonEmptyProject = Workflow.make({
20122
20193
  }))
20123
20194
  });
20124
20195
  //#endregion
20125
- //#region src/run/plan-prepare.workflow.ts
20126
- const PrepareDecisionTypeId = Symbol.for("@systemfsoftware/stryker-js/PrepareDecision");
20127
- var PrepareDecoded = class extends S.Class("PrepareDecoded")({
20128
- mode: S.Literals(["human", "machine"]),
20129
- reporters: S.Array(S.String),
20130
- fileCount: S.Finite
20131
- }) {
20132
- static [Workflow.InstrumentationBrand] = {
20133
- mode: "stryker.prepare.mode",
20134
- fileCount: "stryker.prepare.file_count"
20135
- };
20136
- };
20137
- var HumanReporters$1 = class extends S.TaggedClass()("HumanReporters", { reporters: S.Array(S.String) }) {
20138
- [PrepareDecisionTypeId] = PrepareDecisionTypeId;
20139
- };
20140
- var MachineReporters$1 = class extends S.TaggedClass()("MachineReporters", { reporters: S.Array(S.String) }) {
20141
- [PrepareDecisionTypeId] = PrepareDecisionTypeId;
20142
- };
20143
- const planPrepare = Workflow.make({
20144
- command: PrepareDecoded,
20145
- decision: S.Union([HumanReporters$1, MachineReporters$1]),
20146
- error: S.Never,
20147
- decide: (decoded) => Match$1.value(decoded.mode).pipe(Match$1.when("human", () => Result.succeed(HumanReporters$1.make({ reporters: decoded.reporters }))), Match$1.when("machine", () => Result.succeed(MachineReporters$1.make({ reporters: decoded.reporters }))), Match$1.exhaustive)
20148
- });
20149
- //#endregion
20150
20196
  //#region src/run/plan-reporters.workflow.ts
20151
20197
  const ReporterPlanTypeId = Symbol.for("@systemfsoftware/stryker-js/ReporterPlanDecision");
20152
20198
  const STREAM_REPORTER = StreamReporterSchema.literal;
@@ -20187,7 +20233,7 @@ const planReporters = Workflow.make({
20187
20233
  decide: (command) => Match$1.value(command.mode).pipe(Match$1.when("human", () => Result.succeed(HumanReporters.make({ reporters: [...humanReportersFrom(command.configured)] }))), Match$1.when("machine", () => Result.succeed(MachineReporters.make({ reporters: [...machineReportersFrom(command.configured)] }))), Match$1.exhaustive)
20188
20234
  });
20189
20235
  //#endregion
20190
- //#region src/run/prepare.cell.ts
20236
+ //#region src/run/prepare.ts
20191
20237
  const announceSummary = Effect$1.fn(SpanTaxonomy_exports.Spans.prepareAnnounceSummary.name)(function* (input) {
20192
20238
  yield* Match$1.value(input.env.resolvedMode.mode).pipe(Match$1.when("human", () => Boolean$1.match(input.env.allowConsoleColors, {
20193
20239
  onTrue: () => Console.log(`${AnsiCode.fields.green.literal}${input.summary}${AnsiCode.fields.reset.literal}`),
@@ -20300,7 +20346,7 @@ const readPrepare = Effect$1.fn(SpanTaxonomy_exports.Spans.prepareGather.name)(f
20300
20346
  frameworkClaimants
20301
20347
  };
20302
20348
  });
20303
- const applyPrepare = Effect$1.fn(SpanTaxonomy_exports.Spans.prepareApply.name)(function* (span, reporters, raw) {
20349
+ const admitPreparedProject = (raw) => Effect$1.gen(function* () {
20304
20350
  const mutateCount = pipe(raw.project.filesToMutate, MutableHashMap.size);
20305
20351
  yield* announceSummary({
20306
20352
  env: raw.env,
@@ -20321,7 +20367,12 @@ const applyPrepare = Effect$1.fn(SpanTaxonomy_exports.Spans.prepareApply.name)(f
20321
20367
  reason: "No input files found."
20322
20368
  })
20323
20369
  }))), () => Result.succeed(void 0));
20324
- yield* Effect$1.fromResult(emptyProjectGuard);
20370
+ return yield* Effect$1.fromResult(emptyProjectGuard);
20371
+ });
20372
+ //#endregion
20373
+ //#region src/run/prepare.cell.ts
20374
+ const applyPrepare = Effect$1.fn(SpanTaxonomy_exports.Spans.prepareApply.name)(function* (span, reporters, raw) {
20375
+ yield* admitPreparedProject(raw);
20325
20376
  const temporaryDirectoryPath = yield* Effect$1.map(Layer.build(TemporaryDirectory.layer(raw.options)), (temporaryDirectory) => Context.get(temporaryDirectory, TemporaryDirectory).path).pipe(Effect$1.mapError((cause) => StageError.make({
20326
20377
  stage: "prepare",
20327
20378
  reason: "Failed to create temporary directory",