@jsenv/core 41.4.21 → 41.4.23

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.
@@ -11361,6 +11361,11 @@ const inferUrlInfoType = (urlInfo) => {
11361
11361
  return expectedType || "other";
11362
11362
  };
11363
11363
 
11364
+ // What the newest browser supports, and nothing less: the source untouched.
11365
+ // A version no browser has, so that every feature known to runtime-compat
11366
+ // counts as supported.
11367
+ const UNKNOWN_CLIENT_RUNTIME_COMPAT = { chrome: "9999.0.0" };
11368
+
11364
11369
  const devServerPluginServeSourceFiles = ({
11365
11370
  packageDirectory,
11366
11371
  sourceDirectoryUrl,
@@ -11421,14 +11426,16 @@ const devServerPluginServeSourceFiles = ({
11421
11426
  }
11422
11427
  });
11423
11428
  // A client we cannot identify (curl, fetch, a healthcheck, a proxy dropping
11424
- // the user agent) is assumed to be one of the runtimes the project targets.
11425
- // Treating it as a runtime supporting nothing would serve it the js module
11426
- // fallback, breaking tooling perfectly capable of ES modules; an actual
11427
- // ancient browser hiding its identity fails loudly instead, which is the
11428
- // cheaper of the two mistakes.
11429
+ // the user agent, the WebKit inspector re-requesting a page's resources
11430
+ // under its own agent) is served the source as it is written. Taking the
11431
+ // build targets instead would hand it the js module fallback and a heavy
11432
+ // transpilation — and, when the same page mixes identified and
11433
+ // unidentified requests, two incompatible versions of one module. An
11434
+ // actual ancient browser hiding its identity fails loudly instead, which
11435
+ // is the right failure for dev.
11429
11436
  const clientRuntimeCompat =
11430
11437
  runtimeName === "unknown"
11431
- ? runtimeCompat
11438
+ ? UNKNOWN_CLIENT_RUNTIME_COMPAT
11432
11439
  : { [runtimeName]: runtimeVersion };
11433
11440
 
11434
11441
  kitchen = createKitchen({
@@ -11622,6 +11629,41 @@ const devServerPluginServeSourceFiles = ({
11622
11629
  request.resource,
11623
11630
  parentUrl,
11624
11631
  );
11632
+ if (!reference) {
11633
+ // Inline content ("page.html@L10C7-L14C16.js") has no file of its
11634
+ // own: it is served from the reference its parent creates when it
11635
+ // is cooked. Without a usable referer the parent is not known —
11636
+ // devtools re-fetching a resource on its own, a second kitchen for
11637
+ // the same page (the WebKit inspector sends its own user agent) —
11638
+ // so it is derived from the url and cooked first.
11639
+ const inlineParentUrl = getInlineContentParentUrl(requestedUrl);
11640
+ if (inlineParentUrl) {
11641
+ if (!kitchen.graph.getUrlInfo(inlineParentUrl)) {
11642
+ const rootUrlInfo = kitchen.graph.rootUrlInfo;
11643
+ const inlineParentWebUrl = WEB_URL_CONVERTER.asWebUrl(
11644
+ inlineParentUrl,
11645
+ {
11646
+ origin: request.origin,
11647
+ rootDirectoryUrl: sourceDirectoryUrl,
11648
+ },
11649
+ );
11650
+ const parentReference =
11651
+ rootUrlInfo.dependencies.createResolveAndFinalize({
11652
+ trace: { message: parentUrl },
11653
+ type: "http_request",
11654
+ specifier: inlineParentWebUrl.slice(request.origin.length),
11655
+ });
11656
+ await parentReference.urlInfo.cook({
11657
+ request,
11658
+ reference: parentReference,
11659
+ });
11660
+ }
11661
+ reference = kitchen.graph.inferReference(
11662
+ request.resource,
11663
+ inlineParentUrl,
11664
+ );
11665
+ }
11666
+ }
11625
11667
  if (reference) {
11626
11668
  reference.urlInfo.context.request = request;
11627
11669
  reference.urlInfo.context.requestedUrl = requestedUrl;
@@ -11907,6 +11949,21 @@ const cacheIsDisabledInResponseHeader = (urlInfo) => {
11907
11949
  );
11908
11950
  };
11909
11951
 
11952
+ // "dir/page.html@L10C7-L14C16.js" -> "dir/page.html" (search kept: it is the
11953
+ // parent's). Null for anything else — the inline url grammar is the one
11954
+ // generateUrlForInlineContent writes (@jsenv/ast).
11955
+ const getInlineContentParentUrl = (url) => {
11956
+ const urlObject = new URL(url);
11957
+ const match = /^(.+)@[^@/]*?L\d+C\d+(?:-L\d+C\d+)?\.[a-z0-9]+$/.exec(
11958
+ urlObject.pathname,
11959
+ );
11960
+ if (!match) {
11961
+ return null;
11962
+ }
11963
+ urlObject.pathname = match[1];
11964
+ return urlObject.href;
11965
+ };
11966
+
11910
11967
  const EXECUTED_BY_TEST_PLAN = process.argv.includes("--jsenv-test");
11911
11968
 
11912
11969
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jsenv/core",
3
- "version": "41.4.21",
3
+ "version": "41.4.23",
4
4
  "type": "module",
5
5
  "description": "Tool to develop, test and build js projects",
6
6
  "repository": {
@@ -10,6 +10,11 @@ import { createKitchen } from "../../kitchen/kitchen.js";
10
10
  import { createJsenvPluginsController } from "../../plugins/jsenv_plugins_controller.js";
11
11
  import { getRuntimeFromRequest } from "./runtime_from_request.js";
12
12
 
13
+ // What the newest browser supports, and nothing less: the source untouched.
14
+ // A version no browser has, so that every feature known to runtime-compat
15
+ // counts as supported.
16
+ const UNKNOWN_CLIENT_RUNTIME_COMPAT = { chrome: "9999.0.0" };
17
+
13
18
  export const devServerPluginServeSourceFiles = ({
14
19
  packageDirectory,
15
20
  sourceDirectoryUrl,
@@ -70,14 +75,16 @@ export const devServerPluginServeSourceFiles = ({
70
75
  }
71
76
  });
72
77
  // A client we cannot identify (curl, fetch, a healthcheck, a proxy dropping
73
- // the user agent) is assumed to be one of the runtimes the project targets.
74
- // Treating it as a runtime supporting nothing would serve it the js module
75
- // fallback, breaking tooling perfectly capable of ES modules; an actual
76
- // ancient browser hiding its identity fails loudly instead, which is the
77
- // cheaper of the two mistakes.
78
+ // the user agent, the WebKit inspector re-requesting a page's resources
79
+ // under its own agent) is served the source as it is written. Taking the
80
+ // build targets instead would hand it the js module fallback and a heavy
81
+ // transpilation — and, when the same page mixes identified and
82
+ // unidentified requests, two incompatible versions of one module. An
83
+ // actual ancient browser hiding its identity fails loudly instead, which
84
+ // is the right failure for dev.
78
85
  const clientRuntimeCompat =
79
86
  runtimeName === "unknown"
80
- ? runtimeCompat
87
+ ? UNKNOWN_CLIENT_RUNTIME_COMPAT
81
88
  : { [runtimeName]: runtimeVersion };
82
89
 
83
90
  kitchen = createKitchen({
@@ -271,6 +278,41 @@ export const devServerPluginServeSourceFiles = ({
271
278
  request.resource,
272
279
  parentUrl,
273
280
  );
281
+ if (!reference) {
282
+ // Inline content ("page.html@L10C7-L14C16.js") has no file of its
283
+ // own: it is served from the reference its parent creates when it
284
+ // is cooked. Without a usable referer the parent is not known —
285
+ // devtools re-fetching a resource on its own, a second kitchen for
286
+ // the same page (the WebKit inspector sends its own user agent) —
287
+ // so it is derived from the url and cooked first.
288
+ const inlineParentUrl = getInlineContentParentUrl(requestedUrl);
289
+ if (inlineParentUrl) {
290
+ if (!kitchen.graph.getUrlInfo(inlineParentUrl)) {
291
+ const rootUrlInfo = kitchen.graph.rootUrlInfo;
292
+ const inlineParentWebUrl = WEB_URL_CONVERTER.asWebUrl(
293
+ inlineParentUrl,
294
+ {
295
+ origin: request.origin,
296
+ rootDirectoryUrl: sourceDirectoryUrl,
297
+ },
298
+ );
299
+ const parentReference =
300
+ rootUrlInfo.dependencies.createResolveAndFinalize({
301
+ trace: { message: parentUrl },
302
+ type: "http_request",
303
+ specifier: inlineParentWebUrl.slice(request.origin.length),
304
+ });
305
+ await parentReference.urlInfo.cook({
306
+ request,
307
+ reference: parentReference,
308
+ });
309
+ }
310
+ reference = kitchen.graph.inferReference(
311
+ request.resource,
312
+ inlineParentUrl,
313
+ );
314
+ }
315
+ }
274
316
  if (reference) {
275
317
  reference.urlInfo.context.request = request;
276
318
  reference.urlInfo.context.requestedUrl = requestedUrl;
@@ -555,3 +597,18 @@ const cacheIsDisabledInResponseHeader = (urlInfo) => {
555
597
  urlInfo.headers["cache-control"] === "no-cache"
556
598
  );
557
599
  };
600
+
601
+ // "dir/page.html@L10C7-L14C16.js" -> "dir/page.html" (search kept: it is the
602
+ // parent's). Null for anything else — the inline url grammar is the one
603
+ // generateUrlForInlineContent writes (@jsenv/ast).
604
+ const getInlineContentParentUrl = (url) => {
605
+ const urlObject = new URL(url);
606
+ const match = /^(.+)@[^@/]*?L\d+C\d+(?:-L\d+C\d+)?\.[a-z0-9]+$/.exec(
607
+ urlObject.pathname,
608
+ );
609
+ if (!match) {
610
+ return null;
611
+ }
612
+ urlObject.pathname = match[1];
613
+ return urlObject.href;
614
+ };