@jsenv/core 27.7.0 → 27.8.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.
Files changed (29) hide show
  1. package/dist/main.js +107 -120
  2. package/package.json +1 -1
  3. package/src/build/build.js +4 -5
  4. package/src/dev/start_dev_server.js +1 -1
  5. package/src/execute/execute.js +2 -2
  6. package/src/omega/kitchen.js +9 -14
  7. package/src/omega/omega_server.js +2 -2
  8. package/src/omega/server/file_service.js +11 -11
  9. package/src/plugins/autoreload/jsenv_plugin_autoreload.js +0 -4
  10. package/src/plugins/autoreload/jsenv_plugin_autoreload_client.js +1 -1
  11. package/src/plugins/autoreload/jsenv_plugin_autoreload_server.js +1 -1
  12. package/src/plugins/autoreload/jsenv_plugin_hmr.js +1 -1
  13. package/src/plugins/bundling/jsenv_plugin_bundling.js +1 -3
  14. package/src/plugins/cache_control/jsenv_plugin_cache_control.js +2 -5
  15. package/src/plugins/commonjs_globals/jsenv_plugin_commonjs_globals.js +2 -2
  16. package/src/plugins/file_urls/jsenv_plugin_file_urls.js +4 -8
  17. package/src/plugins/html_supervisor/jsenv_plugin_html_supervisor.js +1 -4
  18. package/src/plugins/import_meta_hot/jsenv_plugin_import_meta_hot.js +2 -2
  19. package/src/plugins/import_meta_scenarios/jsenv_plugin_import_meta_scenarios.js +18 -24
  20. package/src/plugins/importmap/jsenv_plugin_importmap.js +1 -1
  21. package/src/plugins/minification/jsenv_plugin_minification.js +1 -3
  22. package/src/plugins/node_esm_resolution/jsenv_plugin_node_esm_resolution.js +9 -7
  23. package/src/plugins/plugin_controller.js +17 -6
  24. package/src/plugins/plugins.js +0 -2
  25. package/src/plugins/toolbar/jsenv_plugin_toolbar.js +1 -3
  26. package/src/plugins/transpilation/import_assertions/jsenv_plugin_import_assertions.js +1 -1
  27. package/src/plugins/url_analysis/html/html_urls.js +2 -2
  28. package/src/test/execute_plan.js +2 -2
  29. package/src/test/execute_test_plan.js +1 -1
