@systemfsoftware/stryker-js-typescript-checker 7.0.1 → 7.0.3

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.
Files changed (3) hide show
  1. package/CHANGELOG.md +19 -0
  2. package/dist/main.mjs +217 -59
  3. package/package.json +4 -4
package/CHANGELOG.md CHANGED
@@ -1,5 +1,24 @@
1
1
  # @systemfsoftware/stryker-js-typescript-checker
2
2
 
3
+ ## 7.0.3
4
+
5
+ ### Patch Changes
6
+
7
+ - A checker that fails now fails mutation testing with that checker's cause, instead of crashing with an empty error. The TypeScript checker type-checks each mutant, so compile errors appear in the report. Verdict counts are non-negative integers; `Metrics` is a class you can build from mutant statuses; a threshold `low` may not exceed `high`.
8
+
9
+ ## 7.0.2
10
+
11
+ ### Patch Changes
12
+
13
+ - The checker request carries a plain data record, not the instrumenter's `Mutant` class. `CheckerRequest.mutants` and `CheckerService.check`/`group` now speak `CheckerMutantWire` - `id`, `fileName`, `mutatorName`, `replacement`, and `location`. A mutant that cannot be described to a checker is skipped instead of reaching it.
14
+
15
+ With `OTEL_ENABLED=true` the CLI now exports its OpenTelemetry metrics to `OTEL_EXPORTER_OTLP_ENDPOINT`, and `OTEL_METRIC_EXPORT_INTERVAL` sets the export interval in milliseconds. Checker timings, mutant counts, and worker crashes now reach a metrics backend.
16
+
17
+ `ConfigEnv` and `resolveExtends` are no longer exported. Import `ConfigEnv` from the config entry point of the package, and read merged options with `loadConfigCell` or `readConfig` from the package root - either performs the `extends` walk, validation and merge in order.
18
+
19
+ - Updated dependencies:
20
+ - @systemfsoftware/stryker-js-plugin-interface@7.0.0
21
+
3
22
  ## 7.0.1
4
23
 
5
24
  ### Patch Changes
package/dist/main.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  import { createRequire } from "node:module";
2
- import { LocationSchema, Mutant, MutantRunOptionsSchema, MutantStatusSchema, OpenEndLocationSchema, PositionSchema, RunOptionsFields, errorToString, normalizeFileName } from "@systemfsoftware/stryker-js-instrumenter";
2
+ import { LocationSchema, MutantRunOptionsSchema, MutantStatusSchema, OpenEndLocationSchema, PositionSchema, RunOptionsFields, errorToString, normalizeFileName } from "@systemfsoftware/stryker-js-instrumenter";
3
3
  import { createRequire as createRequire$1 } from "module";
4
4
  import * as Net from "node:net";
5
5
  import * as Crypto from "node:crypto";
@@ -8064,6 +8064,15 @@ const withSpan$1 = function() {
8064
8064
  return (self, ...args) => useSpan$1(name, fnArg ? fnArg(...args) : options, (span) => withParentSpan(self, span, traceOptions));
8065
8065
  };
8066
8066
  /** @internal */
8067
+ const annotateCurrentSpan$1 = (...args) => withFiber$1((fiber) => {
8068
+ const span = fiber.currentSpanLocal;
8069
+ if (span) {
8070
+ if (args.length === 1) for (const [key, value] of Object.entries(args[0])) span.attribute(key, value);
8071
+ else span.attribute(args[0], args[1]);
8072
+ }
8073
+ return void_$3;
8074
+ });
8075
+ /** @internal */
8067
8076
  const ClockRef = /*#__PURE__*/ Reference("effect/Clock", { defaultValue: () => new ClockImpl() });
8068
8077
  const MAX_TIMER_MILLIS = 2 ** 31 - 1;
