@jsenv/core 36.2.1 → 36.3.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 (124) hide show
  1. package/dist/babel_helpers/AsyncGenerator/AsyncGenerator.js +45 -35
  2. package/dist/babel_helpers/AwaitValue/AwaitValue.js +3 -3
  3. package/dist/babel_helpers/applyDecoratedDescriptor/applyDecoratedDescriptor.js +13 -13
  4. package/dist/babel_helpers/applyDecs/applyDecs.js +227 -42
  5. package/dist/babel_helpers/applyDecs2203/applyDecs2203.js +559 -418
  6. package/dist/babel_helpers/applyDecs2203R/applyDecs2203R.js +235 -87
  7. package/dist/babel_helpers/applyDecs2301/applyDecs2301.js +591 -456
  8. package/dist/babel_helpers/applyDecs2305/applyDecs2305.js +681 -0
  9. package/dist/babel_helpers/arrayLikeToArray/arrayLikeToArray.js +5 -5
  10. package/dist/babel_helpers/arrayWithHoles/arrayWithHoles.js +3 -3
  11. package/dist/babel_helpers/arrayWithoutHoles/arrayWithoutHoles.js +4 -4
  12. package/dist/babel_helpers/assertThisInitialized/assertThisInitialized.js +4 -4
  13. package/dist/babel_helpers/asyncGeneratorDelegate/asyncGeneratorDelegate.js +12 -4
  14. package/dist/babel_helpers/asyncIterator/asyncIterator.js +13 -11
  15. package/dist/babel_helpers/asyncToGenerator/asyncToGenerator.js +18 -17
  16. package/dist/babel_helpers/awaitAsyncGenerator/awaitAsyncGenerator.js +2 -1
  17. package/dist/babel_helpers/checkInRHS/checkInRHS.js +8 -5
  18. package/dist/babel_helpers/classApplyDescriptorDestructureSet/classApplyDescriptorDestructureSet.js +7 -7
  19. package/dist/babel_helpers/classApplyDescriptorGet/classApplyDescriptorGet.js +3 -3
  20. package/dist/babel_helpers/classApplyDescriptorSet/classApplyDescriptorSet.js +4 -4
  21. package/dist/babel_helpers/classCallCheck/classCallCheck.js +2 -2
  22. package/dist/babel_helpers/classCheckPrivateStaticAccess/classCheckPrivateStaticAccess.js +2 -2
  23. package/dist/babel_helpers/classCheckPrivateStaticFieldDescriptor/classCheckPrivateStaticFieldDescriptor.js +2 -2
  24. package/dist/babel_helpers/classExtractFieldDescriptor/classExtractFieldDescriptor.js +3 -3
  25. package/dist/babel_helpers/classNameTDZError/classNameTDZError.js +2 -2
  26. package/dist/babel_helpers/classPrivateFieldDestructureSet/classPrivateFieldDestructureSet.js +6 -5
  27. package/dist/babel_helpers/classPrivateFieldGet/classPrivateFieldGet.js +6 -5
  28. package/dist/babel_helpers/classPrivateFieldLooseBase/classPrivateFieldLooseBase.js +3 -3
  29. package/dist/babel_helpers/classPrivateFieldLooseKey/classPrivateFieldLooseKey.js +3 -3
  30. package/dist/babel_helpers/classPrivateFieldSet/classPrivateFieldSet.js +7 -6
  31. package/dist/babel_helpers/classPrivateMethodGet/classPrivateMethodGet.js +3 -3
  32. package/dist/babel_helpers/classPrivateMethodSet/classPrivateMethodSet.js +2 -2
  33. package/dist/babel_helpers/classStaticPrivateFieldSpecGet/classStaticPrivateFieldSpecGet.js +8 -7
  34. package/dist/babel_helpers/classStaticPrivateFieldSpecSet/classStaticPrivateFieldSpecSet.js +15 -9
  35. package/dist/babel_helpers/classStaticPrivateMethodGet/classStaticPrivateMethodGet.js +5 -4
  36. package/dist/babel_helpers/classStaticPrivateMethodSet/classStaticPrivateMethodSet.js +2 -2
  37. package/dist/babel_helpers/construct/construct.js +10 -9
  38. package/dist/babel_helpers/createClass/createClass.js +2 -3
  39. package/dist/babel_helpers/createForOfIteratorHelper/createForOfIteratorHelper.js +30 -29
  40. package/dist/babel_helpers/createForOfIteratorHelperLoose/createForOfIteratorHelperLoose.js +18 -16
  41. package/dist/babel_helpers/createRawReactElement/createRawReactElement.js +23 -17
  42. package/dist/babel_helpers/createSuper/createSuper.js +14 -12
  43. package/dist/babel_helpers/decorate/decorate.js +242 -210
  44. package/dist/babel_helpers/defaults/defaults.js +6 -6
  45. package/dist/babel_helpers/defineAccessor/defineAccessor.js +1 -4
  46. package/dist/babel_helpers/defineEnumerableProperties/defineEnumerableProperties.js +12 -12
  47. package/dist/babel_helpers/defineProperty/defineProperty.js +7 -6
  48. package/dist/babel_helpers/extends/extends.js +5 -4
  49. package/dist/babel_helpers/get/get.js +2 -1
  50. package/dist/babel_helpers/getPrototypeOf/getPrototypeOf.js +4 -3
  51. package/dist/babel_helpers/inherits/inherits.js +3 -4
  52. package/dist/babel_helpers/inheritsLoose/inheritsLoose.js +6 -5
  53. package/dist/babel_helpers/initializerDefineProperty/initializerDefineProperty.js +4 -4
  54. package/dist/babel_helpers/initializerWarningHelper/initializerWarningHelper.js +5 -2
  55. package/dist/babel_helpers/instanceof/instanceof.js +3 -3
  56. package/dist/babel_helpers/interopRequireDefault/interopRequireDefault.js +2 -4
  57. package/dist/babel_helpers/interopRequireWildcard/interopRequireWildcard.js +19 -21
  58. package/dist/babel_helpers/isNativeFunction/isNativeFunction.js +2 -2
  59. package/dist/babel_helpers/isNativeReflectConstruct/isNativeReflectConstruct.js +7 -7
  60. package/dist/babel_helpers/iterableToArray/iterableToArray.js +6 -2
  61. package/dist/babel_helpers/iterableToArrayLimit/iterableToArrayLimit.js +6 -1
  62. package/dist/babel_helpers/iterableToArrayLimitLoose/iterableToArrayLimitLoose.js +6 -2
  63. package/dist/babel_helpers/jsx/jsx.js +14 -7
  64. package/dist/babel_helpers/maybeArrayLike/maybeArrayLike.js +6 -5
  65. package/dist/babel_helpers/newArrowCheck/newArrowCheck.js +2 -2
  66. package/dist/babel_helpers/nonIterableRest/nonIterableRest.js +5 -3
  67. package/dist/babel_helpers/nonIterableSpread/nonIterableSpread.js +5 -3
  68. package/dist/babel_helpers/objectDestructuringEmpty/objectDestructuringEmpty.js +2 -2
  69. package/dist/babel_helpers/objectSpread/objectSpread.js +15 -12
  70. package/dist/babel_helpers/objectSpread2/objectSpread2.js +7 -2
  71. package/dist/babel_helpers/objectWithoutProperties/objectWithoutProperties.js +15 -13
  72. package/dist/babel_helpers/objectWithoutPropertiesLoose/objectWithoutPropertiesLoose.js +11 -11
  73. package/dist/babel_helpers/possibleConstructorReturn/possibleConstructorReturn.js +7 -6
  74. package/dist/babel_helpers/readOnlyError/readOnlyError.js +2 -2
  75. package/dist/babel_helpers/regeneratorRuntime/regeneratorRuntime.js +124 -73
  76. package/dist/babel_helpers/set/set.js +23 -20
  77. package/dist/babel_helpers/setPrototypeOf/setPrototypeOf.js +6 -5
  78. package/dist/babel_helpers/skipFirstGeneratorNext/skipFirstGeneratorNext.js +5 -5
  79. package/dist/babel_helpers/slicedToArray/slicedToArray.js +10 -5
  80. package/dist/babel_helpers/slicedToArrayLoose/slicedToArrayLoose.js +12 -6
  81. package/dist/babel_helpers/superPropBase/superPropBase.js +6 -5
  82. package/dist/babel_helpers/taggedTemplateLiteral/taggedTemplateLiteral.js +7 -7
  83. package/dist/babel_helpers/taggedTemplateLiteralLoose/taggedTemplateLiteralLoose.js +4 -4
  84. package/dist/babel_helpers/tdz/tdz.js +2 -2
  85. package/dist/babel_helpers/temporalRef/temporalRef.js +5 -4
  86. package/dist/babel_helpers/temporalUndefined/temporalUndefined.js +1 -1
  87. package/dist/babel_helpers/toArray/toArray.js +10 -5
  88. package/dist/babel_helpers/toConsumableArray/toConsumableArray.js +10 -5
  89. package/dist/babel_helpers/toPrimitive/toPrimitive.js +7 -7
  90. package/dist/babel_helpers/toPropertyKey/toPropertyKey.js +5 -4
  91. package/dist/babel_helpers/typeof/typeof.js +14 -5
  92. package/dist/babel_helpers/unsupportedIterableToArray/unsupportedIterableToArray.js +10 -8
  93. package/dist/babel_helpers/wrapAsyncGenerator/wrapAsyncGenerator.js +5 -4
  94. package/dist/babel_helpers/wrapNativeSuper/wrapNativeSuper.js +17 -15
  95. package/dist/babel_helpers/wrapRegExp/wrapRegExp.js +19 -8
  96. package/dist/babel_helpers/writeOnlyError/writeOnlyError.js +2 -2
  97. package/dist/js/autoreload.js +148 -133
  98. package/dist/js/import_meta_hot.js +19 -13
  99. package/dist/js/inline_content.js +1 -3
  100. package/dist/js/new_stylesheet.js +119 -60
  101. package/dist/js/regenerator_runtime.js +204 -102
  102. package/dist/js/ribbon.js +11 -6
  103. package/dist/js/server_events_client.js +122 -98
  104. package/dist/js/ws.js +968 -265
  105. package/dist/jsenv_core.js +8513 -6162
  106. package/package.json +9 -9
  107. package/src/build/build.js +497 -486
  108. package/src/build/version_mappings_injection.js +21 -44
  109. package/src/kitchen/errors.js +2 -2
  110. package/src/kitchen/fetched_content_compliance.js +6 -2
  111. package/src/kitchen/kitchen.js +285 -80
  112. package/src/kitchen/prepend_content.js +135 -0
  113. package/src/kitchen/url_graph/url_graph_visitor.js +99 -0
  114. package/src/kitchen/url_graph/url_info_transformations.js +140 -21
  115. package/src/kitchen/url_graph.js +59 -29
  116. package/src/plugins/autoreload/jsenv_plugin_hmr.js +1 -2
  117. package/src/plugins/import_meta_hot/jsenv_plugin_import_meta_hot.js +2 -2
  118. package/src/plugins/importmap/jsenv_plugin_importmap.js +2 -2
  119. package/src/plugins/inlining/jsenv_plugin_inlining_as_data_url.js +1 -1
  120. package/src/plugins/reference_analysis/html/jsenv_plugin_html_reference_analysis.js +44 -23
  121. package/src/plugins/reference_analysis/js/jsenv_plugin_js_reference_analysis.js +2 -1
  122. package/dist/js/global_this_js_classic.js +0 -24
  123. package/dist/js/global_this_js_module.js +0 -20
  124. package/src/build/graph_utils.js +0 -34
