@jsenv/core 36.2.1 → 36.3.1

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 +13 -12
  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
@@ -0,0 +1,135 @@
1
+ import { createMagicSource, composeTwoSourcemaps } from "@jsenv/sourcemap";
2
+ import {
3
+ parseHtmlString,
4
+ stringifyHtmlAst,
5
+ createHtmlNode,
6
+ injectHtmlNodeAsEarlyAsPossible,
7
+ applyBabelPlugins,
8
+ } from "@jsenv/ast";
9
+
10
+ export const prependContent = (
11
+ urlInfoTransformer,
12
+ urlInfoReceivingCode,
13
+ urlInfoToPrepend,
14
+ ) => {
15
+ // we could also implement:
16
+ // - prepend svg in html
17
+ // - prepend css in html
18
+ // - prepend css in css
19
+ // - maybe more?
20
+ // but no need for now
21
+ if (
22
+ urlInfoReceivingCode.type === "html" &&
23
+ urlInfoToPrepend.type === "js_classic"
24
+ ) {
25
+ return prependJsClassicInHtml(
26
+ urlInfoTransformer,
27
+ urlInfoReceivingCode,
28
+ urlInfoToPrepend,
29
+ );
30
+ }
31
+ if (
32
+ urlInfoReceivingCode.type === "js_classic" &&
33
+ urlInfoToPrepend.type === "js_classic"
34
+ ) {
35
+ return prependJsClassicInJsClassic(
36
+ urlInfoTransformer,
37
+ urlInfoReceivingCode,
38
+ urlInfoToPrepend,
39
+ );
40
+ }
41
+ if (
42
+ urlInfoReceivingCode.type === "js_module" &&
43
+ urlInfoToPrepend.type === "js_classic"
44
+ ) {
45
+ return prependJsClassicInJsModule(
46
+ urlInfoTransformer,
47
+ urlInfoReceivingCode,
48
+ urlInfoToPrepend,
49
+ );
50
+ }
51
+ throw new Error(
52
+ `cannot prepend content from "${urlInfoToPrepend.type}" into "${urlInfoReceivingCode.type}"`,
53
+ );
54
+ };
55
+
56
+ const prependJsClassicInHtml = (
57
+ urlInfoTransformer,
58
+ htmlUrlInfo,
59
+ urlInfoToPrepend,
60
+ ) => {
61
+ const htmlAst = parseHtmlString(htmlUrlInfo.content);
62
+ injectHtmlNodeAsEarlyAsPossible(
63
+ htmlAst,
64
+ createHtmlNode({
65
+ tagName: "script",
66
+ textContent: urlInfoToPrepend.content,
67
+ ...(urlInfoToPrepend.url
68
+ ? { "inlined-from-src": urlInfoToPrepend.url }
69
+ : {}),
70
+ }),
71
+ "jsenv:core",
72
+ );
73
+ const content = stringifyHtmlAst(htmlAst);
74
+ urlInfoTransformer.applyTransformations(htmlUrlInfo, { content });
75
+ };
76
+
77
+ const prependJsClassicInJsClassic = (
78
+ urlInfoTransformer,
79
+ jsUrlInfo,
80
+ urlInfoToPrepend,
81
+ ) => {
82
+ const magicSource = createMagicSource(jsUrlInfo.content);
83
+ magicSource.prepend(`${urlInfoToPrepend.content}\n\n`);
84
+ const magicResult = magicSource.toContentAndSourcemap();
85
+ const sourcemap = composeTwoSourcemaps(
86
+ jsUrlInfo.sourcemap,
87
+ magicResult.sourcemap,
88
+ );
89
+ urlInfoTransformer.applyTransformations(jsUrlInfo, {
90
+ content: magicResult.content,
91
+ sourcemap,
92
+ });
93
+ };
94
+
95
+ const prependJsClassicInJsModule = async (
96
+ urlInfoTransformer,
97
+ jsUrlInfo,
98
+ urlInfoToPrepend,
99
+ ) => {
100
+ const { code, map } = await applyBabelPlugins({
101
+ babelPlugins: [
102
+ [
103
+ babelPluginPrependCodeInJsModule,
104
+ { codeToPrepend: urlInfoToPrepend.content },
105
+ ],
106
+ ],
107
+ input: jsUrlInfo.content,
108
+ inputIsJsModule: true,
109
+ inputUrl: jsUrlInfo.originalUrl,
110
+ });
111
+ urlInfoTransformer.applyTransformations(jsUrlInfo, {
112
+ content: code,
113
+ sourcemap: map,
114
+ });
115
+ };
116
+ const babelPluginPrependCodeInJsModule = (babel) => {
117
+ return {
118
+ name: "prepend-code-in-js-module",
119
+ visitor: {
120
+ Program: (programPath, state) => {
121
+ const { codeToPrepend } = state.opts;
122
+ const astToPrepend = babel.parse(codeToPrepend);
123
+ const bodyNodePaths = programPath.get("body");
124
+ for (const bodyNodePath of bodyNodePaths) {
125
+ if (bodyNodePath.node.type === "ImportDeclaration") {
126
+ continue;
127
+ }
128
+ bodyNodePath.insertBefore(astToPrepend.program.body);
129
+ return;
130
+ }
131
+ bodyNodePaths.unshift(astToPrepend.program.body);
132
+ },
133
+ },
134
+ };
135
+ };
@@ -0,0 +1,99 @@
1
+ export const GRAPH_VISITOR = {};
2
+
3
+ GRAPH_VISITOR.map = (graph, callback) => {
4
+ const array = [];
5
+ graph.urlInfoMap.forEach((urlInfo) => {
6
+ array.push(callback(urlInfo));
7
+ });
8
+ return array;
9
+ };
10
+ GRAPH_VISITOR.forEach = (graph, callback) => {
11
+ graph.urlInfoMap.forEach(callback);
12
+ };
13
+ GRAPH_VISITOR.filter = (graph, callback) => {
14
+ const urlInfos = [];
15
+ graph.urlInfoMap.forEach((urlInfo) => {
16
+ if (callback(urlInfo)) {
17
+ urlInfos.push(urlInfo);
18
+ }
19
+ });
20
+ return urlInfos;
21
+ };
22
+ GRAPH_VISITOR.find = (graph, callback) => {
23
+ let found = null;
24
+ for (const urlInfo of graph.urlInfoMap.values()) {
25
+ if (callback(urlInfo)) {
26
+ found = urlInfo;
27
+ break;
28
+ }
29
+ }
30
+ return found;
31
+ };
32
+ GRAPH_VISITOR.findDependent = (graph, urlInfo, visitor) => {
33
+ const seen = new Set();
34
+ seen.add(urlInfo.url);
35
+ let found = null;
36
+ const visit = (dependentUrlInfo) => {
37
+ if (seen.has(dependentUrlInfo.url)) {
38
+ return false;
39
+ }
40
+ seen.add(dependentUrlInfo.url);
41
+ if (visitor(dependentUrlInfo)) {
42
+ found = dependentUrlInfo;
43
+ }
44
+ return true;
45
+ };
46
+ const iterate = (currentUrlInfo) => {
47
+ // When cookin html inline content, html references are not yet updated
48
+ // consequently htmlUrlInfo.dependencies is empty
49
+ // and inlineContentUrlInfo.dependents is empty as well
50
+ // in that case we resort to isInline + inlineUrlSite to establish the dependency
51
+ if (currentUrlInfo.isInline) {
52
+ const parentUrl = currentUrlInfo.inlineUrlSite.url;
53
+ const parentUrlInfo = graph.getUrlInfo(parentUrl);
54
+ visit(parentUrlInfo);
55
+ if (found) {
56
+ return;
57
+ }
58
+ }
59
+ for (const dependentUrl of currentUrlInfo.dependents) {
60
+ const dependentUrlInfo = graph.getUrlInfo(dependentUrl);
61
+ if (visit(dependentUrlInfo)) {
62
+ if (found) {
63
+ break;
64
+ }
65
+ iterate(dependentUrlInfo);
66
+ }
67
+ }
68
+ };
69
+ iterate(urlInfo);
70
+ return found;
71
+ };
72
+ GRAPH_VISITOR.findDependency = (graph, urlInfo, visitor) => {
73
+ const seen = new Set();
74
+ seen.add(urlInfo.url);
75
+ let found = null;
76
+ const visit = (dependencyUrlInfo) => {
77
+ if (seen.has(dependencyUrlInfo.url)) {
78
+ return false;
79
+ }
80
+ seen.add(dependencyUrlInfo.url);
81
+ if (visitor(dependencyUrlInfo)) {
82
+ found = dependencyUrlInfo;
83
+ }
84
+ return true;
85
+ };
86
+ const iterate = (currentUrlInfo) => {
87
+ for (const dependencyUrl of currentUrlInfo.dependencies) {
88
+ const dependencyUrlInfo = graph.getUrlInfo(dependencyUrl);
89
+ if (visit(dependencyUrlInfo)) {
90
+ if (found) {
91
+ break;
92
+ }
93
+ iterate(dependencyUrlInfo);
94
+ }
95
+ }
96
+ };
97
+ iterate(urlInfo);
98
+ return found;
99
+ };
@@ -1,4 +1,5 @@
1
1
  import { pathToFileURL } from "node:url";
