@jsenv/core 41.4.27 → 41.4.29

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,7 +1,7 @@
1
1
  import { WebSocketResponse, pickContentType, ServerEvents, serverPluginErrorHandler, fetchDirectory, composeTwoResponses, serverPluginCORS, jsenvAccessControlAllowedHeaders, startServer } from "@jsenv/server";
2
2
  import { existsSync, readFileSync, realpathSync, readdirSync, lstatSync, statSync } from "node:fs";
3
3
  import { pathToFileURL } from "node:url";
4
- import { urlToRelativeUrl, registerFileLifecycle, lookupPackageDirectory, readPackageAtOrNull, generateContentFrame, errorToHTML, DATA_URL, CONTENT_TYPE, normalizeImportMap, composeTwoImportMaps, resolveImport, JS_QUOTES, urlToExtension, urlToBasename, applyNodeEsmResolution, URL_META, readCustomConditionsFromProcessArgs, urlIsOrIsInsideOf, collectFiles, registerDirectoryLifecycle, readEntryStatSync, applyFileSystemMagicResolution, getExtensionsToTry, urlToFilename, asUrlWithoutSearch, ensurePathnameTrailingSlash, compareFileUrls, setUrlExtension, createDetailedMessage, stringifyUrlSite, injectQueryParamsIntoSpecifier, isSpecifierForNodeBuiltin, injectQueryParams, urlToFileSystemPath, writeFileSync, moveUrl, ensureWindowsDriveLetter, validateResponseIntegrity, setUrlFilename, getCallerPosition, asSpecifierWithoutSearch, bufferToEtag, isFileSystemPath, urlToPathname, setUrlBasename, createLogger, normalizeUrl, ANSI, RUNTIME_COMPAT, formatError, assertAndNormalizeDirectoryUrl, createTaskLog } from "./jsenv_core_packages.js";
4
+ import { urlToRelativeUrl, registerFileLifecycle, lookupPackageDirectory, readPackageAtOrNull, generateContentFrame, errorToHTML, DATA_URL, CONTENT_TYPE, normalizeImportMap, composeTwoImportMaps, resolveImport, JS_QUOTES, urlToExtension, urlToBasename, applyNodeEsmResolution, URL_META, readCustomConditionsFromProcessArgs, urlIsOrIsInsideOf, collectFiles, registerDirectoryLifecycle, readEntryStatSync, applyFileSystemMagicResolution, getExtensionsToTry, urlToFilename, asUrlWithoutSearch, ensurePathnameTrailingSlash, compareFileUrls, setUrlExtension, createDetailedMessage, stringifyUrlSite, injectQueryParamsIntoSpecifier, isSpecifierForNodeBuiltin, injectQueryParams, urlToFileSystemPath, writeFileSync, moveUrl, ensureWindowsDriveLetter, validateResponseIntegrity, setUrlFilename, getCallerPosition, asSpecifierWithoutSearch, bufferToEtag, isFileSystemPath, urlToPathname, setUrlBasename, createLogger, normalizeUrl, ANSI, RUNTIME_COMPAT, formatError, assertAndNormalizeDirectoryUrl, browserDefaultRuntimeCompat, inferRuntimeCompatFromClosestPackage, createTaskLog } from "./jsenv_core_packages.js";
5
5
  import { createPluginsController } from "@jsenv/server/src/plugins_controller.js";
6
6
  import { parseHtml, injectJsenvScript, stringifyHtmlAst, parseCssUrls, getHtmlNodeAttribute, getHtmlNodePosition, getHtmlNodeAttributePosition, setHtmlNodeAttributes, parseSrcSet, getUrlForContentInsideHtml, removeHtmlNodeText, setHtmlNodeText, getHtmlNodeText, analyzeScriptNode, visitHtmlNodes, parseJsUrls, getUrlForContentInsideJs, renderCssTemplateLiteral, applyBabelPlugins, visitJsAst, getImportMetaPropertyName, visitJsAstUntil, analyzeLinkNode, injectHtmlNodeAsEarlyAsPossible, createHtmlNode, generateUrlForInlineContent, parseJsWithAcorn } from "@jsenv/ast";