@@ -1,6 +1,5 @@
1
1
  // https://bundlers.tooling.report/hashing/avoid-cascade/
2
2
 
3
- import { createMagicSource } from "@jsenv/sourcemap";
4
3
  import {
5
4
  parseHtmlString,
6
5
  injectHtmlNodeAsEarlyAsPossible,
@@ -9,56 +8,34 @@ import {
9
8
  } from "@jsenv/ast";
10
9
 
11
10
  import { isWebWorkerUrlInfo } from "@jsenv/core/src/kitchen/web_workers.js";
11
+ import { prependContent } from "../kitchen/prepend_content.js";
12
12
 
13
13
  export const injectVersionMappingsAsGlobal = async ({
14
- urlInfo,
15
14
  kitchen,
15
+ urlInfo,
16
16
  versionMappings,
17
17
  }) => {
18
- const injector = injectors[urlInfo.type];
19
- if (injector) {
20
- const { content, sourcemap } = await injector(urlInfo, {
21
- versionMappings,
22
- minification: kitchen.kitchenContext.minification,
23
- });
24
- kitchen.urlInfoTransformer.applyFinalTransformations(urlInfo, {
25
- content,
26
- sourcemap,
18
+ if (urlInfo.type === "html") {
19
+ return prependContent(kitchen.urlInfoTransformer, urlInfo, {
20
+ type: "js_classic",
21
+ content: generateClientCodeForVersionMappings(versionMappings, {
22
+ globalName: "window",
23
+ minification: kitchen.kitchenContext.minification,
24
+ }),
27
25
  });
28
26
  }
29
- };
30
- const injectors = {
31
- html: (urlInfo, { versionMappings, minification }) => {
32
- const htmlAst = parseHtmlString(urlInfo.content, {
33
- storeOriginalPositions: false,
34
- });
35
- injectHtmlNodeAsEarlyAsPossible(
36
- htmlAst,
37
- createHtmlNode({
38
- tagName: "script",
39
- textContent: generateClientCodeForVersionMappings(versionMappings, {
40
- globalName: "window",
41
- minification,
42
- }),
27
+ if (urlInfo.type === "js_classic" || urlInfo.type === "js_module") {
28
+ return prependContent(kitchen.urlInfoTransformer, urlInfo, {
29
+ type: "js_classic",
30
+ content: generateClientCodeForVersionMappings(versionMappings, {
31
+ globalName: isWebWorkerUrlInfo(urlInfo) ? "self" : "window",
32
+ minification: kitchen.kitchenContext.minification,
43
33
  }),
44
- "jsenv:versioning",
45
- );
46
- return {
47
- content: stringifyHtmlAst(htmlAst),
48
- };
49
- },
50
- js_classic: (...args) => jsInjector(...args),
51
- js_module: (...args) => jsInjector(...args),
52
- };
53
- const jsInjector = (urlInfo, { versionMappings, minification }) => {
54
- const magicSource = createMagicSource(urlInfo.content);
55
- const code = generateClientCodeForVersionMappings(versionMappings, {
56
- globalName: isWebWorkerUrlInfo(urlInfo) ? "self" : "window",
57
- minification,
58
- });
59
- magicSource.prepend(`${code}\n\n`);
60
- return magicSource.toContentAndSourcemap();
34
+ });
35
+ }
36
+ return null;
61
37
  };
38
+
62
39
  const generateClientCodeForVersionMappings = (
63
40
  versionMappings,
64
41
  { globalName, minification },
@@ -77,8 +54,8 @@ const generateClientCodeForVersionMappings = (
77
54
  };
78
55
 
79
56
  export const injectVersionMappingsAsImportmap = async ({
80
- urlInfo,
81
57
  kitchen,
58
+ urlInfo,
82
59
  versionMappings,
83
60
  }) => {
84
61
  const htmlAst = parseHtmlString(urlInfo.content, {
@@ -98,7 +75,7 @@ export const injectVersionMappingsAsImportmap = async ({
98
75
  }),
99
76
  "jsenv:versioning",
100
77
  );
101
- kitchen.urlInfoTransformer.applyFinalTransformations(urlInfo, {
78
+ kitchen.urlInfoTransformer.applyTransformations(urlInfo, {
102
79
  content: stringifyHtmlAst(htmlAst),
103
80
  });
104
81
  };
@@ -110,8 +110,8 @@ export const createFetchUrlContentError = ({
110
110
  if (error.code === "PARSE_ERROR") {
111
111
  return createFailedToFetchUrlContentError({
112
112
  "code": "PARSE_ERROR",
113
- "reason": error.reason,
114
- "parse error message": error.cause.message,
113
+ "reason": error.reasonCode,
114
+ ...(error.cause ? { "parse error message": error.cause.message } : {}),
115
115
  "parse error trace": error.traceMessage,
116
116
  });
117
117
  }
@@ -1,6 +1,10 @@
1
1
  import { validateResponseIntegrity } from "@jsenv/integrity";
2
2
 
3
- export const assertFetchedContentCompliance = ({ reference, urlInfo }) => {
3
+ export const assertFetchedContentCompliance = ({
4
+ reference,
5
+ urlInfo,
6
+ content,
7
+ }) => {
4
8
  const { expectedContentType } = reference;
5
9
  if (expectedContentType && urlInfo.contentType !== expectedContentType) {
6
10
  throw new Error(
@@ -18,7 +22,7 @@ export const assertFetchedContentCompliance = ({ reference, urlInfo }) => {
18
22
  validateResponseIntegrity({
19
23
  url: urlInfo.url,
20
24
  type: "basic",
21
- dataRepresentation: urlInfo.content,
25
+ dataRepresentation: content,
22
26
  });
23
27
  }
24
28
  };
@@ -21,8 +21,10 @@ import {
21
21
  createTransformUrlContentError,
22
22
  createFinalizeUrlContentError,
23
23
  } from "./errors.js";
24
+ import { GRAPH_VISITOR } from "./url_graph/url_graph_visitor.js";
24
25
  import { assertFetchedContentCompliance } from "./fetched_content_compliance.js";
25
26
  import { isWebWorkerEntryPointReference } from "./web_workers.js";
27
+ import { prependContent } from "./prepend_content.js";
26
28
 
27
29
  const inlineContentClientFileUrl = new URL(
28
30
  "./client/inline_content.js",
@@ -54,6 +56,8 @@ export const createKitchen = ({
54
56
  sourcemapsSourcesRelative,
55
57
  outDirectoryUrl,
56
58
  }) => {
59
+ const sideEffectForwardCallbacks = [];
60
+
57
61
  const logger = createLogger({ logLevel });
58
62
  const kitchenContext = {
59
63
  signal,
@@ -66,12 +70,8 @@ export const createKitchen = ({
66
70
  runtimeCompat,
67
71
  clientRuntimeCompat,
68
72
  systemJsTranspilation,
69
- isSupportedOnCurrentClients: (feature) => {
70
- return RUNTIME_COMPAT.isSupported(clientRuntimeCompat, feature);
71
- },
72
- isSupportedOnFutureClients: (feature) => {
73
- return RUNTIME_COMPAT.isSupported(runtimeCompat, feature);
74
- },
73
+ isSupportedOnCurrentClients: memoizeIsSupported(clientRuntimeCompat),
74
+ isSupportedOnFutureClients: memoizeIsSupported(runtimeCompat),
75
75
  minification,
76
76
  sourcemaps,
77
77
  outDirectoryUrl,
@@ -133,6 +133,7 @@ export const createKitchen = ({
133
133
  * - "sourcemap_comment"
134
134
  * - "webmanifest_icon_src"
135
135
  * - "package_json"
136
+ * - "side_effect_file"
136
137
  * */
137
138
  const createReference = ({
138
139
  data = {},
@@ -445,11 +446,11 @@ ${ANSI.color(normalizedReturnValue, ANSI.YELLOW)}
445
446
  let {
446
447
  content,
447
448
  contentType,
449
+ originalContent = content,
448
450
  data,
449
451
  type,
450
452
  subtype,
451
453
  originalUrl,
452
- originalContent = content,
453
454
  sourcemap,
454
455
  filename,
455
456
 
@@ -475,15 +476,6 @@ ${ANSI.color(normalizedReturnValue, ANSI.YELLOW)}
475
476
  subtype || reference.expectedSubtype || urlInfo.subtypeHint || "";
476
477
  // during build urls info are reused and load returns originalUrl/originalContent
477
478
  urlInfo.originalUrl = originalUrl || urlInfo.originalUrl;
478
- if (originalContent !== urlInfo.originalContent) {
479
- urlInfo.originalContentEtag = undefined; // set by "initTransformations"
480
- }
481
- if (content !== urlInfo.content) {
482
- urlInfo.contentEtag = undefined; // set by "applyFinalTransformations"
483
- }
484
- urlInfo.originalContent = originalContent;
485
- urlInfo.content = content;
486
- urlInfo.sourcemap = sourcemap;
487
479
  if (data) {
488
480
  Object.assign(urlInfo.data, data);
489
481
  }
@@ -496,7 +488,45 @@ ${ANSI.color(normalizedReturnValue, ANSI.YELLOW)}
496
488
  assertFetchedContentCompliance({
497
489
  reference,
498
490
  urlInfo,
491
+ content,
492
+ });
493
+ urlInfo.generatedUrl = determineFileUrlForOutDirectory({
494
+ urlInfo,
495
+ context: contextDuringFetch,
499
496
  });
497
+
498
+ // we wait here to read .contentAst and .originalContentAst
499
+ // so that we don't trigger lazy getters
500
+ // that would try to parse url too soon (before having urlInfo.type being set)
501
+ // also we do not want to trigger the getters that would parse url content
502
+ // too soon
503
+ const contentAstDescriptor = Object.getOwnPropertyDescriptor(
504
+ fetchUrlContentReturnValue,
505
+ "contentAst",
506
+ );
507
+ const originalContentAstDescriptor = Object.getOwnPropertyDescriptor(
508
+ fetchUrlContentReturnValue,
509
+ "originalContentAst",
510
+ );
511
+ await urlInfoTransformer.initTransformations(
512
+ urlInfo,
513
+ {
514
+ content,
515
+ sourcemap,
516
+ originalContent,
517
+ contentAst: contentAstDescriptor
518
+ ? contentAstDescriptor.get
519
+ ? undefined
520
+ : contentAstDescriptor.value
521
+ : undefined,
522
+ originalContentAst: originalContentAstDescriptor
523
+ ? originalContentAstDescriptor.get
524
+ ? undefined
525
+ : originalContentAstDescriptor.value
526
+ : undefined,
527
+ },
528
+ contextDuringFetch,
529
+ );
500
530
  } catch (error) {
501
531
  throw createFetchUrlContentError({
502
532
  pluginController,
@@ -505,11 +535,6 @@ ${ANSI.color(normalizedReturnValue, ANSI.YELLOW)}
505
535
  error,
506
536
  });
507
537
  }
508
- urlInfo.generatedUrl = determineFileUrlForOutDirectory({
509
- urlInfo,
510
- context: contextDuringFetch,
511
- });
512
- await urlInfoTransformer.initTransformations(urlInfo, contextDuringFetch);
513
538
  };
514
539
  kitchenContext.fetchUrlContent = fetchUrlContent;
515
540
 
@@ -535,22 +560,48 @@ ${ANSI.color(normalizedReturnValue, ANSI.YELLOW)}
535
560
  if (!urlInfo.url.startsWith("ignore:")) {
536
561
  // references
537
562
  const references = [];
563
+ const addReference = (props) => {
564
+ const [reference, referencedUrlInfo] = resolveReference(
565
+ createReference({
566
+ parentUrl: urlInfo.url,
567
+ ...props,
568
+ }),
569
+ context,
570
+ );
571
+ references.push(reference);
572
+ return [reference, referencedUrlInfo];
573
+ };
574
+ const mutateReference = (currentReference, newReferenceParams) => {
575
+ const index = references.indexOf(currentReference);
576
+ if (index === -1) {
577
+ throw new Error(`reference do not exists`);
578
+ }
579
+ const ref = createReference({
580
+ ...currentReference,
581
+ ...newReferenceParams,
582
+ });
583
+ const [newReference, newUrlInfo] = resolveReference(ref, context);
584
+ updateReference(currentReference, newReference);
585
+ references[index] = newReference;
586
+ const currentUrlInfo = context.urlGraph.getUrlInfo(
587
+ currentReference.url,
588
+ );
589
+ if (
590
+ currentUrlInfo &&
591
+ currentUrlInfo !== newUrlInfo &&
592
+ !urlGraph.isUsed(currentUrlInfo)
593
+ ) {
594
+ context.urlGraph.deleteUrlInfo(currentReference.url);
595
+ }
596
+ return [newReference, newUrlInfo];
597
+ };
598
+
599
+ const beforeFinalizeCallbacks = [];
538
600
  context.referenceUtils = {
539
601
  inlineContentClientFileUrl,
540
602
  _references: references,
541
603
  find: (predicate) => references.find(predicate),
542
604
  readGeneratedSpecifier,
543
- add: (props) => {
544
- const [reference, referencedUrlInfo] = resolveReference(
545
- createReference({
546
- parentUrl: urlInfo.url,
547
- ...props,
548
- }),
549
- context,
550
- );
551
- references.push(reference);
552
- return [reference, referencedUrlInfo];
553
- },
554
605
  found: ({ trace, ...rest }) => {
555
606
  if (trace === undefined) {
556
607
  trace = traceFromUrlSite(
@@ -563,7 +614,7 @@ ${ANSI.color(normalizedReturnValue, ANSI.YELLOW)}
563
614
  );
564
615
  }
565
616
  // console.log(trace.message)
566
- return context.referenceUtils.add({
617
+ return addReference({
567
618
  trace,
568
619
  ...rest,
569
620
  });
@@ -580,7 +631,7 @@ ${ANSI.color(normalizedReturnValue, ANSI.YELLOW)}
580
631
  const parentContent = isOriginalPosition
581
632
  ? urlInfo.originalContent
582
633
  : urlInfo.content;
583
- return context.referenceUtils.add({
634
+ return addReference({
584
635
  trace: traceFromUrlSite({
585
636
  url: parentUrl,
586
637
  content: parentContent,
@@ -594,31 +645,155 @@ ${ANSI.color(normalizedReturnValue, ANSI.YELLOW)}
594
645
  ...rest,
595
646
  });
596
647
  },
597
- update: (currentReference, newReferenceParams) => {
598
- const index = references.indexOf(currentReference);
599
- if (index === -1) {
600
- throw new Error(`reference do not exists`);
648
+ foundSideEffectFile: async ({ sideEffectFileUrl, trace, ...rest }) => {
649
+ if (trace === undefined) {
650
+ const { url, line, column } = getCallerPosition();
651
+ trace = traceFromUrlSite({
652
+ url,
653
+ line,
654
+ column,
655
+ });
601
656
  }
602
- const [newReference, newUrlInfo] = resolveReference(
603
- createReference({
604
- ...currentReference,
605
- ...newReferenceParams,
606
- }),
607
- context,
608
- );
609
- updateReference(currentReference, newReference);
610
- references[index] = newReference;
611
- const currentUrlInfo = context.urlGraph.getUrlInfo(
612
- currentReference.url,
613
- );
614
- if (
615
- currentUrlInfo &&
616
- currentUrlInfo !== newUrlInfo &&
617
- currentUrlInfo.dependents.size === 0
618
- ) {
619
- context.urlGraph.deleteUrlInfo(currentReference.url);
657
+
658
+ const addRef = () =>
659
+ addReference({
660
+ trace,
661
+ type: "side_effect_file",
662
+ isImplicit: true,
663
+ injected: true,
664
+ specifier: sideEffectFileUrl,
665
+ ...rest,
666
+ });
667
+
668
+ const injectAsBannerCodeBeforeFinalize = (
669
+ sideEffectFileReference,
670
+ sideEffectFileUrlInfo,
671
+ ) => {
672
+ beforeFinalizeCallbacks.push(async () => {
673
+ await context.cook(sideEffectFileUrlInfo, {
674
+ reference: sideEffectFileReference,
675
+ });
676
+ await context.referenceUtils.readGeneratedSpecifier(
677
+ sideEffectFileReference,
678
+ );
679
+ await prependContent(
680
+ urlInfoTransformer,
681
+ urlInfo,
682
+ sideEffectFileUrlInfo,
683
+ );
684
+ context.referenceUtils.becomesInline(sideEffectFileReference, {
685
+ specifierLine: 0,
686
+ specifierColumn: 0,
687
+ specifier: sideEffectFileReference.generatedSpecifier,
688
+ content: sideEffectFileUrlInfo.content,
689
+ contentType: sideEffectFileUrlInfo.contentType,
690
+ parentUrl: urlInfo.url,
691
+ parentContent: urlInfo.content,
692
+ });
693
+ });
694
+ return [sideEffectFileReference, sideEffectFileUrlInfo];
695
+ };
696
+
697
+ // When possible we inject code inside the file in the HTML
698
+ // -> less duplication
699
+
700
+ // Case #1: Not possible to inject in other files -> inject as banner code
701
+ if (!["js_classic", "js_module", "css"].includes(urlInfo.type)) {
702
+ const [sideEffectFileReference, sideEffectFileUrlInfo] = addRef();
703
+ return injectAsBannerCodeBeforeFinalize(
704
+ sideEffectFileReference,
705
+ sideEffectFileUrlInfo,
706
+ );
620
707
  }
621
- return [newReference, newUrlInfo];
708
+
709
+ // Case #2: During dev
710
+ // during dev cooking files is incremental
711
+ // so HTML is already executed by the browser
712
+ // but if we find that ref in a dependent we are good
713
+ // and it's possible to find it in dependents when using
714
+ // dynamic import for instance
715
+ // (in that case we find the side effect file as it was injected in parent)
716
+ if (context.dev) {
717
+ const urlsBeforeInjection = Array.from(urlGraph.urlInfoMap.keys());
718
+ const [sideEffectFileReference, sideEffectFileUrlInfo] = addRef();
719
+ if (!urlsBeforeInjection.includes(sideEffectFileReference.url)) {
720
+ return injectAsBannerCodeBeforeFinalize(
721
+ sideEffectFileReference,
722
+ sideEffectFileUrlInfo,
723
+ );
724
+ }
725
+ const isReferencingSideEffectFile = (urlInfo) =>
726
+ urlInfo.references.some(
727
+ (ref) => ref.url === sideEffectFileReference.url,
728
+ );
729
+ const selfOrAncestorIsReferencingSideEffectFile = (
730
+ dependentUrl,
731
+ ) => {
732
+ const dependentUrlInfo = urlGraph.getUrlInfo(dependentUrl);
733
+ if (isReferencingSideEffectFile(dependentUrlInfo)) {
734
+ return true;
735
+ }
736
+ const dependentReferencingThatFile = GRAPH_VISITOR.findDependent(
737
+ urlGraph,
738
+ urlInfo,
739
+ (ancestorUrlInfo) =>
740
+ isReferencingSideEffectFile(ancestorUrlInfo),
741
+ );
742
+ return Boolean(dependentReferencingThatFile);
743
+ };
744
+ for (const dependentUrl of urlInfo.dependents) {
745
+ if (!selfOrAncestorIsReferencingSideEffectFile(dependentUrl)) {
746
+ return injectAsBannerCodeBeforeFinalize(
747
+ sideEffectFileReference,
748
+ sideEffectFileUrlInfo,
749
+ );
750
+ }
751
+ }
752
+ return [sideEffectFileReference, sideEffectFileUrlInfo];
753
+ }
754
+
755
+ // Case #3: During build
756
+ // during build, files are not executed so it's
757
+ // possible to inject reference when discovering a side effect file
758
+ if (urlInfo.isEntryPoint) {
759
+ const [sideEffectFileReference, sideEffectFileUrlInfo] = addRef();
760
+ return injectAsBannerCodeBeforeFinalize(
761
+ sideEffectFileReference,
762
+ sideEffectFileUrlInfo,
763
+ );
764
+ }
765
+ const entryPoints = urlGraph.getEntryPoints();
766
+ const [sideEffectFileReference, sideEffectFileUrlInfo] = addRef();
767
+ for (const entryPointUrlInfo of entryPoints) {
768
+ sideEffectForwardCallbacks.push(async () => {
769
+ // do not inject if already there
770
+ const { dependencies } = entryPointUrlInfo;
771
+ if (dependencies.has(sideEffectFileUrlInfo.url)) {
772
+ return;
773
+ }
774
+ dependencies.add(sideEffectFileUrlInfo.url);
775
+ await prependContent(
776
+ urlInfoTransformer,
777
+ entryPointUrlInfo,
778
+ sideEffectFileUrlInfo,
779
+ );
780
+ await context.referenceUtils.readGeneratedSpecifier(
781
+ sideEffectFileReference,
782
+ );
783
+ context.referenceUtils.becomesInline(sideEffectFileReference, {
784
+ specifier: sideEffectFileReference.generatedSpecifier,
785
+ // ideally get the correct line and column
786
+ // (for js it's 0, but for html it's different)
787
+ specifierLine: 0,
788
+ specifierColumn: 0,
789
+ content: sideEffectFileUrlInfo.content,
790
+ contentType: sideEffectFileUrlInfo.contentType,
791
+ parentUrl: entryPointUrlInfo.url,
792
+ parentContent: entryPointUrlInfo.content,
793
+ });
794
+ });
795
+ }
796
+ return [sideEffectFileReference, sideEffectFileUrlInfo];
622
797
  },
623
798
  inject: ({ trace, ...rest }) => {
624
799
  if (trace === undefined) {
@@ -629,7 +804,7 @@ ${ANSI.color(normalizedReturnValue, ANSI.YELLOW)}
629
804
  column,
630
805
  });
631
806
  }
632
- return context.referenceUtils.add({
807
+ return addReference({
633
808
  trace,
634
809
  injected: true,
635
810
  ...rest,
@@ -638,27 +813,35 @@ ${ANSI.color(normalizedReturnValue, ANSI.YELLOW)}
638
813
  becomesInline: (
639
814
  reference,
640
815
  {
641
- isOriginalPosition,
816
+ isOriginalPosition = reference.isOriginalPosition,
642
817
  specifier,
643
818
  specifierLine,
644
819
  specifierColumn,
645
820
  contentType,
646
821
  content,
822
+ parentUrl = reference.parentUrl,
823
+ parentContent,
647
824
  },
648
825
  ) => {
649
- const parentUrl = isOriginalPosition
650
- ? urlInfo.url
651
- : urlInfo.generatedUrl;
652
- const parentContent = isOriginalPosition
653
- ? urlInfo.originalContent
654
- : urlInfo.content;
655
- return context.referenceUtils.update(reference, {
656
- trace: traceFromUrlSite({
657
- url: parentUrl,
658
- content: parentContent,
659
- line: specifierLine,
660
- column: specifierColumn,
661
- }),
826
+ const trace = traceFromUrlSite({
827
+ url:
828
+ parentUrl === undefined
829
+ ? isOriginalPosition
830
+ ? urlInfo.url
831
+ : urlInfo.generatedUrl
832
+ : parentUrl,
833
+ content:
834
+ parentContent === undefined
835
+ ? isOriginalPosition
836
+ ? urlInfo.originalContent
837
+ : urlInfo.content
838
+ : parentContent,
839
+ line: specifierLine,
840
+ column: specifierColumn,
841
+ });
842
+ return mutateReference(reference, {
843
+ trace,
844
+ parentUrl,
662
845
  isOriginalPosition,
663
846
  isInline: true,
664
847
  specifier,
@@ -685,8 +868,8 @@ ${ANSI.color(normalizedReturnValue, ANSI.YELLOW)}
685
868
  "transformUrlContent",
686
869
  urlInfo,
687
870
  context,
688
- async (transformReturnValue) => {
689
- await urlInfoTransformer.applyIntermediateTransformations(
871
+ (transformReturnValue) => {
872
+ urlInfoTransformer.applyTransformations(
690
873
  urlInfo,
691
874
  transformReturnValue,
692
875
  );
@@ -703,21 +886,25 @@ ${ANSI.color(normalizedReturnValue, ANSI.YELLOW)}
703
886
  urlInfo.error = transformError;
704
887
  throw transformError;
705
888
  }
889
+
706
890
  // after "transform" all references from originalContent
707
891
  // and the one injected by plugin are known
708
892
  urlGraph.updateReferences(urlInfo, references);
709
893
 
710
894
  // "finalize" hook
711
895
  try {
896
+ for (const beforeFinalizeCallback of beforeFinalizeCallbacks) {
897
+ await beforeFinalizeCallback();
898
+ }
899
+ beforeFinalizeCallbacks.length = 0;
900
+
712
901
  const finalizeReturnValue = await pluginController.callAsyncHooksUntil(
713
902
  "finalizeUrlContent",
714
903
  urlInfo,
715
904
  context,
716
905
  );
717
- await urlInfoTransformer.applyFinalTransformations(
718
- urlInfo,
719
- finalizeReturnValue,
720
- );
906
+ urlInfoTransformer.applyTransformations(urlInfo, finalizeReturnValue);
907
+ urlInfoTransformer.applyTransformationsEffects(urlInfo);
721
908
  } catch (error) {
722
909
  throw createFinalizeUrlContentError({
723
910
  pluginController,
@@ -858,6 +1045,13 @@ ${ANSI.color(normalizedReturnValue, ANSI.YELLOW)}
858
1045
  cook,
859
1046
  createReference,
860
1047
  injectReference,
1048
+ injectForwardedSideEffectFiles: async () => {
1049
+ await Promise.all(
1050
+ sideEffectForwardCallbacks.map(async (callback) => {
1051
+ await callback();
1052
+ }),
1053
+ );
1054
+ },
861
1055
  };
862
1056
  };
863
1057
 
@@ -867,7 +1061,6 @@ ${ANSI.color(normalizedReturnValue, ANSI.YELLOW)}
867
1061
  // the specifier is a `data:*` url
868
1062
  // in this case we'll wait for the promise returned by
869
1063
  // "formatReferencedUrl"
870
-
871
1064
  const readGeneratedSpecifier = (reference) => {
872
1065
  if (reference.generatedSpecifier.then) {
873
1066
  return reference.generatedSpecifier.then((value) => {
@@ -908,6 +1101,19 @@ const memoizeCook = (cook) => {
908
1101
  };
909
1102
  };
910
1103
 
1104
+ const memoizeIsSupported = (runtimeCompat) => {
1105
+ const cache = new Map();
1106
+ return (feature) => {
1107
+ const fromCache = cache.get(feature);
1108
+ if (typeof fromCache === "boolean") {
1109
+ return fromCache;
1110
+ }
1111
+ const supported = RUNTIME_COMPAT.isSupported(runtimeCompat, feature);
1112
+ cache.set(feature, supported);
1113
+ return supported;
1114
+ };
1115
+ };
1116
+
911
1117
  const traceFromUrlSite = (urlSite) => {
912
1118
  return {
913
1119
  message: stringifyUrlSite(urlSite),
@@ -923,7 +1129,6 @@ const applyReferenceEffectsOnUrlInfo = (reference, urlInfo, context) => {
923
1129
  if (reference.isEntryPoint || isWebWorkerEntryPointReference(reference)) {
924
1130
  urlInfo.isEntryPoint = true;
925
1131
  }
926
-
927
1132
  Object.assign(urlInfo.data, reference.data);
928
1133
  Object.assign(urlInfo.timing, reference.timing);
929
1134
  if (reference.injected) {