@systemfsoftware/stryker-js-instrumenter 5.0.2 → 6.0.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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,19 @@
1
1
  # @systemfsoftware/stryker-js-instrumenter
2
2
 
3
+ ## 6.0.0
4
+
5
+ ### Major Changes
6
+
7
+ - Nothing a consumer can observe moved in the four packages above, so no release is warranted.
8
+
9
+ `@systemfsoftware/stryker-js-instrumenter` now answers with promises: `transform` and `placeHeader` return `Promise`, and `AstTransformer` is a promise-returning function type. Await them where you call them. The parser is read on first use rather than at import, so importing this package no longer constructs Node's WebAssembly runtime, and `ExperimentalWarning: WASI` no longer appears until something is actually parsed.
10
+
11
+ ### Patch Changes
12
+
13
+ - Releases the workspace so its published versions track the shared dependency graph this change moves.
14
+
15
+ - The `@systemfsoftware/source` export condition is gone. It resolved to a package's TypeScript sources for editors and in-repo typechecks; each package now exports only its built entry. If your tsconfig sets `customConditions: ["@systemfsoftware/source"]`, or a bundler config names that condition, remove it — resolution falls back to the built entry, which is what every consumer already got.
16
+
3
17
  ## 5.0.2
4
18
 
5
19
  ### Patch Changes
package/dist/index.mjs CHANGED
@@ -5,7 +5,6 @@ import * as S from "effect/Schema";
5
5
  import * as Arr from "effect/Array";
6
6
  import * as Match from "effect/Match";
7
7
  import * as Option from "effect/Option";
8
- import { parseSync } from "oxc-parser";
9
8
  import path from "path";
10
9
  import "@systemfsoftware/stryker-js/Ignorer";
11
10
  import { propertyPath, strykerReportBugUrl } from "@systemfsoftware/stryker-js/Schema";
@@ -641,6 +640,13 @@ function isIndexedList(container, index) {
641
640
  return isNodeList(container) && Number.isInteger(index);
642
641
  }
643
642
  //#endregion
643
+ //#region src/Oxc.ts
644
+ let oxc;
645
+ const loadOxc = async () => {
646
+ if (oxc === void 0) oxc = await import("oxc-parser");
647
+ return oxc;
648
+ };
649
+ //#endregion
644
650
  //#region src/Parser.schema.ts