8069
8078
  var ClockImpl = class {
@@ -13448,6 +13457,30 @@ const interruptible = interruptible$1;
13448
13457
  */
13449
13458
  const forever = forever$1;
13450
13459
  /**
13460
+ * Adds an annotation to the current span if available.
13461
+ *
13462
+ * **Example** (Annotating the current span)
13463
+ *
13464
+ * ```ts import.meta.vitest
13465
+ * import { Effect } from "effect"
13466
+ *
13467
+ * const program = Effect.gen(function*() {
13468
+ * yield* Effect.annotateCurrentSpan("userId", "123")
13469
+ * yield* Effect.annotateCurrentSpan({
13470
+ * operation: "user-lookup"
13471
+ * })
13472
+ * return "success"
13473
+ * })
13474
+ *
13475
+ * const traced = Effect.withSpan(program, "user-operation")
13476
+ * Effect.runSync(traced) // => "success"
13477
+ * ```
13478
+ *
13479
+ * @category tracing
13480
+ * @since 2.0.0
13481
+ */
13482
+ const annotateCurrentSpan = annotateCurrentSpan$1;
13483
+ /**
13451
13484
  * Create a new span for tracing, and automatically close it when the effect
13452
13485
  * completes.
13453
13486
  *
@@ -28440,6 +28473,23 @@ const set$1 = /*#__PURE__*/ dual(2, (self, value) => sync(() => set$2(self.ref,
28440
28473
  const update = /*#__PURE__*/ dual(2, (self, f) => sync(() => {
28441
28474
  self.ref.current = f(self.ref.current);
28442
28475
  }));
28476
+ //#endregion
28477
+ //#region ../stryker-js-plugin-interface/dist/index.mjs
28478
+ /** A position inside a file, in the coordinates the wire carries — 0-based line and column. */
28479
+ const CheckerPositionWire = Struct({
28480
+ line: Finite,
28481
+ column: Finite
28482
+ });
28483
+ const CheckerMutantWire = Struct({
28484
+ id: NonEmptyString,
28485
+ fileName: NonEmptyString,
28486
+ mutatorName: NonEmptyString,
28487
+ replacement: String$1,
28488
+ location: Struct({
28489
+ start: CheckerPositionWire,
28490
+ end: CheckerPositionWire
28491
+ })
28492
+ });
28443
28493
  Literals(["passed", "compileError"]);
28444
28494
  const CheckResultSchema = Union([Struct({ status: Literal("passed") }), Struct({
28445
28495
  status: Literal("compileError"),
@@ -28469,26 +28519,86 @@ TaggedClass()("ClassifyExitDecision", {
28469
28519
  highestClass: NullOr(ExitClass),
28470
28520
  verdictClass: NullOr(ExitClass)
28471
28521
  });
28522
+ Union([Literal("Killed"), Literal("Timeout")]);
28523
+ Union([Literal("Survived"), Literal("NoCoverage")]);
28524
+ Union([Literal("CompileError"), Literal("RuntimeError")]);
28525
+ Union([Literal("Ignored"), Literal("Pending")]);
28526
+ const NonNegativeInt = Int.pipe(check(isGreaterThanOrEqualTo(0)));
28527
+ const NonNegativeFinite = Finite.pipe(check(isGreaterThanOrEqualTo(0)));
28528
+ const Percentage = Finite.pipe(check(isBetween({
28529
+ minimum: 0,
28530
+ maximum: 100
28531
+ })));
28532
+ var Metrics = class Metrics extends Class("Metrics")({
28533
+ pending: NonNegativeInt,
28534
+ killed: NonNegativeInt,
28535
+ timeout: NonNegativeInt,
28536
+ survived: NonNegativeInt,
28537
+ noCoverage: NonNegativeInt,
28538
+ runtimeErrors: NonNegativeInt,
28539
+ compileErrors: NonNegativeInt,
28540
+ ignored: NonNegativeInt
28541
+ }) {
28542
+ get totalDetected() {
28543
+ return this.timeout + this.killed;
28544
+ }
28545
+ get totalUndetected() {
28546
+ return this.survived + this.noCoverage;
28547
+ }
28548
+ get totalCovered() {
28549
+ return this.totalDetected + this.survived;
28550
+ }
28551
+ get totalValid() {
28552
+ return this.totalUndetected + this.totalDetected;
28553
+ }
28554
+ get totalInvalid() {
28555
+ return this.runtimeErrors + this.compileErrors;
28556
+ }
28557
+ get totalMutants() {
28558
+ return this.totalValid + this.totalInvalid + this.ignored + this.pending;
28559
+ }
28560
+ get mutationScore() {
28561
+ if (this.totalValid === 0) return NaN;
28562
+ return Math.min(100, Math.max(0, this.totalDetected / this.totalValid * 100));
28563
+ }
28564
+ get mutationScoreBasedOnCoveredCode() {
28565
+ if (this.totalCovered === 0) return NaN;
28566
+ return Math.min(100, Math.max(0, this.totalDetected / this.totalCovered * 100));
28567
+ }
28568
+ static fromMutants(mutants) {
28569
+ const counts = emptyMetricCounts();
28570
+ for (const mutant of mutants) incrementMetricStatus(counts, mutant.status);
28571
+ return Metrics.make(counts);
28572
+ }
28573
+ };
28574
+ const emptyMetricCounts = () => ({
28575
+ pending: 0,
28576
+ killed: 0,
28577
+ timeout: 0,
28578
+ survived: 0,
28579
+ noCoverage: 0,
28580
+ runtimeErrors: 0,
28581
+ compileErrors: 0,
28582
+ ignored: 0
28583
+ });
28584
+ const METRIC_STATUS_KEYS = {
28585
+ Pending: "pending",
28586
+ Killed: "killed",
28587
+ Timeout: "timeout",
28588
+ Survived: "survived",
28589
+ NoCoverage: "noCoverage",
28590
+ RuntimeError: "runtimeErrors",
28591
+ CompileError: "compileErrors",
28592
+ Ignored: "ignored"
28593
+ };
28594
+ const incrementMetricStatus = (counts, status) => {
28595
+ const key = METRIC_STATUS_KEYS[status];
28596
+ if (key === void 0) return;
28597
+ counts[key] += 1;
28598
+ };
28472
28599
  const MetricsResultSchema = Struct({
28473
28600
  name: String$1,
28474
- metrics: Struct({
28475
- pending: Finite,
28476
- killed: Finite,
28477
- timeout: Finite,
28478
- survived: Finite,
28479
- noCoverage: Finite,
28480
- runtimeErrors: Finite,
28481
- compileErrors: Finite,
28482
- ignored: Finite,
28483
- totalDetected: Finite,
28484
- totalUndetected: Finite,
28485
- totalInvalid: Finite,
28486
- totalValid: Finite,
28487
- totalMutants: Finite,
28488
- totalCovered: Finite,
28489
- mutationScore: Finite,
28490
- mutationScoreBasedOnCoveredCode: Finite
28491
- }),
28601
+ metrics: Metrics,
28492
28602
  childResults: ArraySchema(suspend(() => MetricsResultSchema))
28493
28603
  }).annotate({ identifier: "MetricsResult" });
28494
28604
  const FileResultDictionarySchema = Record(String$1, Struct({
@@ -28505,8 +28615,8 @@ const FileResultDictionarySchema = Record(String$1, Struct({
28505
28615
  static: optional(Boolean$2),
28506
28616
  coveredBy: optional(ArraySchema(String$1)),
28507
28617
  killedBy: optional(ArraySchema(String$1)),
28508
- testsCompleted: optional(Finite),
28509
- duration: optional(Finite)
28618
+ testsCompleted: optional(NonNegativeInt),
28619
+ duration: optional(NonNegativeFinite)
28510
28620
  }))
28511
28621
  }));
28512
28622
  const TestDefinitionSchema = Struct({
@@ -28519,9 +28629,23 @@ const TestFileDefinitionDictionarySchema = Record(String$1, Struct({
28519
28629
  tests: ArraySchema(TestDefinitionSchema)
28520
28630
  }));
28521
28631
  const ThresholdsSchema = Struct({
28522
- high: Finite,
28523
- low: Finite
28524
- });
28632
+ high: Percentage,
28633
+ low: Percentage
28634
+ }).pipe(check(makeFilter((t) => t.low <= t.high, {
28635
+ expected: "thresholds where low <= high",
28636
+ arbitrary: { candidate: { make: (fc) => fc.tuple(fc.float({
28637
+ min: 0,
28638
+ max: 100,
28639
+ noNaN: true
28640
+ }), fc.float({
28641
+ min: 0,
28642
+ max: 100,
28643
+ noNaN: true
28644
+ })).map(([a, b]) => ({
28645
+ high: Math.max(a, b),
28646
+ low: Math.min(a, b)
28647
+ })) } }
28648
+ })));
28525
28649
  const BrandingInformationSchema = Struct({
28526
28650
  homepageUrl: String$1,
28527
28651
  imageUrl: optional(String$1)
@@ -28649,23 +28773,23 @@ const ReporterEventKind = Literals([
28649
28773
  "mutationTestReportReady"
28650
28774
  ]);
28651
28775
  const RunTimingSchema = Struct({
28652
- net: Finite,
28653
- overhead: Finite
28776
+ net: NonNegativeFinite,
28777
+ overhead: NonNegativeFinite
28654
28778
  });
28655
28779
  const ReporterPlanDescriptorSchema = Struct({
28656
28780
  mutantId: String$1,
28657
28781
  plan: Literals(["EarlyResult", "Run"]),
28658
- netTime: Finite,
28782
+ netTime: NonNegativeFinite,
28659
28783
  reloadEnvironment: Boolean$2
28660
28784
  });
28661
28785
  var DryRunCompleted = class extends TaggedClass()("dryRunCompleted", {
28662
28786
  timing: RunTimingSchema,
28663
28787
  capabilities: TestRunnerCapabilitiesSchema,
28664
- testCount: Finite,
28788
+ testCount: NonNegativeInt,
28665
28789
  tests: ArraySchema(TestResultSchema)
28666
28790
  }) {};
28667
28791
  var MutationTestingPlanReady = class extends TaggedClass()("mutationTestingPlanReady", {
28668
- total: Finite,
28792
+ total: NonNegativeInt,
28669
28793
  plans: ArraySchema(ReporterPlanDescriptorSchema)
28670
28794
  }) {};
28671
28795
  var MutantTested = class extends TaggedClass()("mutantTested", {
@@ -28675,8 +28799,8 @@ var MutantTested = class extends TaggedClass()("mutantTested", {
28675
28799
  location: LocationSchema,
28676
28800
  mutator: String$1,
28677
28801
  replacement: NullOr(String$1),
28678
- completed: Finite,
28679
- total: Finite
28802
+ completed: NonNegativeInt,
28803
+ total: NonNegativeInt
28680
28804
  }) {};
28681
28805
  var MutationTestReportReady = class extends TaggedClass()("mutationTestReportReady", {
28682
28806
  report: MutationTestResultSchema,
@@ -28703,7 +28827,7 @@ const TestRunnerDryRunRequest = Struct({ options: DryRunOptionsSchema });
28703
28827
  const TestRunnerMutantRunRequest = Struct({ options: MutantRunOptionsSchema });
28704
28828
  const CheckerRequest = Struct({
28705
28829
  checkerName: String$1,
28706
- mutants: ArraySchema(Mutant)
28830
+ mutants: ArraySchema(CheckerMutantWire)
28707
28831
  });
28708
28832
  const CheckerCheckResult = Record(String$1, CheckResultSchema);
28709
28833
  const CheckerGroupResult = ArraySchema(ArraySchema(String$1));
@@ -28839,11 +28963,6 @@ const PackageManager = Literals([
28839
28963
  "yarn",
28840
28964
  "pnpm"
28841
28965
  ]);
28842
- /** 0–100 percentage used by the mutation-score thresholds. */
28843
- const Percentage = Finite.pipe(check(isBetween({
28844
- minimum: 0,
28845
- maximum: 100
28846
- })));
28847
28966
  const CommandRunnerOptionsSchema = openStruct({ command: defaulted(String$1, "npm test") });
28848
28967
  const ClearTextReporterOptions = openStruct({
28849
28968
  allowColor: defaulted(Boolean$2, true),
@@ -28861,7 +28980,26 @@ const MutationScoreThresholdsSchema = Struct({
28861
28980
  high: defaulted(Percentage, 80),
28862
28981
  low: defaulted(Percentage, 60),
28863
28982
  break: defaulted(NullOr(Percentage), null)
28864
- });
28983
+ }).pipe(check(makeFilter((t) => t.low <= t.high, {
28984
+ expected: "thresholds where low <= high",
28985
+ arbitrary: { candidate: { make: (fc) => fc.tuple(fc.float({
28986
+ min: 0,
28987
+ max: 100,
28988
+ noNaN: true
28989
+ }), fc.float({
28990
+ min: 0,
28991
+ max: 100,
28992
+ noNaN: true
28993
+ }), fc.option(fc.float({
28994
+ min: 0,
28995
+ max: 100,
28996
+ noNaN: true
28997
+ }), { nil: null })).map(([a, b, brk]) => ({
28998
+ high: Math.max(a, b),
28999
+ low: Math.min(a, b),
29000
+ break: brk
29001
+ })) } }
29002
+ })));
28865
29003
  const MutatorDescriptor = Struct({ excludedMutations: defaulted(ArraySchema(String$1), []) });
28866
29004
  const WarningOptions = openStruct({
28867
29005
  unknownOptions: defaulted(Boolean$2, true),
@@ -51816,7 +51954,7 @@ const TSFileNodeSchema = suspend(() => Struct({
51816
51954
  children: ArraySchema(TSFileNodeSchema)
51817
51955
  }));
51818
51956
  var CheckMutantsInput = class extends TaggedClass()("CheckMutantsInput", {
51819
- mutants: ArraySchema(Mutant),
51957
+ mutants: ArraySchema(CheckerMutantWire),
51820
51958
  diagnostics: ArraySchema(DiagnosticSchema),
51821
51959
  nodes: Record(SourceFileSchema, TSFileNodeSchema)
51822
51960
  }) {};
@@ -51837,7 +51975,7 @@ var CheckFinished = class extends TaggedClass()("CheckFinished", { results: Reco
51837
51975
  };
51838
51976
  var RetestRequired = class extends TaggedClass()("RetestRequired", {
51839
51977
  results: Record(String$1, MutantCheckStatusSchema),
51840
- needsRetest: ArraySchema(Mutant)
51978
+ needsRetest: ArraySchema(CheckerMutantWire)
51841
51979
  }) {
51842
51980
  [CheckMutantsTypeId] = CheckMutantsTypeId;
51843
51981
  };
@@ -51927,7 +52065,7 @@ const verdict = (input) => match$4(withoutDisambiguation(input), {
51927
52065
  });
51928
52066
  const checkMutants = Workflow_exports.make(CheckMutantsInput, verdict);
51929
52067
  Struct({ typescriptChecker: optional(Struct({ prioritizePerformanceOverAccuracy: optional(Boolean$2) })) });
51930
- var CheckMutantsCommand = class extends TaggedClass()("CheckMutantsCommand", { mutants: ArraySchema(Mutant) }) {};
52068
+ var CheckMutantsCommand = class extends TaggedClass()("CheckMutantsCommand", { mutants: ArraySchema(CheckerMutantWire) }) {};
51931
52069
  /**
51932
52070
  * Every way the TypeScript compiler can fail while serving a check.
51933
52071
  * One tagged error — callers branch only on failure itself; `reason` keeps
@@ -52256,7 +52394,7 @@ function parseTsConfig(fileName, jsonText) {
52256
52394
  }
52257
52395
  /** Whether `--build` mode should be enabled based on `references` in the tsconfig. */
52258
52396
  const determineBuildModeEnabled = (tsconfigFileName, fsService) => gen(function* () {
52259
- const parsed = parseTsConfig(tsconfigFileName, yield* fsService.readFileString(tsconfigFileName));
52397
+ const parsed = parseTsConfig(tsconfigFileName, yield* fsService.readFileString(tsconfigFileName).pipe(orElseSucceed(() => "")));
52260
52398
  return match$3(parsed, {
52261
52399
  onFailure: () => false,
52262
52400
  onSuccess: (config) => config.references !== void 0
@@ -52334,7 +52472,7 @@ const readTypescriptPackageVersion = (fsService, pathService) => gen(function* (
52334
52472
  onSuccess: (value) => value
52335
52473
  });
52336
52474
  return getOrElse(flatMap$4(versionFieldOf(raw), (version) => liftPredicate(version, isString)), () => "");
52337
- });
52475
+ }).pipe(orElseSucceed(() => ""));
52338
52476
  const getTSVersion = (fsService, pathService) => gen(function* () {
52339
52477
  if (cachedTSVersion !== void 0) return cachedTSVersion;
52340
52478
  const version = yield* readTypescriptPackageVersion(fsService, pathService);
@@ -52419,7 +52557,7 @@ function resetScriptFile(file, now) {
52419
52557
  function getOffset(file, pos) {
52420
52558
  const lines = file.originalContent.split("\n");
52421
52559
  const lineCount = Math.min(pos.line, lines.length);
52422
- let offset = pos.column;
52560
+ let offset = Math.max(0, pos.column - 1);
52423
52561
  lines.forEach((line, index) => {
52424
52562
  if (index < lineCount) offset += line.length + 1;
52425
52563
  });
@@ -52641,7 +52779,7 @@ function makeTypescriptCompiler(options, fs, fsService, pathService) {
52641
52779
  }));
52642
52780
  return succeed$1(projects.map((project) => project.program));
52643
52781
  };
52644
- const getProgramsEffect = () => gen(function* () {
52782
+ const getPrograms = () => gen(function* () {
52645
52783
  const state = yield* get$1(stateRef);
52646
52784
  const snapshot = yield* snapshotOf(state);
52647
52785
  return yield* programsOf(snapshot, state.tsconfigFile);
@@ -52670,7 +52808,7 @@ function makeTypescriptCompiler(options, fs, fsService, pathService) {
52670
52808
  const current = traversal.pending.pop();
52671
52809
  if (!isUnprocessedTsConfigPath(current, traversal.processed)) return;
52672
52810
  add(traversal.processed, current);
52673
- const content = yield* fsService.readFileString(current);
52811
+ const content = yield* fsService.readFileString(current).pipe(mapError(() => TsConfigNotFoundError.make({ file: current })));
52674
52812
  recordTsConfig(current, content, parseTsConfig(current, content), traversal);
52675
52813
  });
52676
52814
  const collectAllTSConfigFiles = (buildModeEnabled) => gen(function* () {
@@ -52875,15 +53013,20 @@ function makeTypescriptCompiler(options, fs, fsService, pathService) {
52875
53013
  yield* buildFileNodes(state);
52876
53014
  return state.nodes;
52877
53015
  });
53016
+ const resolveFileName = (fileName) => normalizeFileName$1(pathService.resolve(fileName));
52878
53017
  const resetMutatedFiles = (mutants) => gen(function* () {
52879
- for (const mutant of mutants) yield* fs.resetFile(mutant.fileName);
53018
+ for (const mutant of mutants) yield* fs.resetFile(resolveFileName(mutant.fileName));
52880
53019
  });
52881
53020
  const applyMutant = (mutant) => gen(function* () {
52882
- if ((yield* fs.getFile(mutant.fileName)) === void 0) return yield* CompilerFailed.make({
53021
+ const resolved = resolveFileName(mutant.fileName);
53022
+ if ((yield* fs.getFile(resolved)) === void 0) return yield* CompilerFailed.make({
52883
53023
  reason: "file-not-in-project",
52884
53024
  subject: mutant.fileName
52885
53025
  });
52886
- yield* fs.mutateFile(mutant.fileName, mutant);
53026
+ yield* fs.mutateFile(resolved, mutant).pipe(mapError(() => CompilerFailed.make({
53027
+ reason: "file-not-in-project",
53028
+ subject: mutant.fileName
53029
+ })));
52887
53030
  });
52888
53031
  const applyMutants = (mutants) => gen(function* () {
52889
53032
  for (const mutant of mutants) yield* applyMutant(mutant);
@@ -52901,25 +53044,40 @@ function makeTypescriptCompiler(options, fs, fsService, pathService) {
52901
53044
  snapshot: next
52902
53045
  }));
52903
53046
  });
53047
+ const refreshSnapshotIfOpen = (current, changedFiles) => {
53048
+ if (!hasOpenSnapshot(current)) return void_$1;
53049
+ return updateSnapshot(current, changedFiles);
53050
+ };
53051
+ const annotateDiagnosticSample = (diagnostics) => {
53052
+ if (diagnostics.length === 0) return void_$1;
53053
+ const summary = diagnostics.slice(0, 10).map((d) => `${d.fileName ?? "unknown"}:${d.code}: ${d.text}`).join("; ");
53054
+ return annotateCurrentSpan({ "typescript.diagnostics.sample": summary });
53055
+ };
52904
53056
  const check = (mutants) => gen(function* () {
52905
53057
  const state = yield* get$1(stateRef);
52906
53058
  yield* resetMutatedFiles(state.lastMutants);
52907
53059
  yield* applyMutants(mutants);
52908
- const mutatedFileNames = Array.from(fromIterable(mutants.map((mutant) => normalizeFileName$1(mutant.fileName))));
53060
+ const mutatedFileNames = Array.from(fromIterable(mutants.map((mutant) => resolveFileName(mutant.fileName))));
52909
53061
  const changedFiles = Array.from(fromIterable([...state.lastMutatedFileNames, ...mutatedFileNames]));
52910
53062
  const current = yield* get$1(stateRef);
52911
- if (hasOpenSnapshot(current)) yield* updateSnapshot(current, changedFiles);
53063
+ yield* refreshSnapshotIfOpen(current, changedFiles);
52912
53064
  yield* update(stateRef, (prev) => ({
52913
53065
  ...prev,
52914
53066
  lastMutants: [...mutants],
52915
53067
  lastMutatedFileNames: mutatedFileNames
52916
53068
  }));
52917
- return (yield* getProgramsEffect()).flatMap((program) => [
53069
+ const diagnostics = (yield* getPrograms()).flatMap((program) => [
52918
53070
  ...program.getConfigFileParsingDiagnostics(),
52919
53071
  ...program.getSemanticDiagnostics(),
52920
53072
  ...program.getProgramDiagnostics()
52921
53073
  ]).filter((diagnostic) => diagnostic.category === DiagnosticCategory.Error);
52922
- });
53074
+ yield* annotateCurrentSpan({ "typescript.diagnostics.count": diagnostics.length });
53075
+ yield* annotateDiagnosticSample(diagnostics);
53076
+ return diagnostics;
53077
+ }).pipe(withSpan("typescript-checker.compiler.check", { attributes: {
53078
+ "stryker.mutants.count": mutants.length,
53079
+ "stryker.mutants.ids": mutants.map((m) => m.id).join(",")
53080
+ } }));
52923
53081
  const init = gen(function* () {
52924
53082
  yield* guardTSVersion(fsService, pathService);
52925
53083
  const absoluteTsconfigFile = normalizeFileName$1(pathService.resolve(rawTsconfigFile));
@@ -52939,7 +53097,7 @@ function makeTypescriptCompiler(options, fs, fsService, pathService) {
52939
53097
  api,
52940
53098
  snapshot
52941
53099
  }));
52942
- const programs = yield* getProgramsEffect();
53100
+ const programs = yield* getPrograms();
52943
53101
  yield* buildDependencyGraph(programs);
52944
53102
  return yield* check([]);
52945
53103
  });
@@ -52954,12 +53112,12 @@ function makeTypescriptCompiler(options, fs, fsService, pathService) {
52954
53112
  }));
52955
53113
  });
52956
53114
  const getLineAndCharacterOfPosition = (fileName, position) => gen(function* () {
52957
- return (yield* getProgramsEffect()).map((program) => program.getSourceFile(fileName)).find((sourceFile) => sourceFile !== void 0)?.getLineAndCharacterOfPosition(position);
53115
+ return (yield* getPrograms().pipe(orElseSucceed(() => []))).map((program) => program.getSourceFile(fileName)).find((sourceFile) => sourceFile !== void 0)?.getLineAndCharacterOfPosition(position);
52958
53116
  });
52959
53117
  return {
52960
53118
  init,
52961
53119
  check,
52962
- nodes: getNodesEffect,
53120
+ nodes: getNodesEffect.pipe(orDie),
52963
53121
  close,
52964
53122
  getLineAndCharacterOfPosition
52965
53123
  };
@@ -52979,7 +53137,7 @@ const knownFileGroups = (mutants, nodes) => {
52979
53137
  };
52980
53138
  const groupMutants = (mutants, nodes, prioritizePerformanceOverAccuracy) => {
52981
53139
  if (prioritizePerformanceOverAccuracy) return knownFileGroups(mutants, nodes);
52982
- return [mutants.map((mutant) => mutant.id)];
53140
+ return mutants.map((mutant) => [mutant.id]);
52983
53141
  };
52984
53142
  //#endregion
52985
53143
  //#region src/Checker.ts
@@ -53023,14 +53181,14 @@ const makeCheckerService = ({ options, compiler }) => {
53023
53181
  });
53024
53182
  const formatDiagnostic = (error) => positionOf(error).pipe(map$2((position) => `${position}${severityOf(error.category)} TS${error.code}: ${error.text}`));
53025
53183
  const createErrorText = (errors) => map$2(forEach$2(errors, formatDiagnostic), (parts) => parts.join("\n"));
53026
- const soloRound = (mutant) => verify.run(CheckMutantsCommand.make({ mutants: [mutant] })).pipe(map$2((decision) => decision.results));
53184
+ const soloRound = (mutant) => verify.run(CheckMutantsCommand.make({ mutants: [mutant] })).pipe(withSpan("typescript-checker.soloRound", { attributes: { "stryker.mutant.id": mutant.id } }), map$2((decision) => decision.results));
53027
53185
  const soloRounds = (decision) => value(decision).pipe(tag("CheckFinished", () => succeed$1([])), tag("RetestRequired", (retest) => verify.run(CheckMutantsCommand.make({ mutants: [] })).pipe(flatMap(() => forEach$2(retest.needsRetest, soloRound)))), exhaustive);
53028
53186
  return {
53029
53187
  init: compiler.init.pipe(mapError((cause) => refuse([], cause)), flatMap((errors) => {
53030
53188
  if (errors.length === 0) return void_$1;
53031
53189
  return createErrorText(errors).pipe(map$2((text) => refuse([], /* @__PURE__ */ new Error(`Typescript error(s) found in dry run compilation: ${text}`))), flatMap(fail));
53032
53190
  })),
53033
- check: (mutants) => verify.run(CheckMutantsCommand.make({ mutants: [...mutants] })).pipe(flatMap((first) => map$2(soloRounds(first), (rounds) => mergeAnswers([first.results, ...rounds])))),
53191
+ check: (mutants) => verify.run(CheckMutantsCommand.make({ mutants: [...mutants] })).pipe(flatMap((first) => map$2(soloRounds(first), (rounds) => mergeAnswers([first.results, ...rounds]))), withSpan("typescript-checker.check", { attributes: { "stryker.mutants.count": mutants.length } })),
53034
53192
  group: (mutants) => compiler.nodes.pipe(map$2((nodes) => groupMutants(mutants, nodes, getPrioritize(options))), mapError((cause) => refuse(mutants.map((mutant) => mutant.id), cause)))
53035
53193
  };
53036
53194
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@systemfsoftware/stryker-js-typescript-checker",
3
- "version": "7.0.1",
3
+ "version": "7.0.3",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "git+https://github.com/systemfsoftware/stryker-js-effect.git",
@@ -30,8 +30,8 @@
30
30
  "effect": "4.0.0-rc.112",
31
31
  "typescript": "^7",
32
32
  "@systemfsoftware/stryker-js-instrumenter": "^8.0.0",
33
- "@systemfsoftware/stryker-js-plugin-interface": "^6.0.1",
34
- "@systemfsoftware/stryker-js-plugin-runtime": "^5.0.1"
33
+ "@systemfsoftware/stryker-js-plugin-interface": "^7.1.0",
34
+ "@systemfsoftware/stryker-js-plugin-runtime": "^5.0.2"
35
35
  },
36
36
  "devDependencies": {
37
37
  "@effect/platform-node": "4.0.0-rc.112",
@@ -56,8 +56,8 @@
56
56
  "rimraf": "^6.1.3",
57
57
  "tsdown": "^0.23.0",
58
58
  "vitest": "^4",
59
- "@systemfsoftware/stryker-config": "^0.1.0",
60
59
  "@systemfsoftware/tsdown-config": "^0.1.0",
60
+ "@systemfsoftware/stryker-config": "^0.1.0",
61
61
  "@systemfsoftware/vitest-config": "^0.1.0"
62
62
  },
63
63
  "inlinedDependencies": {