7
7
  import { jsenvPluginSupervisor } from "@jsenv/plugin-supervisor";
@@ -17,20 +17,6 @@ import "node:tty";
17
17
  import "node:util";
18
18
  import "node:path";
19
19
 
20
- // default runtimeCompat corresponds to
21
- // "we can keep <script type="module"> intact":
22
- // so script_type_module + dynamic_import + import_meta
23
- const defaultRuntimeCompat = {
24
- // android: "8",
25
- chrome: "64",
26
- edge: "79",
27
- firefox: "67",
28
- ios: "12",
29
- opera: "51",
30
- safari: "11.3",
31
- samsung: "9.2",
32
- };
33
-
34
20
  const createEventEmitter = () => {
35
21
  const callbackSet = new Set();
36
22
  const on = (callback) => {
@@ -12121,10 +12107,11 @@ const startDevServer = async ({
12121
12107
  // a test wants them all, hence 0 there.
12122
12108
  serverTiming = { minDuration: EXECUTED_BY_TEST_PLAN ? 0 : 0.5 },
12123
12109
 
12124
- // runtimeCompat is the runtimeCompat for the build
12125
- // when specified, dev server use it to warn in case
12126
- // code would be supported during dev but not after build
12127
- runtimeCompat = defaultRuntimeCompat,
12110
+ // The runtimeCompat the build will use: the dev server warns when code works
12111
+ // in dev but would not survive that build, and transpiles what those runtimes
12112
+ // lack. Left out, it is inferred exactly as build() infers it, so the two
12113
+ // never disagree on what they target.
12114
+ runtimeCompat,
12128
12115
  plugins = [],
12129
12116
  referenceAnalysis = {},
12130
12117
  nodeEsmResolution,
@@ -12195,6 +12182,12 @@ const startDevServer = async ({
12195
12182
  }
12196
12183
  // params normalization
12197
12184
  {
12185
+ if (runtimeCompat === undefined) {
12186
+ runtimeCompat =
12187
+ (await inferRuntimeCompatFromClosestPackage(sourceDirectoryUrl, {
12188
+ runtimeType: "browser",
12189
+ })) || browserDefaultRuntimeCompat;
12190
+ }
12198
12191
  if (clientAutoreload === true) {
12199
12192
  clientAutoreload = {};
12200
12193
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jsenv/core",
3
- "version": "41.4.27",
3
+ "version": "41.4.29",
4
4
  "type": "module",
5
5
  "description": "Tool to develop, test and build js projects",
6
6
  "repository": {
@@ -75,10 +75,10 @@
75
75
  "dependencies": {
76
76
  "@jsenv/ast": "6.9.3",
77
77
  "@jsenv/js-module-fallback": "1.5.2",
78
- "@jsenv/plugin-bundling": "2.10.18",
78
+ "@jsenv/plugin-bundling": "2.10.19",
79
79
  "@jsenv/plugin-minification": "1.7.11",
80
80
  "@jsenv/plugin-supervisor": "1.8.14",
81
- "@jsenv/plugin-transpilation": "1.6.3",
81
+ "@jsenv/plugin-transpilation": "1.6.4",
82
82
  "@jsenv/server": "17.6.3",
83
83
  "@jsenv/sourcemap": "1.4.2",
84
84
  "react-table": "7.8.0"
@@ -70,7 +70,7 @@ import { isBareSpecifier } from "../helpers/bare_specifier.js";
70
70
  import { getCorePlugins } from "../plugins/plugins.js";
71
71
  import { jsenvPluginReferenceAnalysis } from "../plugins/reference_analysis/jsenv_plugin_reference_analysis.js";
72
72
  import { renderBuildDoneLog } from "./build_content_report.js";
73
- import { defaultRuntimeCompat, logsDefault } from "./build_params.js";
73
+ import { logsDefault } from "./build_params.js";
74
74
  import { createBuildSpecifierManager } from "./build_specifier_manager.js";
75
75
  import { createBuildUrlsGenerator } from "./build_urls_generator.js";
76
76
  import { jsenvPluginLineBreakNormalization } from "./jsenv_plugin_line_break_normalization.js";
@@ -679,12 +679,10 @@ entryPoints: {
679
679
  for (const entryPoint of entryPointArray) {
680
680
  let { runtimeCompat } = entryPoint.params;
681
681
  if (runtimeCompat === undefined) {
682
- const runtimeCompatFromPackage = inferRuntimeCompatFromClosestPackage(
683
- entryPoint.sourceUrl,
684
- {
682
+ const runtimeCompatFromPackage =
683
+ await inferRuntimeCompatFromClosestPackage(entryPoint.sourceUrl, {
685
684
  runtimeType: entryPoint.runtimeType,
686
- },
687
- );
685
+ });
688
686
  if (runtimeCompatFromPackage) {
689
687
  entryPoint.params.runtimeCompat = runtimeCompat =
690
688
  runtimeCompatFromPackage;
@@ -981,7 +979,7 @@ entryPoints: {
981
979
  const entryPointDefaultParams = {
982
980
  buildRelativeUrl: undefined,
983
981
  mode: undefined,
984
- runtimeCompat: defaultRuntimeCompat,
982
+ runtimeCompat: undefined,
985
983
  plugins: [],
986
984
  mappings: undefined,
987
985
  assetsDirectory: undefined,
@@ -1,16 +1,3 @@
1
- // default runtimeCompat corresponds to
2
- // "we can keep <script type="module"> intact":
3
- // so script_type_module + dynamic_import + import_meta
4
- export const defaultRuntimeCompat = {
5
- // android: "8",
6
- chrome: "64",
7
- edge: "79",
8
- firefox: "67",
9
- ios: "12",
10
- opera: "51",
11
- safari: "11.3",
12
- samsung: "9.2",
13
- };
14
1
  export const logsDefault = {
15
2
  level: "info",
16
3
  animated: true,
@@ -154,6 +154,25 @@ const splitFileExtension = (filename) => {
154
154
  return [filename.slice(0, dotLastIndex), filename.slice(dotLastIndex)];
155
155
  };
156
156
 
157
+ const resolveImportIdPath = (ownerUrlInfo, dynamicImportId) => {
158
+ const ancestorImportIds = [];
159
+ let ancestorUrlInfo = ownerUrlInfo;
160
+ let currentImportId = dynamicImportId;
161
+ while (ancestorUrlInfo) {
162
+ const ancestorDynamicImportId =
163
+ ancestorUrlInfo.searchParams.get("dynamic_import_id");
164
+ if (!ancestorDynamicImportId) {
165
+ break;
166
+ }
167
+ if (ancestorDynamicImportId !== currentImportId) {
168
+ ancestorImportIds.push(ancestorDynamicImportId);
169
+ currentImportId = ancestorDynamicImportId;
170
+ }
171
+ ancestorUrlInfo = ancestorUrlInfo.firstReference?.ownerUrlInfo;
172
+ }
173
+ return [...ancestorImportIds, dynamicImportId].join("/");
174
+ };
175
+
157
176
  const determineDirectoryPath = ({
158
177
  sourceDirectoryUrl,
159
178
  assetsDirectory,
@@ -176,23 +195,24 @@ const determineDirectoryPath = ({
176
195
  }
177
196
  const dynamicImportId = urlInfo.searchParams.get("dynamic_import_id");
178
197
  if (dynamicImportId) {
179
- const ancestorImportIds = [];
180
- let ancestorUrlInfo = ownerUrlInfo;
181
- let currentImportId = dynamicImportId;
182
- while (ancestorUrlInfo) {
183
- const ancestorDynamicImportId =
184
- ancestorUrlInfo.searchParams.get("dynamic_import_id");
185
- if (!ancestorDynamicImportId) {
186
- break;
187
- }
188
- if (ancestorDynamicImportId !== currentImportId) {
189
- ancestorImportIds.push(ancestorDynamicImportId);
190
- currentImportId = ancestorDynamicImportId;
191
- }
192
- ancestorUrlInfo = ancestorUrlInfo.firstReference?.ownerUrlInfo;
198
+ // Inside the isolated group that asked for it — but only while ONE did.
199
+ // A chunk several groups reach belongs to none of them: put inside the
200
+ // first asker it would move the day another one asks first, and the others
201
+ // would import it out of a sibling's directory.
202
+ const importIdPathSet = new Set();
203
+ for (const referenceFromOther of urlInfo.referenceFromOthersSet) {
204
+ importIdPathSet.add(
205
+ resolveImportIdPath(referenceFromOther.ownerUrlInfo, dynamicImportId),
206
+ );
207
+ }
208
+ if (importIdPathSet.size === 0) {
209
+ importIdPathSet.add(resolveImportIdPath(ownerUrlInfo, dynamicImportId));
210
+ }
211
+ if (importIdPathSet.size === 1) {
212
+ const [importIdPath] = importIdPathSet;
213
+ return `${assetsDirectory}${importIdPath}/`;
193
214
  }
194
- const importIdPath = [...ancestorImportIds, dynamicImportId].join("/");
195
- return `${assetsDirectory}${importIdPath}/`;
215
+ return `${assetsDirectory}${dynamicImportId}/`;
196
216
  }
197
217
  if (urlInfo.isEntryPoint && !urlInfo.isDynamicEntryPoint) {
198
218
  return "";
@@ -13,10 +13,13 @@ import {
13
13
  urlToFileSystemPath,
14
14
  urlToRelativeUrl,
15
15
  } from "@jsenv/urls";
16
+ import {
17
+ browserDefaultRuntimeCompat,
18
+ inferRuntimeCompatFromClosestPackage,
19
+ } from "@jsenv/runtime-compat";
16
20
  import { existsSync } from "node:fs";
17
21
  import { pathToFileURL } from "node:url";
18
22
 
19
- import { defaultRuntimeCompat } from "../build/build_params.js";
20
23
  import { createEventEmitter } from "../helpers/event_emitter.js";
21
24
  import { watchDependencies } from "../helpers/watch_dependencies.js";
22
25
  import { jsenvCoreDirectoryUrl } from "../jsenv_core_directory_url.js";
@@ -104,10 +107,11 @@ export const startDevServer = async ({
104
107
  // a test wants them all, hence 0 there.
105
108
  serverTiming = { minDuration: EXECUTED_BY_TEST_PLAN ? 0 : 0.5 },
106
109
 
107
- // runtimeCompat is the runtimeCompat for the build
108
- // when specified, dev server use it to warn in case
109
- // code would be supported during dev but not after build
110
- runtimeCompat = defaultRuntimeCompat,
110
+ // The runtimeCompat the build will use: the dev server warns when code works
111
+ // in dev but would not survive that build, and transpiles what those runtimes
112
+ // lack. Left out, it is inferred exactly as build() infers it, so the two
113
+ // never disagree on what they target.
114
+ runtimeCompat,
111
115
  plugins = [],
112
116
  referenceAnalysis = {},
113
117
  nodeEsmResolution,
@@ -179,6 +183,12 @@ export const startDevServer = async ({
179
183
  }
180
184
  // params normalization
181
185
  {
186
+ if (runtimeCompat === undefined) {
187
+ runtimeCompat =
188
+ (await inferRuntimeCompatFromClosestPackage(sourceDirectoryUrl, {
189
+ runtimeType: "browser",
190
+ })) || browserDefaultRuntimeCompat;
191
+ }
182
192
  if (clientAutoreload === true) {
183
193
  clientAutoreload = {};
184
194
  }