2
+ import { parseJsWithAcorn } from "@jsenv/ast";
2
3
  import { bufferToEtag } from "@jsenv/filesystem";
3
4
  import { urlToRelativeUrl, isFileSystemPath } from "@jsenv/urls";
4
5
  import {
@@ -65,10 +66,80 @@ export const createUrlInfoTransformer = ({
65
66
  return sourcemap;
66
67
  };
67
68
 
68
- const initTransformations = async (urlInfo, context) => {
69
- urlInfo.originalContentEtag =
70
- urlInfo.originalContentEtag ||
71
- bufferToEtag(Buffer.from(urlInfo.originalContent));
69
+ const defineGettersOnPropertiesDerivedFromContent = (urlInfo) => {
70
+ const contentAstDescriptor = Object.getOwnPropertyDescriptor(
71
+ urlInfo,
72
+ "contentAst",
73
+ );
74
+ if (contentAstDescriptor.value === undefined) {
75
+ defineVolaliteGetter(urlInfo, "contentAst", () => {
76
+ if (urlInfo.content === urlInfo.originalContent) {
77
+ return urlInfo.originalContentAst;
78
+ }
79
+ const ast = getContentAst(urlInfo.content, urlInfo.type, urlInfo.url);
80
+ return ast;
81
+ });
82
+ }
83
+ const contentEtagDescriptor = Object.getOwnPropertyDescriptor(
84
+ urlInfo,
85
+ "contentEtag",
86
+ );
87
+ if (contentEtagDescriptor.value === undefined) {
88
+ defineVolaliteGetter(urlInfo, "contentEtag", () => {
89
+ if (urlInfo.content === urlInfo.originalContent) {
90
+ return urlInfo.originalContentEtag;
91
+ }
92
+ return getContentEtag(urlInfo.content);
93
+ });
94
+ }
95
+ };
96
+
97
+ const initTransformations = async (
98
+ urlInfo,
99
+ {
100
+ content,
101
+ contentAst, // most of the time will be undefined
102
+ contentEtag, // in practice it's always undefined
103
+ originalContent,
104
+ originalContentAst, // most of the time will be undefined
105
+ originalContentEtag, // in practice always undefined
106
+ },
107
+ context,
108
+ ) => {
109
+ urlInfo.contentFinalized = false;
110
+ urlInfo.originalContentAst = originalContentAst;
111
+ urlInfo.originalContentEtag = originalContentEtag;
112
+ if (originalContent !== urlInfo.originalContent) {
113
+ urlInfo.originalContent = originalContent;
114
+ }
115
+ const originalContentAstDescriptor = Object.getOwnPropertyDescriptor(
116
+ urlInfo,
117
+ "originalContentAst",
118
+ );
119
+ if (originalContentAstDescriptor.value === undefined) {
120
+ defineVolaliteGetter(urlInfo, "originalContentAst", () => {
121
+ return getContentAst(
122
+ urlInfo.originalContent,
123
+ urlInfo.type,
124
+ urlInfo.url,
125
+ );
126
+ });
127
+ }
128
+ const originalContentEtagDescriptor = Object.getOwnPropertyDescriptor(
129
+ urlInfo,
130
+ "originalContentEtag",
131
+ );
132
+ if (originalContentEtagDescriptor.value === undefined) {
133
+ defineVolaliteGetter(urlInfo, "originalContentEtag", () => {
134
+ return bufferToEtag(Buffer.from(urlInfo.originalContent));
135
+ });
136
+ }
137
+
138
+ urlInfo.contentAst = contentAst;
139
+ urlInfo.contentEtag = contentEtag;
140
+ urlInfo.content = content;
141
+ defineGettersOnPropertiesDerivedFromContent(urlInfo);
142
+
72
143
  if (!sourcemapsEnabled) {
73
144
  return;
74
145
  }
@@ -92,7 +163,6 @@ export const createUrlInfoTransformer = ({
92
163
  generatedUrlObject.searchParams.delete("as_js_classic");
93
164
  const urlForSourcemap = generatedUrlObject.href;
94
165
  urlInfo.sourcemapGeneratedUrl = generateSourcemapFileUrl(urlForSourcemap);
95
-
96
166
  // already loaded during "load" hook (happens during build)
97
167
  if (urlInfo.sourcemap) {
98
168
  const [sourcemapReference, sourcemapUrlInfo] = injectSourcemapPlaceholder(
@@ -106,7 +176,6 @@ export const createUrlInfoTransformer = ({
106
176
  urlInfo.sourcemap = normalizeSourcemap(urlInfo, urlInfo.sourcemap);
107
177
  return;
108
178
  }
109
-
110
179
  // check for existing sourcemap for this content
111
180
  const sourcemapFound = SOURCEMAP.readComment({
112
181
  contentType: urlInfo.contentType,
@@ -139,20 +208,30 @@ export const createUrlInfoTransformer = ({
139
208
  }
140
209
  };
141
210
 
142
- const applyIntermediateTransformations = (urlInfo, transformations) => {
211
+ const applyTransformations = (urlInfo, transformations) => {
143
212
  if (!transformations) {
144
213
  return;
145
214
  }
146
- const { type, contentType, content, sourcemap, sourcemapIsWrong } =
147
- transformations;
215
+ const {
216
+ type,
217
+ contentType,
218
+ content,
219
+ contentAst, // undefined most of the time
220
+ contentEtag, // in practice always undefined
221
+ sourcemap,
222
+ sourcemapIsWrong,
223
+ } = transformations;
148
224
  if (type) {
149
225
  urlInfo.type = type;
150
226
  }
151
227
  if (contentType) {
152
228
  urlInfo.contentType = contentType;
153
229
  }
154
- if (content) {
230
+ if (content && content !== urlInfo.content) {
155
231
  urlInfo.content = content;
232
+ urlInfo.contentAst = contentAst;
233
+ urlInfo.contentEtag = contentEtag;
234
+ defineGettersOnPropertiesDerivedFromContent(urlInfo);
156
235
  }
157
236
  if (sourcemapsEnabled && sourcemap) {
158
237
  const sourcemapNormalized = normalizeSourcemap(urlInfo, sourcemap);
@@ -176,12 +255,14 @@ export const createUrlInfoTransformer = ({
176
255
  // "no sourcemap is better than wrong sourcemap"
177
256
  urlInfo.sourcemapIsWrong = urlInfo.sourcemapIsWrong || sourcemapIsWrong;
178
257
  }
179
- };
180
258
 
181
- const applyFinalTransformations = (urlInfo, transformations) => {
182
- if (transformations) {
183
- applyIntermediateTransformations(urlInfo, transformations);
259
+ if (urlInfo.contentFinalized) {
260
+ applyTransformationsEffects(urlInfo);
184
261
  }
262
+ };
263
+
264
+ const applyTransformationsEffects = (urlInfo) => {
265
+ urlInfo.contentFinalized = true;
185
266
  if (urlInfo.sourcemapReference) {
186
267
  if (
187
268
  sourcemapsEnabled &&
@@ -235,16 +316,54 @@ export const createUrlInfoTransformer = ({
235
316
  urlGraph.deleteUrlInfo(urlInfo.sourcemapReference.url);
236
317
  }
237
318
  }
238
-
239
- urlInfo.contentEtag =
240
- urlInfo.content === urlInfo.originalContent
241
- ? urlInfo.originalContentEtag
242
- : bufferToEtag(Buffer.from(urlInfo.content));
243
319
  };
244
320
 
245
321
  return {
246
322
  initTransformations,
247
- applyIntermediateTransformations,
248
- applyFinalTransformations,
323
+ applyTransformations,
324
+ applyTransformationsEffects,
249
325
  };
250
326
  };
327
+
328
+ const defineVolaliteGetter = (object, property, getter) => {
329
+ const restore = (value) => {
330
+ Object.defineProperty(object, property, {
331
+ enumerable: true,
332
+ configurable: true,
333
+ writable: true,
334
+ value,
335
+ });
336
+ };
337
+
338
+ Object.defineProperty(object, property, {
339
+ enumerable: true,
340
+ configurable: true,
341
+ get: () => {
342
+ const value = getter();
343
+ restore(value);
344
+ return value;
345
+ },
346
+ set: restore,
347
+ });
348
+ };
349
+
350
+ const getContentAst = (content, type, url) => {
351
+ if (type === "js_module") {
352
+ return parseJsWithAcorn({
353
+ js: content,
354
+ url,
355
+ isJsModule: true,
356
+ });
357
+ }
358
+ if (type === "js_classic") {
359
+ return parseJsWithAcorn({
360
+ js: content,
361
+ url,
362
+ });
363
+ }
364
+ return null;
365
+ };
366
+
367
+ const getContentEtag = (content) => {
368
+ return bufferToEtag(Buffer.from(content));
369
+ };
@@ -62,31 +62,6 @@ export const createUrlGraph = ({ name = "anonymous" } = {}) => {
62
62
  };
63
63
  return search(parentUrlInfo);
64
64
  };
65
- const findDependent = (urlInfo, visitor) => {
66
- const seen = [urlInfo.url];
67
- let found = null;
68
- const iterate = (currentUrlInfo) => {
69
- for (const dependentUrl of currentUrlInfo.dependents) {
70
- if (seen.includes(dependentUrl)) {
71
- continue;
72
- }
73
- if (found) {
74
- break;
75
- }
76
- seen.push(dependentUrl);
77
- const dependentUrlInfo = getUrlInfo(dependentUrl);
78
- if (visitor(dependentUrlInfo)) {
79
- found = dependentUrlInfo;
80
- }
81
- if (found) {
82
- break;
83
- }
84
- iterate(dependentUrlInfo);
85
- }
86
- };
87
- iterate(urlInfo);
88
- return found;
89
- };
90
65
 
91
66
  const updateReferences = (urlInfo, references) => {
92
67
  const setOfDependencyUrls = new Set();
@@ -103,11 +78,12 @@ export const createUrlGraph = ({ name = "anonymous" } = {}) => {
103
78
  }
104
79
  const dependencyUrl = reference.url;
105
80
  setOfDependencyUrls.add(dependencyUrl);
106
- // an implicit reference do not appear in the file but a non-explicited file have an impact on it
107
- // (package.json on import resolution for instance)
81
+ // an implicit reference do not appear in the file but the non explicited file
82
+ // have an impact on it
83
+ // -> package.json on import resolution for instance
108
84
  // in that case:
109
85
  // - file depends on the implicit file (it must autoreload if package.json is modified)
110
- // - cache validity for the file depends on the implicit file (it must be re-cooked in package.json is modified)
86
+ // - cache validity for the file depends on the implicit file (it must be re-cooked if package.json is modified)
111
87
  if (reference.isImplicit) {
112
88
  setOfImplicitUrls.add(dependencyUrl);
113
89
  }
@@ -207,6 +183,55 @@ export const createUrlGraph = ({ name = "anonymous" } = {}) => {
207
183
  iterate(urlInfo);
208
184
  };
209
185
 
186
+ const getEntryPoints = () => {
187
+ const entryPoints = [];
188
+ urlInfoMap.forEach((urlInfo) => {
189
+ if (urlInfo.isEntryPoint) {
190
+ entryPoints.push(urlInfo);
191
+ }
192
+ });
193
+ return entryPoints;
194
+ };
195
+
196
+ const hasDependent = (urlInfo) => {
197
+ for (const dependentUrl of urlInfo.dependents) {
198
+ const dependentUrlInfo = getUrlInfo(dependentUrl);
199
+ for (const reference of dependentUrlInfo.references) {
200
+ if (reference.url === urlInfo.url) {
201
+ if (
202
+ !reference.isInline &&
203
+ reference.next &&
204
+ reference.next.isInline
205
+ ) {
206
+ // the url info was inlined, an other reference is required
207
+ // to consider the non-inlined urlInfo as used
208
+ continue;
209
+ }
210
+ return true;
211
+ }
212
+ }
213
+ }
214
+ return false;
215
+ };
216
+
217
+ const isUsed = (urlInfo) => {
218
+ // nothing uses this url anymore
219
+ // - versioning update inline content
220
+ // - file converted for import assertion or js_classic conversion
221
+ // - urlInfo for a file that is now inlined
222
+ if (urlInfo.isEntryPoint) {
223
+ return true;
224
+ }
225
+ // if (urlInfo.type === "sourcemap") {
226
+ // return true;
227
+ // }
228
+ // check if there is a valid reference to this urlInfo
229
+ if (hasDependent(urlInfo)) {
230
+ return true;
231
+ }
232
+ return false;
233
+ };
234
+
210
235
  return {
211
236
  name,
212
237
  createUrlInfoCallbackRef,
@@ -217,11 +242,13 @@ export const createUrlGraph = ({ name = "anonymous" } = {}) => {
217
242
  getUrlInfo,
218
243
  deleteUrlInfo,
219
244
  getParentIfInline,
245
+ getEntryPoints,
246
+ hasDependent,
247
+ isUsed,
220
248
 
221
249
  inferReference,
222
250
  updateReferences,
223
251
  considerModified,
224
- findDependent,
225
252
 
226
253
  toObject: () => {
227
254
  const data = {};
@@ -269,7 +296,10 @@ const createUrlInfo = (url) => {
269
296
  filename: "",
270
297
  isEntryPoint: false,
271
298
  originalContent: undefined,
299
+ originalContentAst: undefined,
272
300
  content: undefined,
301
+ contentAst: undefined,
302
+ contentFinalized: false,
273
303
 
274
304
  sourcemap: null,
275
305
  sourcemapReference: null,
@@ -18,8 +18,7 @@ export const jsenvPluginHmr = () => {
18
18
  return urlObject.href;
19
19
  },
20
20
  transformReferenceSearchParams: (reference, context) => {
21
- if (reference.type === "package_json") {
22
- // maybe the if above shoulb be .isImplicit but it's just a detail anyway
21
+ if (reference.isImplicit) {
23
22
  return null;
24
23
  }
25
24
  if (context.reference && !context.reference.data.hmr) {
@@ -110,8 +110,8 @@ const injectImportMetaHot = (urlInfo, context, importMetaHotClientFileUrl) => {
110
110
  });
111
111
  const magicSource = createMagicSource(urlInfo.content);
112
112
  magicSource.prepend(
113
- `import { createImportMetaHot } from ${importMetaHotClientFileReference.generatedSpecifier}
114
- import.meta.hot = createImportMetaHot(import.meta.url)
113
+ `import { createImportMetaHot } from ${importMetaHotClientFileReference.generatedSpecifier};
114
+ import.meta.hot = createImportMetaHot(import.meta.url);
115
115
  `,
116
116
  );
117
117
  return magicSource.toContentAndSourcemap();
@@ -184,8 +184,8 @@ export const jsenvPluginImportmap = () => {
184
184
  columnEnd,
185
185
  });
186
186
  context.referenceUtils.becomesInline(importmapReference, {
187
- line: line - 1,
188
- column,
187
+ specifierLine: line - 1,
188
+ specifierColumn: column,
189
189
  isOriginal,
190
190
  specifier: inlineImportmapUrl,
191
191
  contentType: "application/importmap+json",
@@ -37,7 +37,7 @@ export const jsenvPluginInliningAsDataUrl = () => {
37
37
  const contentAsBase64 = Buffer.from(urlInfo.content).toString(
38
38
  "base64",
39
39
  );
40
- const specifier = DATA_URL.stringify({
40
+ let specifier = DATA_URL.stringify({
41
41
  mediaType: urlInfo.contentType,
42
42
  base64Flag: true,
43
43
  data: contentAsBase64,