645
651
  var ParseFailed = class extends S.TaggedError("@systemfsoftware/stryker-js-instrumenter/ParseFailed")("ParseFailed", {
646
652
  fileName: S.String,
@@ -723,7 +729,8 @@ function fieldOf(value, key) {
723
729
  function appendIfDefined(values, value) {
724
730
  if (value !== void 0) values.push(value);
725
731
  }
726
- function parseWithOxc(text, fileName, lang) {
732
+ async function parseWithOxc(text, fileName, lang) {
733
+ const { parseSync } = await loadOxc();
727
734
  const result = parseSync(fileName, text, {
728
735
  lang,
729
736
  range: true
@@ -795,7 +802,7 @@ function getFormat(fileName, override) {
795
802
  }
796
803
  function createJSParser() {
797
804
  return async function parse(text, fileName) {
798
- const { root, comments } = parseWithOxc(text, fileName, "js");
805
+ const { root, comments } = await parseWithOxc(text, fileName, "js");
799
806
  return {
800
807
  originFileName: fileName,
801
808
  rawContent: text,
@@ -806,7 +813,7 @@ function createJSParser() {
806
813
  };
807
814
  }
808
815
  async function parseTS(text, fileName) {
809
- const { root, comments } = parseWithOxc(text, fileName, "ts");
816
+ const { root, comments } = await parseWithOxc(text, fileName, "ts");
810
817
  return {
811
818
  originFileName: fileName,
812
819
  rawContent: text,
@@ -816,7 +823,7 @@ async function parseTS(text, fileName) {
816
823
  };
817
824
  }
818
825
  async function parseTsx(text, fileName) {
819
- const { root, comments } = parseWithOxc(text, fileName, "tsx");
826
+ const { root, comments } = await parseWithOxc(text, fileName, "tsx");
820
827
  return {
821
828
  root,
822
829
  comments,
@@ -4794,7 +4801,7 @@ function isPropertyBearing(node) {
4794
4801
  }
4795
4802
  const strykerPlugins = [];
4796
4803
  const frameworkPluginsFileUrl = import.meta.url;
4797
- const parsedInstrumentationHeader = parseSync("instrumenter-header.js", `// @ts-nocheck
4804
+ const INSTRUMENTATION_HEADER_SOURCE = `// @ts-nocheck
4798
4805
  var ${STRYKER_NAMESPACE_HELPER} = function(){
4799
4806
  var g = typeof globalThis === 'object' && globalThis && globalThis.Math === Math && globalThis || new Function("return this")();
4800
4807
  var ns = g.${INSTRUMENTER_CONSTANTS.NAMESPACE} || (g.${INSTRUMENTER_CONSTANTS.NAMESPACE} = {});
@@ -4838,34 +4845,37 @@ var ${IS_MUTANT_ACTIVE_HELPER} = function(id) {
4838
4845
  }
4839
4846
  ${IS_MUTANT_ACTIVE_HELPER} = isActive;
4840
4847
  return isActive(id);
4841
- }`, {
4842
- lang: "js",
4843
- range: true
4844
- });
4845
- if (parsedInstrumentationHeader.errors.length > 0) throw new Error("Instrumentation header failed to parse");
4846
- const instrumentationHeader = parsedInstrumentationHeader.program.body;
4847
- deepFreeze(instrumentationHeader);
4848
- function placeHeaderIfNeeded(mutantCollector, originFileName, options, root) {
4849
- if (shouldPlaceHeader(mutantCollector, originFileName, options)) placeHeader(root);
4848
+ }`;
4849
+ let instrumentationHeaderValue;
4850
+ const instrumentationHeader = async () => {
4851
+ if (instrumentationHeaderValue === void 0) {
4852
+ instrumentationHeaderValue = (await parseWithOxc(INSTRUMENTATION_HEADER_SOURCE, "instrumenter-header.js", "js")).root.body;
4853
+ deepFreeze(instrumentationHeaderValue);
4854
+ }
4855
+ return instrumentationHeaderValue;
4856
+ };
4857
+ async function placeHeaderIfNeeded(mutantCollector, originFileName, options, root) {
4858
+ if (shouldPlaceHeader(mutantCollector, originFileName, options)) await placeHeader(root);
4850
4859
  }
4851
4860
  function shouldPlaceHeader(mutantCollector, originFileName, options) {
4852
4861
  return hasPlacedMutants(mutantCollector, originFileName) && options.noHeader !== true;
4853
4862
  }
4854
- function placeHeader(root) {
4855
- root.body.unshift(...headerFor(root));
4863
+ async function placeHeader(root) {
4864
+ root.body.unshift(...await headerFor(root));
4856
4865
  }
4857
- function headerFor(root) {
4866
+ async function headerFor(root) {
4867
+ const header = await instrumentationHeader();
4858
4868
  return Option.match(leadingCommentsOf(root), {
4859
- onNone: () => instrumentationHeader,
4860
- onSome: (leadingComments) => [commentedHeader(leadingComments), ...instrumentationHeader.slice(1)]
4869
+ onNone: () => header,
4870
+ onSome: (leadingComments) => [commentedHeader(leadingComments, header), ...header.slice(1)]
4861
4871
  });
4862
4872
  }
4863
4873
  function leadingCommentsOf(root) {
4864
4874
  const firstStatement = root.body[0];
4865
4875
  return Option.filter(Option.fromNullishOr(firstStatement?.leadingComments), isUnknownArray);
4866
4876
  }
4867
- function commentedHeader(leadingComments) {
4868
- const cloned = cloneNode(Option.getOrThrowWith(Option.fromNullishOr(instrumentationHeader[0]), () => /* @__PURE__ */ new Error("Instrumentation header is empty")));
4877
+ function commentedHeader(leadingComments, header) {
4878
+ const cloned = cloneNode(Option.getOrThrowWith(Option.fromNullishOr(header[0]), () => /* @__PURE__ */ new Error("Instrumentation header is empty")));
4869
4879
  cloned.leadingComments = leadingComments;
4870
4880
  return cloned;
4871
4881
  }
@@ -4905,7 +4915,7 @@ function isMap(value) {
4905
4915
  function isSet(value) {
4906
4916
  return value instanceof Set;
4907
4917
  }
4908
- function transform(ast, mutantCollector, transformerContext) {
4918
+ async function transform(ast, mutantCollector, transformerContext) {
4909
4919
  const context = {
4910
4920
  ...transformerContext,
4911
4921
  transform
@@ -4918,34 +4928,31 @@ function transform(ast, mutantCollector, transformerContext) {
4918
4928
  case "svelte": return transformSvelte(ast, mutantCollector, context);
4919
4929
  }
4920
4930
  }
4921
- const transformHtml = ({ root }, mutantCollector, context) => {
4931
+ const transformHtml = async ({ root }, mutantCollector, context) => {
4922
4932
  const warnings = [];
4923
- root.scripts.forEach((ast) => {
4924
- warnings.push(...context.transform(ast, mutantCollector, context));
4925
- });
4933
+ for (const script of root.scripts) warnings.push(...await context.transform(script, mutantCollector, context));
4926
4934
  return warnings;
4927
4935
  };
4928
4936
  const moduleScript = `<script context="module">
4929
4937
  \n<\/script>\n`;
4930
- const transformSvelte = (svelte, mutantCollector, context) => {
4938
+ const transformSvelte = async (svelte, mutantCollector, context) => {
4931
4939
  const warnings = [];
4932
4940
  const { root } = svelte;
4933
- [root.moduleScript, ...root.additionalScripts].filter(Predicate.isNotNullish).forEach((script) => {
4934
- warnings.push(...context.transform(script.ast, mutantCollector, {
4935
- ...context,
4936
- options: {
4937
- ...context.options,
4938
- noHeader: true
4939
- }
4940
- }));
4941
- });
4942
- placeModuleHeaderIfNeeded(svelte, mutantCollector);
4941
+ const scripts = [root.moduleScript, ...root.additionalScripts].filter(Predicate.isNotNullish);
4942
+ for (const script of scripts) warnings.push(...await context.transform(script.ast, mutantCollector, {
4943
+ ...context,
4944
+ options: {
4945
+ ...context.options,
4946
+ noHeader: true
4947
+ }
4948
+ }));
4949
+ await placeModuleHeaderIfNeeded(svelte, mutantCollector);
4943
4950
  return warnings;
4944
4951
  };
4945
- function placeModuleHeaderIfNeeded(svelte, mutantCollector) {
4946
- if (hasPlacedMutants(mutantCollector, svelte.originFileName)) placeModuleHeader(svelte);
4952
+ async function placeModuleHeaderIfNeeded(svelte, mutantCollector) {
4953
+ if (hasPlacedMutants(mutantCollector, svelte.originFileName)) await placeModuleHeader(svelte);
4947
4954
  }
4948
- function placeModuleHeader(svelte) {
4955
+ async function placeModuleHeader(svelte) {
4949
4956
  const { root, originFileName } = svelte;
4950
4957
  if (!root.moduleScript) {
4951
4958
  root.moduleScript = {
@@ -4968,7 +4975,7 @@ function placeModuleHeader(svelte) {
4968
4975
  script.range.end += moduleScript.length;
4969
4976
  });
4970
4977
  }
4971
- placeHeader(root.moduleScript.ast.root);
4978
+ await placeHeader(root.moduleScript.ast.root);
4972
4979
  }
4973
4980
  function emptyProgram() {
4974
4981
  return {
@@ -4980,7 +4987,7 @@ function emptyProgram() {
4980
4987
  function isMutateRangeList(value) {
4981
4988
  return Array.isArray(value);
4982
4989
  }
4983
- const transformScript = ({ root, originFileName, rawContent, offset, comments }, mutantCollector, { options, mutateDescription }, mutators, mutantPlacers) => {
4990
+ const transformScript = async ({ root, originFileName, rawContent, offset, comments }, mutantCollector, { options, mutateDescription }, mutators, mutantPlacers) => {
4984
4991
  const lineTable = buildLineTable(rawContent);
4985
4992
  attachComments(root, comments, lineTable);
4986
4993
  const placementMap = /* @__PURE__ */ new Map();
@@ -5001,7 +5008,7 @@ const transformScript = ({ root, originFileName, rawContent, offset, comments },
5001
5008
  if (hasAppliedMutants(placement)) applyPlacement(path, placement);
5002
5009
  }
5003
5010
  });
5004
- placeHeaderIfNeeded(mutantCollector, originFileName, options, root);
5011
+ await placeHeaderIfNeeded(mutantCollector, originFileName, options, root);
5005
5012
  return warnings;
5006
5013
  function visitNode(path) {
5007
5014
  if (shouldSkip(path)) {
@@ -5303,7 +5310,7 @@ const readCollected = (command) => Effect.gen(function* () {
5303
5310
  ast
5304
5311
  })));
5305
5312
  const collector = createMutantCollector();
5306
- yield* Effect.forEach(parsed, ({ file, ast }) => Effect.try({
5313
+ yield* Effect.forEach(parsed, ({ file, ast }) => Effect.tryPromise({
5307
5314
  try: () => transform(ast, collector, {
5308
5315
  options: toTransformerOptions(options),
5309
5316
  mutateDescription: toOneBasedLineNumber(file.mutate)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@systemfsoftware/stryker-js-instrumenter",
3
- "version": "5.0.2",
3
+ "version": "6.0.0",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "git+https://github.com/systemfsoftware/systemfsoftware.git",
@@ -24,11 +24,11 @@
24
24
  "angular-html-parser": "~10.4.0",
25
25
  "effect": "4.0.0-rc.112",
26
26
  "oxc-parser": "^0.140.0",
27
- "@systemfsoftware/effect-cell-types": "^7.0.0",
28
- "@systemfsoftware/stryker-js": "^3.0.1"
27
+ "@systemfsoftware/stryker-js": "^3.0.2",
28
+ "@systemfsoftware/effect-cell-types": "^7.0.1"
29
29
  },
30
30
  "devDependencies": {
31
- "@systemfsoftware/arethetypeswrong-cli": "^1.1.1",
31
+ "@systemfsoftware/arethetypeswrong-cli": "^4.1.0",
32
32
  "@types/estree": "1.0.8",
33
33
  "@types/node": "^24",
34
34
  "oxlint": "^1.77.0",
@@ -37,11 +37,11 @@
37
37
  "tsdown": "^0.22.14",
38
38
  "typescript": "^7",
39
39
  "vitest": "^4",
40
- "@systemfsoftware/all": "^2.0.0",
41
- "@systemfsoftware/effect-gherkin-spec": "^4.0.1",
40
+ "@systemfsoftware/all": "^2.0.1",
41
+ "@systemfsoftware/effect-gherkin-spec": "^4.0.2",
42
+ "@systemfsoftware/vitest-config": "^0.1.0",
42
43
  "@systemfsoftware/oxlint-config": "^0.1.0",
43
- "@systemfsoftware/tsconfig": "^1.3.3",
44
- "@systemfsoftware/vitest-config": "^0.1.0"
44
+ "@systemfsoftware/tsconfig": "^1.3.4"
45
45
  },
46
46
  "engines": {
47
47
  "node": ">=20.0.0"