package/dist/main.js CHANGED
@@ -4217,11 +4217,11 @@ const parseAndTransformHtmlUrls = async (urlInfo, context) => {
4217
4217
  const url = urlInfo.originalUrl;
4218
4218
  const content = urlInfo.content;
4219
4219
  const {
4220
- scenario,
4220
+ scenarios,
4221
4221
  referenceUtils
4222
4222
  } = context;
4223
4223
  const htmlAst = parseHtmlString(content, {
4224
- storeOriginalPositions: scenario !== "build"
4224
+ storeOriginalPositions: scenarios.dev
4225
4225
  });
4226
4226
  const actions = [];
4227
4227
  visitHtmlUrls({
@@ -11464,7 +11464,7 @@ const jsenvPluginImportmap = () => {
11464
11464
  // Duing build we get rid of it
11465
11465
 
11466
11466
 
11467
- if (context.scenario === "build") {
11467
+ if (context.scenarios.build) {
11468
11468
  removeHtmlNode(importmap);
11469
11469
  }
11470
11470
 
@@ -12801,13 +12801,8 @@ const jsenvPluginNodeEsmResolution = ({
12801
12801
  return {
12802
12802
  name: "jsenv:node_esm_resolution",
12803
12803
  appliesDuring: "*",
12804
- init: ({
12805
- rootDirectoryUrl,
12806
- scenario,
12807
- runtimeCompat,
12808
- urlGraph
12809
- }) => {
12810
- const nodeRuntimeEnabled = Object.keys(runtimeCompat).includes("node"); // https://nodejs.org/api/esm.html#resolver-algorithm-specification
12804
+ init: context => {
12805
+ const nodeRuntimeEnabled = Object.keys(context.runtimeCompat).includes("node"); // https://nodejs.org/api/esm.html#resolver-algorithm-specification
12811
12806
 
12812
12807
  packageConditions = packageConditions || [...readCustomConditionsFromProcessArgs(), nodeRuntimeEnabled ? "node" : "browser", "import"];
12813
12808
  const packageScopesCache = new Map();
@@ -12838,19 +12833,19 @@ const jsenvPluginNodeEsmResolution = ({
12838
12833
  return packageJson;
12839
12834
  };
12840
12835
 
12841
- if (scenario === "dev") {
12836
+ if (context.scenarios.dev) {
12842
12837
  const onFileChange = () => {
12843
12838
  packageScopesCache.clear();
12844
12839
  packageJsonsCache.clear();
12845
- urlGraph.urlInfoMap.forEach(urlInfo => {
12840
+ context.urlGraph.urlInfoMap.forEach(urlInfo => {
12846
12841
  if (urlInfo.dependsOnPackageJson) {
12847
- urlGraph.considerModified(urlInfo);
12842
+ context.urlGraph.considerModified(urlInfo);
12848
12843
  }
12849
12844
  });
12850
12845
  };
12851
12846
 
12852
12847
  filesInvalidatingCache.forEach(file => {
12853
- const unregister = registerFileLifecycle(new URL(file, rootDirectoryUrl), {
12848
+ const unregister = registerFileLifecycle(new URL(file, context.rootDirectoryUrl), {
12854
12849
  added: () => {
12855
12850
  onFileChange();
12856
12851
  },
@@ -12912,7 +12907,7 @@ const jsenvPluginNodeEsmResolution = ({
12912
12907
  return null;
12913
12908
  },
12914
12909
  transformUrlSearchParams: (reference, context) => {
12915
- if (context.scenario === "build") {
12910
+ if (context.scenarios.build) {
12916
12911
  return null;
12917
12912
  }
12918
12913
 
@@ -13091,14 +13086,10 @@ const jsenvPluginFileUrls = ({
13091
13086
  }
13092
13087
  }, {
13093
13088
  name: "jsenv:@fs_resolution",
13094
- appliesDuring: {
13095
- // during dev and test it's a browser running the code
13096
- // so absolute file urls needs to be relativized
13097
- dev: true,
13098
- test: true,
13099
- // during build it's fine to use file:// urls
13100
- build: false
13101
- },
13089
+ // during dev and test it's a browser running the code
13090
+ // so absolute file urls needs to be relativized
13091
+ // during build it's fine to use file:// urls
13092
+ appliesDuring: "dev",
13102
13093
  resolveUrl: reference => {
13103
13094
  if (reference.specifier.startsWith("/@fs/")) {
13104
13095
  const fsRootRelativeUrl = reference.specifier.slice("/@fs/".length);
@@ -13197,10 +13188,7 @@ const jsenvPluginHtmlSupervisor = ({
13197
13188
  const htmlSupervisorInstallerFileUrl = new URL("./js/html_supervisor_installer.js", import.meta.url).href;
13198
13189
  return {
13199
13190
  name: "jsenv:html_supervisor",
13200
- appliesDuring: {
13201
- dev: true,
13202
- test: true
13203
- },
13191
+ appliesDuring: "dev",
13204
13192
  serve: async (request, context) => {
13205
13193
  if (request.ressource.startsWith("/__get_code_frame__/")) {
13206
13194
  const {
@@ -13569,16 +13557,14 @@ const generateCodeToSuperviseScript = ({
13569
13557
  * - global
13570
13558
  */
13571
13559
  const jsenvPluginCommonJsGlobals = () => {
13572
- const transformCommonJsGlobals = async (urlInfo, {
13573
- scenario
13574
- }) => {
13560
+ const transformCommonJsGlobals = async (urlInfo, context) => {
13575
13561
  if (!urlInfo.content.includes("process.env.NODE_ENV") && !urlInfo.content.includes("__filename") && !urlInfo.content.includes("__dirname")) {
13576
13562
  return null;
13577
13563
  }
13578
13564
 
13579
13565
  const isJsModule = urlInfo.type === "js_module";
13580
13566
  const replaceMap = {
13581
- "process.env.NODE_ENV": `("${scenario === "dev" || scenario === "test" ? "development" : "production"}")`,
13567
+ "process.env.NODE_ENV": `("${context.scenarios.dev ? "development" : "production"}")`,
13582
13568
  "global": "globalThis",
13583
13569
  "__filename": isJsModule ? `import.meta.url.slice('file:///'.length)` : `document.currentScript.src`,
13584
13570
  "__dirname": isJsModule ? `import.meta.url.slice('file:///'.length).replace(/[\\\/\\\\][^\\\/\\\\]*$/, '')` : `new URL('./', document.currentScript.src).href`
@@ -13732,11 +13718,10 @@ const babelPluginMetadataExpressionPaths = (babel, {
13732
13718
  /*
13733
13719
  * Source code can contain the following
13734
13720
  * - import.meta.dev
13735
- * - import.meta.test
13736
13721
  * - import.meta.build
13737
13722
  * They are either:
13738
13723
  * - replaced by true: When scenario matches (import.meta.dev and it's the dev server)
13739
- * - left as is to be evaluated to undefined (import.meta.test but it's the dev server)
13724
+ * - left as is to be evaluated to undefined (import.meta.build but it's the dev server)
13740
13725
  * - replaced by undefined (import.meta.dev but it's build; the goal is to ensure it's tree-shaked)
13741
13726
  */
13742
13727
  const jsenvPluginImportMetaScenarios = () => {
@@ -13744,9 +13729,7 @@ const jsenvPluginImportMetaScenarios = () => {
13744
13729
  name: "jsenv:import_meta_scenario",
13745
13730
  appliesDuring: "*",
13746
13731
  transformUrlContent: {
13747
- js_module: async (urlInfo, {
13748
- scenario
13749
- }) => {
13732
+ js_module: async (urlInfo, context) => {
13750
13733
  if (!urlInfo.content.includes("import.meta.dev") && !urlInfo.content.includes("import.meta.test") && !urlInfo.content.includes("import.meta.build")) {
13751
13734
  return null;
13752
13735
  }
@@ -13771,34 +13754,31 @@ const jsenvPluginImportMetaScenarios = () => {
13771
13754
  });
13772
13755
  };
13773
13756
 
13774
- if (scenario === "dev") {
13775
- dev.forEach(path => {
13776
- replace(path, "true");
13777
- });
13778
- } else if (scenario === "test") {
13779
- // test is also considered a dev environment
13780
- // just like the dev server can be used to debug test files
13781
- // without this people would have to write
13782
- // if (import.meta.dev || import.meta.test) or if (!import.meta.build)
13783
- dev.forEach(path => {
13784
- replace(path, "true");
13785
- });
13786
- test.forEach(path => {
13787
- replace(path, "true");
13788
- });
13789
- } else if (scenario === "build") {
13790
- // replacing by undefined might not be required
13791
- // as I suppose rollup would consider them as undefined
13792
- // but let's make it explicit to ensure code is properly tree-shaked
13757
+ if (context.scenarios.build) {
13758
+ // during build ensure replacement for tree-shaking
13793
13759
  dev.forEach(path => {
13794
13760
  replace(path, "undefined");
13795
13761
  });
13796
13762
  test.forEach(path => {
13797
- replace(path, "undefined");
13763
+ replace(path, context.scenarios.test ? "true" : "undefined");
13798
13764
  });
13799
13765
  build.forEach(path => {
13800
13766
  replace(path, "true");
13801
13767
  });
13768
+ } else {
13769
+ // during dev we can let "import.meta.build" untouched
13770
+ // it will be evaluated to undefined.
13771
+ // Moreover it can be surprising to see some "undefined"
13772
+ // when source file contains "import.meta.build"
13773
+ dev.forEach(path => {
13774
+ replace(path, "true");
13775
+ });
13776
+
13777
+ if (context.scenarios.test) {
13778
+ test.forEach(path => {
13779
+ replace(path, "true");
13780
+ });
13781
+ }
13802
13782
  }
13803
13783
 
13804
13784
  const magicSource = createMagicSource(urlInfo.content);
@@ -13863,7 +13843,6 @@ const babelPluginMetadataImportMetaScenarios = () => {
13863
13843
  });
13864
13844
  state.file.metadata.importMetaScenarios = {
13865
13845
  dev: importMetas.dev,
13866
- test: importMetas.test,
13867
13846
  build: importMetas.build
13868
13847
  };
13869
13848
  }
@@ -13933,7 +13912,7 @@ const jsenvPluginImportAssertions = ({
13933
13912
  // We would have to tell rollup to ignore import with assertion
13934
13913
  // - means rollup can bundle more js file together
13935
13914
  // - means url versioning can work for css inlined in js
13936
- if (context.scenario === "build") {
13915
+ if (context.scenarios.build) {
13937
13916
  json = true;
13938
13917
  css = true;
13939
13918
  text = true;
@@ -16034,9 +16013,7 @@ const jsenvPluginBundling = bundling => {
16034
16013
  });
16035
16014
  return {
16036
16015
  name: "jsenv:bundling",
16037
- appliesDuring: {
16038
- build: true
16039
- },
16016
+ appliesDuring: "build",
16040
16017
  bundle: {
16041
16018
  css: bundling.css ? (cssUrlInfos, context) => {
16042
16019
  return bundleCss({
@@ -16172,9 +16149,7 @@ const jsenvPluginMinification = minification => {
16172
16149
  }) : null;
16173
16150
  return {
16174
16151
  name: "jsenv:minification",
16175
- appliesDuring: {
16176
- build: true
16177
- },
16152
+ appliesDuring: "build",
16178
16153
  optimizeUrlContent: {
16179
16154
  html: htmlOptimizer,
16180
16155
  svg: htmlOptimizer,
@@ -16494,7 +16469,7 @@ const jsenvPluginImportMetaHot = () => {
16494
16469
  transformUrlContent: {
16495
16470
  html: (htmlUrlInfo, context) => {
16496
16471
  // during build we don't really care to parse html hot dependencies
16497
- if (context.scenario === "build") {
16472
+ if (context.scenarios.build) {
16498
16473
  return;
16499
16474
  }
16500
16475
 
@@ -16543,7 +16518,7 @@ const jsenvPluginImportMetaHot = () => {
16543
16518
  return null;
16544
16519
  }
16545
16520
 
16546
- if (context.scenario === "build") {
16521
+ if (context.scenarios.build) {
16547
16522
  return removeImportMetaHots(urlInfo, importMetaHotPaths);
16548
16523
  }
16549
16524
 
@@ -16587,7 +16562,8 @@ const jsenvPluginHmr = () => {
16587
16562
  return {
16588
16563
  name: "jsenv:hmr",
16589
16564
  appliesDuring: {
16590
- dev: true
16565
+ dev: true,
16566
+ test: false
16591
16567
  },
16592
16568
  redirectUrl: reference => {
16593
16569
  const urlObject = new URL(reference.url);
@@ -16632,7 +16608,8 @@ const jsenvPluginAutoreloadClient = () => {
16632
16608
  return {
16633
16609
  name: "jsenv:autoreload_client",
16634
16610
  appliesDuring: {
16635
- dev: true
16611
+ dev: true,
16612
+ test: false
16636
16613
  },
16637
16614
  transformUrlContent: {
16638
16615
  html: (htmlUrlInfo, context) => {
@@ -16664,7 +16641,8 @@ const jsenvPluginAutoreloadServer = ({
16664
16641
  return {
16665
16642
  name: "jsenv:autoreload_server",
16666
16643
  appliesDuring: {
16667
- dev: true
16644
+ dev: true,
16645
+ test: false
16668
16646
  },
16669
16647
  serverEvents: {
16670
16648
  reload: ({
@@ -16892,14 +16870,9 @@ const jsenvPluginAutoreloadServer = ({
16892
16870
  };
16893
16871
 
16894
16872
  const jsenvPluginAutoreload = ({
16895
- scenario,
16896
16873
  clientFileChangeCallbackList,
16897
16874
  clientFilesPruneCallbackList
16898
16875
  }) => {
16899
- if (scenario === "build") {
16900
- return [];
16901
- }
16902
-
16903
16876
  return [jsenvPluginHmr(), jsenvPluginAutoreloadClient(), jsenvPluginAutoreloadServer({
16904
16877
  clientFileChangeCallbackList,
16905
16878
  clientFilesPruneCallbackList
@@ -16909,14 +16882,11 @@ const jsenvPluginAutoreload = ({
16909
16882
  const jsenvPluginCacheControl = () => {
16910
16883
  return {
16911
16884
  name: "jsenv:cache_control",
16912
- appliesDuring: {
16913
- dev: true,
16914
- test: true
16915
- },
16885
+ appliesDuring: "dev",
16916
16886
  augmentResponse: ({
16917
16887
  reference
16918
16888
  }, context) => {
16919
- if (context.scenario === "test") {
16889
+ if (context.scenarios.test) {
16920
16890
  // During dev, all files are put into browser cache for 1 hour because:
16921
16891
  // 1: Browser cache is a temporary directory created by playwright
16922
16892
  // 2: We assume source files won't be modified while tests are running
@@ -17003,7 +16973,6 @@ const jsenvPluginExplorer = ({
17003
16973
 
17004
16974
  const getCorePlugins = ({
17005
16975
  rootDirectoryUrl,
17006
- scenario,
17007
16976
  runtimeCompat,
17008
16977
  urlAnalysis = {},
17009
16978
  htmlSupervisor,
@@ -17048,7 +17017,6 @@ const getCorePlugins = ({
17048
17017
  jsenvPluginNodeEsmResolution(nodeEsmResolution), jsenvPluginUrlResolution(), jsenvPluginUrlVersion(), jsenvPluginCommonJsGlobals(), jsenvPluginImportMetaScenarios(), jsenvPluginNodeRuntime({
17049
17018
  runtimeCompat
17050
17019
  }), jsenvPluginBundling(bundling), jsenvPluginMinification(minification), jsenvPluginImportMetaHot(), ...(clientAutoreload ? [jsenvPluginAutoreload({ ...clientAutoreload,
17051
- scenario,
17052
17020
  clientFileChangeCallbackList,
17053
17021
  clientFilesPruneCallbackList
17054
17022
  })] : []), jsenvPluginCacheControl(), ...(explorer ? [jsenvPluginExplorer(explorer)] : [])];
@@ -20743,10 +20711,10 @@ const HOOK_NAMES = ["init", "serve", // is called only during dev/tests
20743
20711
  "destroy"];
20744
20712
  const createPluginController = ({
20745
20713
  plugins,
20746
- scenario
20714
+ scenarios
20747
20715
  }) => {
20748
20716
  const flatPlugins = flattenAndFilterPlugins(plugins, {
20749
- scenario
20717
+ scenarios
20750
20718
  }); // precompute a list of hooks per hookName for one major reason:
20751
20719
  // - When debugging, there is less iteration
20752
20720
  // also it should increase perf as there is less work to do
@@ -20953,7 +20921,7 @@ const createPluginController = ({
20953
20921
  };
20954
20922
 
20955
20923
  const flattenAndFilterPlugins = (plugins, {
20956
- scenario
20924
+ scenarios
20957
20925
  }) => {
20958
20926
  const flatPlugins = [];
20959
20927
 
@@ -20983,12 +20951,13 @@ const flattenAndFilterPlugins = (plugins, {
20983
20951
  }
20984
20952
 
20985
20953
  if (typeof appliesDuring === "string") {
20986
- if (!["dev", "build", "test"].includes(appliesDuring)) {
20954
+ if (!["dev", "test", "build"].includes(appliesDuring)) {
20987
20955
  throw new Error(`"appliesDuring" must be "dev", "test" or "build", got ${appliesDuring}`);
20988
20956
  }
20989
20957
 
20990
- if (appliesDuring === scenario) {
20958
+ if (scenarios[appliesDuring]) {
20991
20959
  flatPlugins.push(pluginEntry);
20960
+ return;
20992
20961
  }
20993
20962
 
20994
20963
  return;
@@ -20998,7 +20967,20 @@ const flattenAndFilterPlugins = (plugins, {
20998
20967
  throw new Error(`"appliesDuring" must be an object or a string, got ${appliesDuring}`);
20999
20968
  }
21000
20969
 
21001
- if (appliesDuring[scenario]) {
20970
+ let applies;
20971
+
20972
+ for (const key of Object.keys(appliesDuring)) {
20973
+ if (!appliesDuring[key] && scenarios[key]) {
20974
+ applies = false;
20975
+ break;
20976
+ }
20977
+
20978
+ if (appliesDuring[key] && scenarios[key]) {
20979
+ applies = true;
20980
+ }
20981
+ }
20982
+
20983
+ if (applies) {
21002
20984
  flatPlugins.push(pluginEntry);
21003
20985
  return;
21004
20986
  }
@@ -21710,19 +21692,15 @@ const createKitchen = ({
21710
21692
  signal,
21711
21693
  logLevel,
21712
21694
  rootDirectoryUrl,
21713
- scenario,
21695
+ scenarios,
21714
21696
  runtimeCompat,
21715
21697
  // during dev/test clientRuntimeCompat is a single runtime
21716
21698
  // during build clientRuntimeCompat is runtimeCompat
21717
21699
  clientRuntimeCompat = runtimeCompat,
21718
21700
  urlGraph,
21719
21701
  plugins,
21720
- sourcemaps = {
21721
- dev: "inline",
21722
- // "programmatic" and "file" also allowed
21723
- test: "inline",
21724
- build: "none"
21725
- }[scenario],
21702
+ sourcemaps = scenarios.dev ? "inline" : "none",
21703
+ // "programmatic" and "file" also allowed
21726
21704
  sourcemapsSourcesProtocol,
21727
21705
  sourcemapsSourcesContent,
21728
21706
  sourcemapsRelativeSources,
@@ -21733,7 +21711,7 @@ const createKitchen = ({
21733
21711
  });
21734
21712
  const pluginController = createPluginController({
21735
21713
  plugins,
21736
- scenario
21714
+ scenarios
21737
21715
  });
21738
21716
  const jsenvDirectoryUrl = new URL(".jsenv/", rootDirectoryUrl).href;
21739
21717
  const kitchenContext = {
@@ -21741,7 +21719,7 @@ const createKitchen = ({
21741
21719
  logger,
21742
21720
  rootDirectoryUrl,
21743
21721
  urlGraph,
21744
- scenario,
21722
+ scenarios,
21745
21723
  runtimeCompat,
21746
21724
  clientRuntimeCompat,
21747
21725
  isSupportedOnCurrentClients: feature => {
@@ -22446,7 +22424,7 @@ const applyReferenceEffectsOnUrlInfo = (reference, urlInfo, context) => {
22446
22424
  column: reference.specifierColumn
22447
22425
  };
22448
22426
  urlInfo.contentType = reference.contentType;
22449
- urlInfo.originalContent = context.scenario === "build" ? urlInfo.originalContent === undefined ? reference.content : urlInfo.originalContent : reference.content;
22427
+ urlInfo.originalContent = context.scenarios.build ? urlInfo.originalContent === undefined ? reference.content : urlInfo.originalContent : reference.content;
22450
22428
  urlInfo.content = reference.content;
22451
22429
  }
22452
22430
  };
@@ -23581,7 +23559,9 @@ build ${entryPointKeys.length} entry points`);
23581
23559
  logger,
23582
23560
  rootDirectoryUrl,
23583
23561
  urlGraph: rawGraph,
23584
- scenario: "build",
23562
+ scenarios: {
23563
+ build: true
23564
+ },
23585
23565
  sourcemaps,
23586
23566
  sourcemapsSourcesContent,
23587
23567
  runtimeCompat,
@@ -23603,7 +23583,6 @@ build ${entryPointKeys.length} entry points`);
23603
23583
  }, ...getCorePlugins({
23604
23584
  rootDirectoryUrl,
23605
23585
  urlGraph: rawGraph,
23606
- scenario: "build",
23607
23586
  runtimeCompat,
23608
23587
  urlAnalysis,
23609
23588
  nodeEsmResolution,
@@ -23821,7 +23800,9 @@ build ${entryPointKeys.length} entry points`);
23821
23800
  logger,
23822
23801
  rootDirectoryUrl,
23823
23802
  urlGraph: finalGraph,
23824
- scenario: "build",
23803
+ scenarios: {
23804
+ build: true
23805
+ },
23825
23806
  sourcemaps,
23826
23807
  sourcemapsSourcesContent,
23827
23808
  sourcemapsRelativeSources: !versioning,
@@ -24483,7 +24464,9 @@ const applyUrlVersioning = async ({
24483
24464
  logger,
24484
24465
  rootDirectoryUrl: buildDirectoryUrl,
24485
24466
  urlGraph: finalGraph,
24486
- scenario: "build",
24467
+ scenarios: {
24468
+ build: true
24469
+ },
24487
24470
  sourcemaps,
24488
24471
  sourcemapsSourcesContent,
24489
24472
  sourcemapsRelativeSources: true,
@@ -24496,9 +24479,7 @@ const applyUrlVersioning = async ({
24496
24479
  allowEscapeForVersioning: true
24497
24480
  }), {
24498
24481
  name: "jsenv:versioning",
24499
- appliesDuring: {
24500
- build: true
24501
- },
24482
+ appliesDuring: "build",
24502
24483
  resolveUrl: reference => {
24503
24484
  const buildUrl = buildUrls[reference.specifier];
24504
24485
 
@@ -24893,7 +24874,7 @@ const createFileService = ({
24893
24874
  serverStopCallbacks,
24894
24875
  serverEventsDispatcher,
24895
24876
  rootDirectoryUrl,
24896
- scenario,
24877
+ scenarios,
24897
24878
  runtimeCompat,
24898
24879
  plugins,
24899
24880
  urlAnalysis,
@@ -24931,7 +24912,7 @@ const createFileService = ({
24931
24912
  ".jsenv/": false
24932
24913
  };
24933
24914
 
24934
- if (scenario === "dev") {
24915
+ if (scenarios.dev) {
24935
24916
  const stopWatchingClientFiles = registerDirectoryLifecycle(rootDirectoryUrl, {
24936
24917
  watchPatterns: clientFilePatterns,
24937
24918
  cooldownBetweenFileEvents,
@@ -24995,13 +24976,13 @@ const createFileService = ({
24995
24976
 
24996
24977
  urlInfo.isValid = () => watch;
24997
24978
  },
24998
- includeOriginalUrls: scenario === "dev"
24979
+ includeOriginalUrls: scenarios.dev
24999
24980
  });
25000
24981
  const kitchen = createKitchen({
25001
24982
  signal,
25002
24983
  logLevel,
25003
24984
  rootDirectoryUrl,
25004
- scenario,
24985
+ scenarios,
25005
24986
  runtimeCompat,
25006
24987
  clientRuntimeCompat: {
25007
24988
  [runtimeName]: runtimeVersion
@@ -25009,7 +24990,6 @@ const createFileService = ({
25009
24990
  urlGraph,
25010
24991
  plugins: [...plugins, ...getCorePlugins({
25011
24992
  rootDirectoryUrl,
25012
- scenario,
25013
24993
  runtimeCompat,
25014
24994
  urlAnalysis,
25015
24995
  htmlSupervisor,
@@ -25052,7 +25032,7 @@ const createFileService = ({
25052
25032
  allServerEvents[serverEventName]({
25053
25033
  rootDirectoryUrl,
25054
25034
  urlGraph,
25055
- scenario,
25035
+ scenarios,
25056
25036
  sendServerEvent: data => {
25057
25037
  serverEventsDispatcher.dispatch({
25058
25038
  type: serverEventName,
@@ -25068,7 +25048,7 @@ const createFileService = ({
25068
25048
 
25069
25049
  const context = {
25070
25050
  rootDirectoryUrl,
25071
- scenario,
25051
+ scenarios,
25072
25052
  runtimeName,
25073
25053
  runtimeVersion,
25074
25054
  urlGraph,
@@ -25155,7 +25135,7 @@ const createFileService = ({
25155
25135
  await kitchen.cook(urlInfo, {
25156
25136
  request,
25157
25137
  reference,
25158
- outDirectoryUrl: scenario === "dev" ? `${rootDirectoryUrl}.jsenv/${runtimeName}@${runtimeVersion}/` : `${rootDirectoryUrl}.jsenv/${scenario}/${runtimeName}@${runtimeVersion}/`
25138
+ outDirectoryUrl: scenarios.dev ? `${rootDirectoryUrl}.jsenv/${runtimeName}@${runtimeVersion}/` : `${rootDirectoryUrl}.jsenv/${scenarios.test ? "test" : "build"}/${runtimeName}@${runtimeVersion}/`
25159
25139
  });
25160
25140
  let {
25161
25141
  response
@@ -25287,7 +25267,7 @@ const startOmegaServer = async ({
25287
25267
  onStop = () => {},
25288
25268
  services = [],
25289
25269
  rootDirectoryUrl,
25290
- scenario,
25270
+ scenarios,
25291
25271
  runtimeCompat,
25292
25272
  plugins,
25293
25273
  urlAnalysis,
@@ -25340,7 +25320,7 @@ const startOmegaServer = async ({
25340
25320
  serverStopCallbacks,
25341
25321
  serverEventsDispatcher,
25342
25322
  rootDirectoryUrl,
25343
- scenario,
25323
+ scenarios,
25344
25324
  runtimeCompat,
25345
25325
  plugins,
25346
25326
  urlAnalysis,
@@ -25572,7 +25552,9 @@ const startDevServer = async ({
25572
25552
  port,
25573
25553
  services,
25574
25554
  rootDirectoryUrl,
25575
- scenario: "dev",
25555
+ scenarios: {
25556
+ dev: true
25557
+ },
25576
25558
  runtimeCompat,
25577
25559
  plugins,
25578
25560
  urlAnalysis,
@@ -26891,7 +26873,7 @@ const executePlan = async (plan, {
26891
26873
  coverageMethodForNodeJs,
26892
26874
  coverageV8ConflictWarning,
26893
26875
  coverageTempDirectoryRelativeUrl,
26894
- scenario,
26876
+ scenarios,
26895
26877
  sourcemaps,
26896
26878
  plugins,
26897
26879
  nodeEsmResolution,
@@ -27036,7 +27018,7 @@ const executePlan = async (plan, {
27036
27018
  privateKey,
27037
27019
  services,
27038
27020
  rootDirectoryUrl,
27039
- scenario,
27021
+ scenarios,
27040
27022
  runtimeCompat: runtimes,
27041
27023
  plugins,
27042
27024
  htmlSupervisor: true,
@@ -27551,7 +27533,10 @@ const executeTestPlan = async ({
27551
27533
  coverageMethodForNodeJs,
27552
27534
  coverageV8ConflictWarning,
27553
27535
  coverageTempDirectoryRelativeUrl,
27554
- scenario: "test",
27536
+ scenarios: {
27537
+ dev: true,
27538
+ test: true
27539
+ },
27555
27540
  sourcemaps,
27556
27541
  plugins,
27557
27542
  nodeEsmResolution,
@@ -29439,7 +29424,9 @@ const execute = async ({
29439
29424
  collectPerformance = false,
29440
29425
  runtime,
29441
29426
  runtimeParams,
29442
- scenario = "dev",
29427
+ scenarios = {
29428
+ dev: true
29429
+ },
29443
29430
  plugins = [],
29444
29431
  nodeEsmResolution,
29445
29432
  fileSystemMagicResolution,
@@ -29489,7 +29476,7 @@ const execute = async ({
29489
29476
  certificate,
29490
29477
  privateKey,
29491
29478
  rootDirectoryUrl,
29492
- scenario,
29479
+ scenarios,
29493
29480
  runtimeCompat: {
29494
29481
  [runtime.name]: runtime.version
29495
29482
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jsenv/core",
3
- "version": "27.7.0",
3
+ "version": "27.8.0",
4
4
  "description": "Tool to develop, test and build js projects",
5
5
  "license": "MIT",
6
6
  "author": {
@@ -175,7 +175,7 @@ build ${entryPointKeys.length} entry points`)
175
175
  logger,
176
176
  rootDirectoryUrl,
177
177
  urlGraph: rawGraph,
178
- scenario: "build",
178
+ scenarios: { build: true },
179
179
  sourcemaps,
180
180
  sourcemapsSourcesContent,
181
181
  runtimeCompat,
@@ -202,7 +202,6 @@ build ${entryPointKeys.length} entry points`)
202
202
  ...getCorePlugins({
203
203
  rootDirectoryUrl,
204
204
  urlGraph: rawGraph,
205
- scenario: "build",
206
205
  runtimeCompat,
207
206
 
208
207
  urlAnalysis,
@@ -423,7 +422,7 @@ build ${entryPointKeys.length} entry points`)
423
422
  logger,
424
423
  rootDirectoryUrl,
425
424
  urlGraph: finalGraph,
426
- scenario: "build",
425
+ scenarios: { build: true },
427
426
  sourcemaps,
428
427
  sourcemapsSourcesContent,
429
428
  sourcemapsRelativeSources: !versioning,
@@ -1063,7 +1062,7 @@ const applyUrlVersioning = async ({
1063
1062
  logger,
1064
1063
  rootDirectoryUrl: buildDirectoryUrl,
1065
1064
  urlGraph: finalGraph,
1066
- scenario: "build",
1065
+ scenarios: { build: true },
1067
1066
  sourcemaps,
1068
1067
  sourcemapsSourcesContent,
1069
1068
  sourcemapsRelativeSources: true,
@@ -1078,7 +1077,7 @@ const applyUrlVersioning = async ({
1078
1077
  }),
1079
1078
  {
1080
1079
  name: "jsenv:versioning",
1081
- appliesDuring: { build: true },
1080
+ appliesDuring: "build",
1082
1081
  resolveUrl: (reference) => {
1083
1082
  const buildUrl = buildUrls[reference.specifier]
1084
1083
  if (buildUrl) {
@@ -155,7 +155,7 @@ export const startDevServer = async ({
155
155
  services,
156
156
 
157
157
  rootDirectoryUrl,
158
- scenario: "dev",
158
+ scenarios: { dev: true },
159
159
  runtimeCompat,
160
160
 
161
161
  plugins,
@@ -24,7 +24,7 @@ export const execute = async ({
24
24
  runtime,
25
25
  runtimeParams,
26
26
 
27
- scenario = "dev",
27
+ scenarios = { dev: true },
28
28
  plugins = [],
29
29
  nodeEsmResolution,
30
30
  fileSystemMagicResolution,
@@ -75,7 +75,7 @@ export const execute = async ({
75
75
  privateKey,
76
76
 
77
77
  rootDirectoryUrl,
78
- scenario,
78
+ scenarios,
79
79
  runtimeCompat: { [runtime.name]: runtime.version },
80
80
 
81
81
  plugins,
@@ -28,18 +28,14 @@ export const createKitchen = ({
28
28
  logLevel,
29
29
 
30
30
  rootDirectoryUrl,
31
- scenario,
31
+ scenarios,
32
32
  runtimeCompat,
33
33
  // during dev/test clientRuntimeCompat is a single runtime
34
34
  // during build clientRuntimeCompat is runtimeCompat
35
35
  clientRuntimeCompat = runtimeCompat,
36
36
  urlGraph,
37
37
  plugins,
38
- sourcemaps = {
39
- dev: "inline", // "programmatic" and "file" also allowed
40
- test: "inline",
41
- build: "none",
42
- }[scenario],
38
+ sourcemaps = scenarios.dev ? "inline" : "none", // "programmatic" and "file" also allowed
43
39
  sourcemapsSourcesProtocol,
44
40
  sourcemapsSourcesContent,
45
41
  sourcemapsRelativeSources,
@@ -48,7 +44,7 @@ export const createKitchen = ({
48
44
  const logger = createLogger({ logLevel })
49
45
  const pluginController = createPluginController({
50
46
  plugins,
51
- scenario,
47
+ scenarios,
52
48
  })
53
49
  const jsenvDirectoryUrl = new URL(".jsenv/", rootDirectoryUrl).href
54
50
  const kitchenContext = {
@@ -56,7 +52,7 @@ export const createKitchen = ({
56
52
  logger,
57
53
  rootDirectoryUrl,
58
54
  urlGraph,
59
- scenario,
55
+ scenarios,
60
56
  runtimeCompat,
61
57
  clientRuntimeCompat,
62
58
  isSupportedOnCurrentClients: (feature) => {
@@ -769,12 +765,11 @@ const applyReferenceEffectsOnUrlInfo = (reference, urlInfo, context) => {
769
765
  column: reference.specifierColumn,
770
766
  }
771
767
  urlInfo.contentType = reference.contentType
772
- urlInfo.originalContent =
773
- context.scenario === "build"
774
- ? urlInfo.originalContent === undefined
775
- ? reference.content
776
- : urlInfo.originalContent
777
- : reference.content
768
+ urlInfo.originalContent = context.scenarios.build
769
+ ? urlInfo.originalContent === undefined
770
+ ? reference.content
771
+ : urlInfo.originalContent
772
+ : reference.content
778
773
  urlInfo.content = reference.content
779
774
  }
780
775
  }
@@ -25,7 +25,7 @@ export const startOmegaServer = async ({
25
25
  services = [],
26
26
 
27
27
  rootDirectoryUrl,
28
- scenario,
28
+ scenarios,
29
29
  runtimeCompat,
30
30
 
31
31
  plugins,
@@ -87,7 +87,7 @@ export const startOmegaServer = async ({
87
87
  serverEventsDispatcher,
88
88
 
89
89
  rootDirectoryUrl,
90
- scenario,
90
+ scenarios,
91
91
  runtimeCompat,
92
92
 
93
93
  plugins,
@@ -20,7 +20,7 @@ export const createFileService = ({
20
20
  serverEventsDispatcher,
21
21
 
22
22
  rootDirectoryUrl,
23
- scenario,
23
+ scenarios,
24
24
  runtimeCompat,
25
25
 
26
26
  plugins,
@@ -53,7 +53,7 @@ export const createFileService = ({
53
53
  ".jsenv/": false,
54
54
  }
55
55
 
56
- if (scenario === "dev") {
56
+ if (scenarios.dev) {
57
57
  const stopWatchingClientFiles = registerDirectoryLifecycle(
58
58
  rootDirectoryUrl,
59
59
  {
@@ -99,13 +99,13 @@ export const createFileService = ({
99
99
  })
100
100
  urlInfo.isValid = () => watch
101
101
  },
102
- includeOriginalUrls: scenario === "dev",
102
+ includeOriginalUrls: scenarios.dev,
103
103
  })
104
104
  const kitchen = createKitchen({
105
105
  signal,
106
106
  logLevel,
107
107
  rootDirectoryUrl,
108
- scenario,
108
+ scenarios,
109
109
  runtimeCompat,
110
110
  clientRuntimeCompat: {
111
111
  [runtimeName]: runtimeVersion,
@@ -115,7 +115,6 @@ export const createFileService = ({
115
115
  ...plugins,
116
116
  ...getCorePlugins({
117
117
  rootDirectoryUrl,
118
- scenario,
119
118
  runtimeCompat,
120
119
 
121
120
  urlAnalysis,
@@ -156,7 +155,7 @@ export const createFileService = ({
156
155
  allServerEvents[serverEventName]({
157
156
  rootDirectoryUrl,
158
157
  urlGraph,
159
- scenario,
158
+ scenarios,
160
159
  sendServerEvent: (data) => {
161
160
  serverEventsDispatcher.dispatch({
162
161
  type: serverEventName,
@@ -174,7 +173,7 @@ export const createFileService = ({
174
173
 
175
174
  const context = {
176
175
  rootDirectoryUrl,
177
- scenario,
176
+ scenarios,
178
177
  runtimeName,
179
178
  runtimeVersion,
180
179
  urlGraph,
@@ -260,10 +259,11 @@ export const createFileService = ({
260
259
  await kitchen.cook(urlInfo, {
261
260
  request,
262
261
  reference,
263
- outDirectoryUrl:
264
- scenario === "dev"
265
- ? `${rootDirectoryUrl}.jsenv/${runtimeName}@${runtimeVersion}/`
266
- : `${rootDirectoryUrl}.jsenv/${scenario}/${runtimeName}@${runtimeVersion}/`,
262
+ outDirectoryUrl: scenarios.dev
263
+ ? `${rootDirectoryUrl}.jsenv/${runtimeName}@${runtimeVersion}/`
264
+ : `${rootDirectoryUrl}.jsenv/${
265
+ scenarios.test ? "test" : "build"
266
+ }/${runtimeName}@${runtimeVersion}/`,
267
267
  })
268
268
  let { response } = urlInfo
269
269
  if (response) {
@@ -3,13 +3,9 @@ import { jsenvPluginAutoreloadClient } from "./jsenv_plugin_autoreload_client.js
3
3
  import { jsenvPluginAutoreloadServer } from "./jsenv_plugin_autoreload_server.js"
4
4
 
5
5
  export const jsenvPluginAutoreload = ({
6
- scenario,
7
6
  clientFileChangeCallbackList,
8
7
  clientFilesPruneCallbackList,
9
8
  }) => {
10
- if (scenario === "build") {
11
- return []
12
- }
13
9
  return [
14
10
  jsenvPluginHmr(),
15
11
  jsenvPluginAutoreloadClient(),
@@ -13,7 +13,7 @@ export const jsenvPluginAutoreloadClient = () => {
13
13
 
14
14
  return {
15
15
  name: "jsenv:autoreload_client",
16
- appliesDuring: { dev: true },
16
+ appliesDuring: { dev: true, test: false },
17
17
  transformUrlContent: {
18
18
  html: (htmlUrlInfo, context) => {
19
19
  const htmlAst = parseHtmlString(htmlUrlInfo.content)
@@ -6,7 +6,7 @@ export const jsenvPluginAutoreloadServer = ({
6
6
  }) => {
7
7
  return {
8
8
  name: "jsenv:autoreload_server",
9
- appliesDuring: { dev: true },
9
+ appliesDuring: { dev: true, test: false },
10
10
  serverEvents: {
11
11
  reload: ({ sendServerEvent, rootDirectoryUrl, urlGraph }) => {
12
12
  const formatUrlForClient = (url) => {
@@ -1,7 +1,7 @@
1
1
  export const jsenvPluginHmr = () => {
2
2
  return {
3
3
  name: "jsenv:hmr",
4
- appliesDuring: { dev: true },
4
+ appliesDuring: { dev: true, test: false },
5
5
  redirectUrl: (reference) => {
6
6
  const urlObject = new URL(reference.url)
7
7
  if (!urlObject.searchParams.has("hmr")) {
@@ -18,9 +18,7 @@ export const jsenvPluginBundling = (bundling) => {
18
18
 
19
19
  return {
20
20
  name: "jsenv:bundling",
21
- appliesDuring: {
22
- build: true,
23
- },
21
+ appliesDuring: "build",
24
22
  bundle: {
25
23
  css: bundling.css
26
24
  ? (cssUrlInfos, context) => {
@@ -1,12 +1,9 @@
1
1
  export const jsenvPluginCacheControl = () => {
2
2
  return {
3
3
  name: "jsenv:cache_control",
4
- appliesDuring: {
5
- dev: true,
6
- test: true,
7
- },
4
+ appliesDuring: "dev",
8
5
  augmentResponse: ({ reference }, context) => {
9
- if (context.scenario === "test") {
6
+ if (context.scenarios.test) {
10
7
  // During dev, all files are put into browser cache for 1 hour because:
11
8
  // 1: Browser cache is a temporary directory created by playwright
12
9
  // 2: We assume source files won't be modified while tests are running
@@ -11,7 +11,7 @@ import { createMagicSource } from "@jsenv/sourcemap"
11
11
  import { applyBabelPlugins } from "@jsenv/ast"
12
12
 
13
13
  export const jsenvPluginCommonJsGlobals = () => {
14
- const transformCommonJsGlobals = async (urlInfo, { scenario }) => {
14
+ const transformCommonJsGlobals = async (urlInfo, context) => {
15
15
  if (
16
16
  !urlInfo.content.includes("process.env.NODE_ENV") &&
17
17
  !urlInfo.content.includes("__filename") &&
@@ -22,7 +22,7 @@ export const jsenvPluginCommonJsGlobals = () => {
22
22
  const isJsModule = urlInfo.type === "js_module"
23
23
  const replaceMap = {
24
24
  "process.env.NODE_ENV": `("${
25
- scenario === "dev" || scenario === "test" ? "development" : "production"
25
+ context.scenarios.dev ? "development" : "production"
26
26
  }")`,
27
27
  "global": "globalThis",
28
28
  "__filename": isJsModule
@@ -113,14 +113,10 @@ export const jsenvPluginFileUrls = ({
113
113
  },
114
114
  {
115
115
  name: "jsenv:@fs_resolution",
116
- appliesDuring: {
117
- // during dev and test it's a browser running the code
118
- // so absolute file urls needs to be relativized
119
- dev: true,
120
- test: true,
121
- // during build it's fine to use file:// urls
122
- build: false,
123
- },
116
+ // during dev and test it's a browser running the code
117
+ // so absolute file urls needs to be relativized
118
+ // during build it's fine to use file:// urls
119
+ appliesDuring: "dev",
124
120
  resolveUrl: (reference) => {
125
121
  if (reference.specifier.startsWith("/@fs/")) {
126
122
  const fsRootRelativeUrl = reference.specifier.slice("/@fs/".length)
@@ -43,10 +43,7 @@ export const jsenvPluginHtmlSupervisor = ({
43
43
 
44
44
  return {
45
45
  name: "jsenv:html_supervisor",
46
- appliesDuring: {
47
- dev: true,
48
- test: true,
49
- },
46
+ appliesDuring: "dev",
50
47
  serve: async (request, context) => {
51
48
  if (request.ressource.startsWith("/__get_code_frame__/")) {
52
49
  const { pathname, searchParams } = new URL(request.url)
@@ -16,7 +16,7 @@ export const jsenvPluginImportMetaHot = () => {
16
16
  transformUrlContent: {
17
17
  html: (htmlUrlInfo, context) => {
18
18
  // during build we don't really care to parse html hot dependencies
19
- if (context.scenario === "build") {
19
+ if (context.scenarios.build) {
20
20
  return
21
21
  }
22
22
  const htmlAst = parseHtmlString(htmlUrlInfo.content)
@@ -58,7 +58,7 @@ export const jsenvPluginImportMetaHot = () => {
58
58
  if (importMetaHotPaths.length === 0) {
59
59
  return null
60
60
  }
61
- if (context.scenario === "build") {
61
+ if (context.scenarios.build) {
62
62
  return removeImportMetaHots(urlInfo, importMetaHotPaths)
63
63
  }
64
64
  return injectImportMetaHot(urlInfo, context, importMetaHotClientFileUrl)
@@ -1,11 +1,10 @@
1
1
  /*
2
2
  * Source code can contain the following
3
3
  * - import.meta.dev
4
- * - import.meta.test
5
4
  * - import.meta.build
6
5
  * They are either:
7
6
  * - replaced by true: When scenario matches (import.meta.dev and it's the dev server)
8
- * - left as is to be evaluated to undefined (import.meta.test but it's the dev server)
7
+ * - left as is to be evaluated to undefined (import.meta.build but it's the dev server)
9
8
  * - replaced by undefined (import.meta.dev but it's build; the goal is to ensure it's tree-shaked)
10
9
  */
11
10
 
@@ -17,7 +16,7 @@ export const jsenvPluginImportMetaScenarios = () => {
17
16
  name: "jsenv:import_meta_scenario",
18
17
  appliesDuring: "*",
19
18
  transformUrlContent: {
20
- js_module: async (urlInfo, { scenario }) => {
19
+ js_module: async (urlInfo, context) => {
21
20
  if (
22
21
  !urlInfo.content.includes("import.meta.dev") &&
23
22
  !urlInfo.content.includes("import.meta.test") &&
@@ -34,34 +33,30 @@ export const jsenvPluginImportMetaScenarios = () => {
34
33
  const replace = (path, value) => {
35
34
  replacements.push({ path, value })
36
35
  }
37
- if (scenario === "dev") {
38
- dev.forEach((path) => {
39
- replace(path, "true")
40
- })
41
- } else if (scenario === "test") {
42
- // test is also considered a dev environment
43
- // just like the dev server can be used to debug test files
44
- // without this people would have to write
45
- // if (import.meta.dev || import.meta.test) or if (!import.meta.build)
46
- dev.forEach((path) => {
47
- replace(path, "true")
48
- })
49
- test.forEach((path) => {
50
- replace(path, "true")
51
- })
52
- } else if (scenario === "build") {
53
- // replacing by undefined might not be required
54
- // as I suppose rollup would consider them as undefined
55
- // but let's make it explicit to ensure code is properly tree-shaked
36
+ if (context.scenarios.build) {
37
+ // during build ensure replacement for tree-shaking
56
38
  dev.forEach((path) => {
57
39
  replace(path, "undefined")
58
40
  })
59
41
  test.forEach((path) => {
60
- replace(path, "undefined")
42
+ replace(path, context.scenarios.test ? "true" : "undefined")
61
43
  })
62
44
  build.forEach((path) => {
63
45
  replace(path, "true")
64
46
  })
47
+ } else {
48
+ // during dev we can let "import.meta.build" untouched
49
+ // it will be evaluated to undefined.
50
+ // Moreover it can be surprising to see some "undefined"
51
+ // when source file contains "import.meta.build"
52
+ dev.forEach((path) => {
53
+ replace(path, "true")
54
+ })
55
+ if (context.scenarios.test) {
56
+ test.forEach((path) => {
57
+ replace(path, "true")
58
+ })
59
+ }
65
60
  }
66
61
  const magicSource = createMagicSource(urlInfo.content)
67
62
  replacements.forEach(({ path, value }) => {
@@ -106,7 +101,6 @@ const babelPluginMetadataImportMetaScenarios = () => {
106
101
  })
107
102
  state.file.metadata.importMetaScenarios = {
108
103
  dev: importMetas.dev,
109
- test: importMetas.test,
110
104
  build: importMetas.build,
111
105
  }
112
106
  },
@@ -202,7 +202,7 @@ export const jsenvPluginImportmap = () => {
202
202
  // by "formatReferencedUrl" making the importmap presence useless.
203
203
  // In dev/test we keep importmap into the HTML to see it even if useless
204
204
  // Duing build we get rid of it
205
- if (context.scenario === "build") {
205
+ if (context.scenarios.build) {
206
206
  removeHtmlNode(importmap)
207
207
  }
208
208
  return {
@@ -40,9 +40,7 @@ export const jsenvPluginMinification = (minification) => {
40
40
 
41
41
  return {
42
42
  name: "jsenv:minification",
43
- appliesDuring: {
44
- build: true,
45
- },
43
+ appliesDuring: "build",
46
44
  optimizeUrlContent: {
47
45
  html: htmlOptimizer,
48
46
  svg: htmlOptimizer,
@@ -27,8 +27,10 @@ export const jsenvPluginNodeEsmResolution = ({
27
27
  return {
28
28
  name: "jsenv:node_esm_resolution",
29
29
  appliesDuring: "*",
30
- init: ({ rootDirectoryUrl, scenario, runtimeCompat, urlGraph }) => {
31
- const nodeRuntimeEnabled = Object.keys(runtimeCompat).includes("node")
30
+ init: (context) => {
31
+ const nodeRuntimeEnabled = Object.keys(context.runtimeCompat).includes(
32
+ "node",
33
+ )
32
34
  // https://nodejs.org/api/esm.html#resolver-algorithm-specification
33
35
  packageConditions = packageConditions || [
34
36
  ...readCustomConditionsFromProcessArgs(),
@@ -57,19 +59,19 @@ export const jsenvPluginNodeEsmResolution = ({
57
59
  return packageJson
58
60
  }
59
61
 
60
- if (scenario === "dev") {
62
+ if (context.scenarios.dev) {
61
63
  const onFileChange = () => {
62
64
  packageScopesCache.clear()
63
65
  packageJsonsCache.clear()
64
- urlGraph.urlInfoMap.forEach((urlInfo) => {
66
+ context.urlGraph.urlInfoMap.forEach((urlInfo) => {
65
67
  if (urlInfo.dependsOnPackageJson) {
66
- urlGraph.considerModified(urlInfo)
68
+ context.urlGraph.considerModified(urlInfo)
67
69
  }
68
70
  })
69
71
  }
70
72
  filesInvalidatingCache.forEach((file) => {
71
73
  const unregister = registerFileLifecycle(
72
- new URL(file, rootDirectoryUrl),
74
+ new URL(file, context.rootDirectoryUrl),
73
75
  {
74
76
  added: () => {
75
77
  onFileChange()
@@ -131,7 +133,7 @@ export const jsenvPluginNodeEsmResolution = ({
131
133
  return null
132
134
  },
133
135
  transformUrlSearchParams: (reference, context) => {
134
- if (context.scenario === "build") {
136
+ if (context.scenarios.build) {
135
137
  return null
136
138
  }
137
139
  if (!reference.url.startsWith("file:")) {
@@ -17,8 +17,8 @@ const HOOK_NAMES = [
17
17
  "destroy",
18
18
  ]
19
19
 
20
- export const createPluginController = ({ plugins, scenario }) => {
21
- const flatPlugins = flattenAndFilterPlugins(plugins, { scenario })
20
+ export const createPluginController = ({ plugins, scenarios }) => {
21
+ const flatPlugins = flattenAndFilterPlugins(plugins, { scenarios })
22
22
  // precompute a list of hooks per hookName for one major reason:
23
23
  // - When debugging, there is less iteration
24
24
  // also it should increase perf as there is less work to do
@@ -187,7 +187,7 @@ export const createPluginController = ({ plugins, scenario }) => {
187
187
  }
188
188
  }
189
189
 
190
- const flattenAndFilterPlugins = (plugins, { scenario }) => {
190
+ const flattenAndFilterPlugins = (plugins, { scenarios }) => {
191
191
  const flatPlugins = []
192
192
  const visitPluginEntry = (pluginEntry) => {
193
193
  if (Array.isArray(pluginEntry)) {
@@ -208,13 +208,14 @@ const flattenAndFilterPlugins = (plugins, { scenario }) => {
208
208
  return
209
209
  }
210
210
  if (typeof appliesDuring === "string") {
211
- if (!["dev", "build", "test"].includes(appliesDuring)) {
211
+ if (!["dev", "test", "build"].includes(appliesDuring)) {
212
212
  throw new Error(
213
213
  `"appliesDuring" must be "dev", "test" or "build", got ${appliesDuring}`,
214
214
  )
215
215
  }
216
- if (appliesDuring === scenario) {
216
+ if (scenarios[appliesDuring]) {
217
217
  flatPlugins.push(pluginEntry)
218
+ return
218
219
  }
219
220
  return
220
221
  }
@@ -223,7 +224,17 @@ const flattenAndFilterPlugins = (plugins, { scenario }) => {
223
224
  `"appliesDuring" must be an object or a string, got ${appliesDuring}`,
224
225
  )
225
226
  }
226
- if (appliesDuring[scenario]) {
227
+ let applies
228
+ for (const key of Object.keys(appliesDuring)) {
229
+ if (!appliesDuring[key] && scenarios[key]) {
230
+ applies = false
231
+ break
232
+ }
233
+ if (appliesDuring[key] && scenarios[key]) {
234
+ applies = true
235
+ }
236
+ }
237
+ if (applies) {
227
238
  flatPlugins.push(pluginEntry)
228
239
  return
229
240
  }
@@ -24,7 +24,6 @@ import { jsenvPluginExplorer } from "./explorer/jsenv_plugin_explorer.js"
24
24
 
25
25
  export const getCorePlugins = ({
26
26
  rootDirectoryUrl,
27
- scenario,
28
27
  runtimeCompat,
29
28
 
30
29
  urlAnalysis = {},
@@ -84,7 +83,6 @@ export const getCorePlugins = ({
84
83
  ? [
85
84
  jsenvPluginAutoreload({
86
85
  ...clientAutoreload,
87
- scenario,
88
86
  clientFileChangeCallbackList,
89
87
  clientFilesPruneCallbackList,
90
88
  }),
@@ -17,9 +17,7 @@ export const jsenvPluginToolbar = ({ logs = false } = {}) => {
17
17
 
18
18
  return {
19
19
  name: "jsenv:toolbar",
20
- appliesDuring: {
21
- dev: true,
22
- },
20
+ appliesDuring: { dev: true, test: false },
23
21
  transformUrlContent: {
24
22
  html: ({ url, content }, { referenceUtils }) => {
25
23
  if (url === toolbarHtmlClientFileUrl) {
@@ -43,7 +43,7 @@ export const jsenvPluginImportAssertions = ({
43
43
  // We would have to tell rollup to ignore import with assertion
44
44
  // - means rollup can bundle more js file together
45
45
  // - means url versioning can work for css inlined in js
46
- if (context.scenario === "build") {
46
+ if (context.scenarios.build) {
47
47
  json = true
48
48
  css = true
49
49
  text = true
@@ -13,9 +13,9 @@ import {
13
13
  export const parseAndTransformHtmlUrls = async (urlInfo, context) => {
14
14
  const url = urlInfo.originalUrl
15
15
  const content = urlInfo.content
16
- const { scenario, referenceUtils } = context
16
+ const { scenarios, referenceUtils } = context
17
17
  const htmlAst = parseHtmlString(content, {
18
- storeOriginalPositions: scenario !== "build",
18
+ storeOriginalPositions: scenarios.dev,
19
19
  })
20
20
  const actions = []
21
21
  visitHtmlUrls({
@@ -55,7 +55,7 @@ export const executePlan = async (
55
55
  coverageV8ConflictWarning,
56
56
  coverageTempDirectoryRelativeUrl,
57
57
 
58
- scenario,
58
+ scenarios,
59
59
  sourcemaps,
60
60
  plugins,
61
61
  nodeEsmResolution,
@@ -208,7 +208,7 @@ export const executePlan = async (
208
208
  services,
209
209
 
210
210
  rootDirectoryUrl,
211
- scenario,
211
+ scenarios,
212
212
  runtimeCompat: runtimes,
213
213
 
214
214
  plugins,
@@ -166,7 +166,7 @@ export const executeTestPlan = async ({
166
166
  coverageV8ConflictWarning,
167
167
  coverageTempDirectoryRelativeUrl,
168
168
 
169
- scenario: "test",
169
+ scenarios: { dev: true, test: true },
170
170
  sourcemaps,
171
171
  plugins,
172
172
  nodeEsmResolution,