@jsenv/core 27.0.0-alpha.7 → 27.0.0-alpha.70

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 (247) hide show
  1. package/dist/babel_helpers/AsyncGenerator/AsyncGenerator.js +95 -0
  2. package/dist/babel_helpers/AwaitValue/AwaitValue.js +3 -0
  3. package/dist/babel_helpers/applyDecoratorDescriptor/applyDecoratorDescriptor.js +29 -0
  4. package/dist/babel_helpers/arrayLikeToArray/arrayLikeToArray.js +9 -0
  5. package/dist/babel_helpers/arrayWithHoles/arrayWithHoles.js +4 -0
  6. package/dist/babel_helpers/arrayWithoutHoles/arrayWithoutHoles.js +5 -0
  7. package/dist/babel_helpers/assertThisInitialized/assertThisInitialized.js +8 -0
  8. package/dist/babel_helpers/asyncGeneratorDelegate/asyncGeneratorDelegate.js +52 -0
  9. package/dist/babel_helpers/asyncIterator/asyncIterator.js +78 -0
  10. package/dist/babel_helpers/asyncToGenerator/asyncToGenerator.js +39 -0
  11. package/dist/babel_helpers/awaitAsyncGenerator/awaitAsyncGenerator.js +4 -0
  12. package/dist/babel_helpers/classApplyDescriptorDestructureSet/classApplyDescriptorDestructureSet.js +24 -0
  13. package/dist/babel_helpers/classApplyDescriptorGet/classApplyDescriptorGet.js +7 -0
  14. package/dist/babel_helpers/classApplyDescriptorSet/classApplyDescriptorSet.js +14 -0
  15. package/dist/babel_helpers/classCallCheck/classCallCheck.js +5 -0
  16. package/dist/babel_helpers/classCheckPrivateStaticAccess/classCheckPrivateStaticAccess.js +5 -0
  17. package/dist/babel_helpers/classCheckPrivateStaticFieldDescriptor/classCheckPrivateStaticFieldDescriptor.js +6 -0
  18. package/dist/babel_helpers/classExtractFieldDescriptor/classExtractFieldDescriptor.js +8 -0
  19. package/dist/babel_helpers/classNameTDZError/classNameTDZError.js +4 -0
  20. package/dist/babel_helpers/classPrivateFieldDestructureSet/classPrivateFieldDestructureSet.js +6 -0
  21. package/dist/babel_helpers/classPrivateFieldGet/classPrivateFieldGet.js +6 -0
  22. package/dist/babel_helpers/classPrivateFieldLooseBase/classPrivateFieldLooseBase.js +7 -0
  23. package/dist/babel_helpers/classPrivateFieldLooseKey/classPrivateFieldLooseKey.js +5 -0
  24. package/dist/babel_helpers/classPrivateFieldSet/classPrivateFieldSet.js +7 -0
  25. package/dist/babel_helpers/classPrivateMethodGet/classPrivateMethodGet.js +7 -0
  26. package/dist/babel_helpers/classPrivateMethodSet/classPrivateMethodSet.js +3 -0
  27. package/dist/babel_helpers/classStaticPrivateFieldSpecGet/classStaticPrivateFieldSpecGet.js +8 -0
  28. package/dist/babel_helpers/classStaticPrivateFieldSpecSet/classStaticPrivateFieldSpecSet.js +9 -0
  29. package/dist/babel_helpers/classStaticPrivateMethodGet/classStaticPrivateMethodGet.js +5 -0
  30. package/dist/babel_helpers/classStaticPrivateMethodSet/classStaticPrivateMethodSet.js +3 -0
  31. package/dist/babel_helpers/construct/construct.js +15 -0
  32. package/dist/babel_helpers/createClass/createClass.js +18 -0
  33. package/dist/babel_helpers/createForOfIteratorHelper/createForOfIteratorHelper.js +63 -0
  34. package/dist/babel_helpers/createForOfIteratorHelperLoose/createForOfIteratorHelperLoose.js +22 -0
  35. package/dist/babel_helpers/createRawReactElement/createRawReactElement.js +50 -0
  36. package/dist/babel_helpers/createSuper/createSuper.js +22 -0
  37. package/dist/babel_helpers/decorate/decorate.js +622 -0
  38. package/dist/babel_helpers/defaults/defaults.js +14 -0
  39. package/dist/babel_helpers/defineEnumerableProperties/defineEnumerableProperties.js +26 -0
  40. package/dist/babel_helpers/defineProperty/defineProperty.js +19 -0
  41. package/dist/babel_helpers/extends/extends.js +16 -0
  42. package/dist/babel_helpers/get/get.js +21 -0
  43. package/dist/babel_helpers/getPrototypeOf/getPrototypeOf.js +2 -0
  44. package/dist/babel_helpers/inherits/inherits.js +21 -0
  45. package/dist/babel_helpers/inheritsLoose/inheritsLoose.js +6 -0
  46. package/dist/babel_helpers/initializerDefineProperty/initializerDefineProperty.js +10 -0
  47. package/dist/babel_helpers/initializerWarningHelper/initializerWarningHelper.js +3 -0
  48. package/dist/babel_helpers/instanceof/instanceof.js +7 -0
  49. package/dist/babel_helpers/interopRequireDefault/interopRequireDefault.js +5 -0
  50. package/dist/babel_helpers/interopRequireWildcard/interopRequireWildcard.js +49 -0
  51. package/dist/babel_helpers/isNativeFunction/isNativeFunction.js +4 -0
  52. package/dist/babel_helpers/isNativeReflectConstruct/isNativeReflectConstruct.js +21 -0
  53. package/dist/babel_helpers/iterableToArray/iterableToArray.js +3 -0
  54. package/dist/babel_helpers/iterableToArrayLimit/iterableToArrayLimit.js +38 -0
  55. package/dist/babel_helpers/iterableToArrayLimitLoose/iterableToArrayLimitLoose.js +13 -0
  56. package/dist/babel_helpers/jsx/jsx.js +49 -0
  57. package/dist/babel_helpers/maybeArrayLike/maybeArrayLike.js +10 -0
  58. package/dist/babel_helpers/newArrowCheck/newArrowCheck.js +5 -0
  59. package/dist/babel_helpers/nonIterableRest/nonIterableRest.js +3 -0
  60. package/dist/babel_helpers/nonIterableSpread/nonIterableSpread.js +3 -0
  61. package/dist/babel_helpers/objectDestructuringEmpty/objectDestructuringEmpty.js +3 -0
  62. package/dist/babel_helpers/objectSpread/objectSpread.js +22 -0
  63. package/dist/babel_helpers/objectSpread2/objectSpread2.js +41 -0
  64. package/dist/babel_helpers/objectWithoutProperties/objectWithoutProperties.js +20 -0
  65. package/dist/babel_helpers/objectWithoutPropertiesLoose/objectWithoutPropertiesLoose.js +15 -0
  66. package/dist/babel_helpers/possibleConstructorReturn/possibleConstructorReturn.js +10 -0
  67. package/dist/babel_helpers/readOnlyError/readOnlyError.js +4 -0
  68. package/dist/babel_helpers/readme.md +8 -0
  69. package/dist/babel_helpers/set/set.js +51 -0
  70. package/dist/babel_helpers/setPrototypeOf/setPrototypeOf.js +5 -0
  71. package/dist/babel_helpers/skipFirstGeneratorNext/skipFirstGeneratorNext.js +8 -0
  72. package/dist/babel_helpers/slicedToArray/slicedToArray.js +5 -0
  73. package/dist/babel_helpers/slicedToArrayLoose/slicedToArrayLoose.js +7 -0
  74. package/dist/babel_helpers/superPropBase/superPropBase.js +10 -0
  75. package/dist/babel_helpers/taggedTemplateLiteral/taggedTemplateLiteral.js +11 -0
  76. package/dist/babel_helpers/taggedTemplateLiteralLoose/taggedTemplateLiteralLoose.js +8 -0
  77. package/dist/babel_helpers/tdz/tdz.js +4 -0
  78. package/dist/babel_helpers/temporalRef/temporalRef.js +5 -0
  79. package/dist/babel_helpers/temporalUndefined/temporalUndefined.js +3 -0
  80. package/dist/babel_helpers/toArray/toArray.js +5 -0
  81. package/dist/babel_helpers/toConsumableArray/toConsumableArray.js +5 -0
  82. package/dist/babel_helpers/toPrimitive/toPrimitive.js +14 -0
  83. package/dist/babel_helpers/toPropertyKey/toPropertyKey.js +5 -0
  84. package/dist/babel_helpers/typeof/typeof.js +7 -0
  85. package/dist/babel_helpers/unsupportedIterableToArray/unsupportedIterableToArray.js +10 -0
  86. package/dist/babel_helpers/wrapAsyncGenerator/wrapAsyncGenerator.js +7 -0
  87. package/dist/babel_helpers/wrapNativeSuper/wrapNativeSuper.js +35 -0
  88. package/dist/babel_helpers/wrapRegExp/wrapRegExp.js +67 -0
  89. package/dist/babel_helpers/writeOnlyError/writeOnlyError.js +4 -0
  90. package/dist/html/explorer.html +557 -0
  91. package/dist/js/controllable_file.mjs +227 -0
  92. package/dist/js/event_source_client.js +324 -0
  93. package/dist/js/global_this.js +32 -0
  94. package/dist/js/html_supervisor_installer.js +522 -0
  95. package/dist/js/html_supervisor_setup.js +79 -0
  96. package/dist/js/import_meta_hot.js +84 -0
  97. package/dist/js/inline_content.js +8 -0
  98. package/dist/js/new_stylesheet.js +409 -0
  99. package/dist/js/regenerator_runtime.js +721 -0
  100. package/dist/js/s.js +429 -0
  101. package/dist/main.js +13452 -0
  102. package/dist/other/jsenv.png +0 -0
  103. package/dist/s.js +626 -0
  104. package/dist/s.js.map +204 -0
  105. package/main.js +9 -1
  106. package/package.json +44 -32
  107. package/readme.md +6 -14
  108. package/src/build/build.js +1080 -562
  109. package/src/build/build_urls_generator.js +65 -24
  110. package/src/build/graph_utils.js +31 -0
  111. package/src/build/{inject_version_mappings.js → inject_global_version_mappings.js} +49 -18
  112. package/src/build/inject_service_worker_urls.js +79 -0
  113. package/src/build/resync_ressource_hints.js +115 -0
  114. package/src/build/start_build_server.js +211 -0
  115. package/src/dev/plugins/explorer/client/explorer.html +1 -1
  116. package/src/dev/plugins/explorer/jsenv_plugin_explorer.js +8 -12
  117. package/src/dev/plugins/toolbar/jsenv_plugin_toolbar.js +3 -1
  118. package/src/dev/start_dev_server.js +170 -38
  119. package/src/execute/execute.js +36 -6
  120. package/src/execute/run.js +21 -57
  121. package/src/execute/runtimes/browsers/from_playwright.js +218 -148
  122. package/src/execute/runtimes/node/controllable_file.mjs +26 -10
  123. package/src/execute/runtimes/node/node_execution_performance.js +67 -0
  124. package/src/execute/runtimes/node/node_process.js +288 -39
  125. package/src/omega/{runtime_support/features_compatibility.js → compat/features_compats.js} +30 -7
  126. package/src/omega/{runtime_support/runtime_support.js → compat/runtime_compat.js} +14 -16
  127. package/src/omega/errors.js +62 -66
  128. package/src/omega/fetched_content_compliance.js +24 -0
  129. package/src/omega/file_url_converter.js +9 -51
  130. package/src/omega/kitchen.js +593 -463
  131. package/src/omega/omega_server.js +2 -3
  132. package/src/omega/server/file_service.js +86 -38
  133. package/src/omega/server/user_agent.js +4 -2
  134. package/src/omega/url_graph/url_graph_load.js +31 -23
  135. package/src/omega/url_graph/url_graph_report.js +94 -51
  136. package/src/omega/url_graph/url_info_transformations.js +37 -17
  137. package/src/omega/url_graph.js +88 -19
  138. package/src/omega/url_specifier_encoding.js +59 -0
  139. package/src/omega/web_workers.js +42 -0
  140. package/src/{dev/plugins/autoreload → plugins/autoreload/dev_sse}/client/autoreload_preference.js +0 -0
  141. package/src/{dev/plugins/autoreload → plugins/autoreload/dev_sse}/client/event_source_client.js +19 -12
  142. package/src/{dev/plugins/autoreload → plugins/autoreload/dev_sse}/client/reload.js +0 -0
  143. package/src/{dev/plugins/autoreload → plugins/autoreload/dev_sse}/client/url_helpers.js +0 -0
  144. package/src/plugins/autoreload/dev_sse/jsenv_plugin_dev_sse_client.js +41 -0
  145. package/src/plugins/autoreload/dev_sse/jsenv_plugin_dev_sse_server.js +204 -0
  146. package/src/plugins/autoreload/jsenv_plugin_autoreload.js +25 -0
  147. package/src/plugins/autoreload/jsenv_plugin_hmr.js +35 -0
  148. package/src/plugins/bundling/css/bundle_css.js +140 -0
  149. package/src/plugins/bundling/js_classic_workers/bundle_js_classic_workers.js +13 -0
  150. package/src/plugins/bundling/js_module/bundle_js_module.js +342 -0
  151. package/src/plugins/bundling/jsenv_plugin_bundling.js +54 -0
  152. package/src/plugins/cache_control/jsenv_plugin_cache_control.js +34 -0
  153. package/src/{omega/core_plugins → plugins}/commonjs_globals/jsenv_plugin_commonjs_globals.js +54 -41
  154. package/src/plugins/file_urls/jsenv_plugin_file_urls.js +198 -0
  155. package/src/{omega/core_plugins → plugins}/html_supervisor/client/error_in_document.js +0 -0
  156. package/src/{omega/core_plugins → plugins}/html_supervisor/client/error_in_notification.js +0 -0
  157. package/src/plugins/html_supervisor/client/html_supervisor_installer.js +254 -0
  158. package/src/plugins/html_supervisor/client/html_supervisor_setup.js +79 -0
  159. package/src/{omega/core_plugins → plugins}/html_supervisor/client/perf_browser.js +0 -0
  160. package/src/{omega/core_plugins → plugins}/html_supervisor/client/uneval_exception.js +0 -0
  161. package/src/{omega/core_plugins → plugins}/html_supervisor/jsenv_plugin_html_supervisor.js +73 -55
  162. package/src/plugins/http_urls/jsenv_plugin_http_urls.js +12 -0
  163. package/src/{dev/plugins/autoreload → plugins/import_meta_hot}/babel_plugin_metadata_import_meta_hot.js +4 -5
  164. package/src/{dev/plugins/autoreload → plugins/import_meta_hot}/client/import_meta_hot.js +3 -1
  165. package/src/{dev/plugins/autoreload → plugins/import_meta_hot}/html_hot_dependencies.js +7 -4
  166. package/src/plugins/import_meta_hot/jsenv_plugin_import_meta_hot.js +100 -0
  167. package/src/{omega/core_plugins → plugins}/import_meta_scenarios/jsenv_plugin_import_meta_scenarios.js +33 -8
  168. package/src/plugins/import_meta_url/client/import_meta_url_browser.js +52 -0
  169. package/src/plugins/import_meta_url/client/import_meta_url_commonjs.mjs +9 -0
  170. package/src/{omega/core_plugins → plugins}/importmap/jsenv_plugin_importmap.js +40 -36
  171. package/src/plugins/inject_globals/jsenv_plugin_inject_globals.js +76 -0
  172. package/src/{omega/core_plugins → plugins}/inline/client/inline_content.js +0 -0
  173. package/src/{omega/core_plugins → plugins}/inline/jsenv_plugin_data_urls.js +19 -18
  174. package/src/plugins/inline/jsenv_plugin_html_inline_content.js +161 -0
  175. package/src/plugins/inline/jsenv_plugin_inline.js +36 -0
  176. package/src/{omega/core_plugins → plugins}/inline/jsenv_plugin_inline_query_param.js +7 -10
  177. package/src/plugins/inline/jsenv_plugin_js_inline_content.js +294 -0
  178. package/src/plugins/leading_slash/jsenv_plugin_leading_slash.js +13 -0
  179. package/src/plugins/minification/css/minify_css.js +9 -0
  180. package/src/plugins/minification/html/minify_html.js +15 -0
  181. package/src/{build/plugins/minify_js/jsenv_plugin_minify_js.js → plugins/minification/js/minify_js.js} +6 -22
  182. package/src/plugins/minification/jsenv_plugin_minification.js +78 -0
  183. package/src/plugins/minification/json/minify_json.js +8 -0
  184. package/src/plugins/node_esm_resolution/jsenv_plugin_node_esm_resolution.js +160 -0
  185. package/src/plugins/node_runtime/jsenv_plugin_node_runtime.js +12 -0
  186. package/src/{omega → plugins}/plugin_controller.js +56 -11
  187. package/src/plugins/plugins.js +92 -0
  188. package/src/plugins/transpilation/as_js_classic/client/s.js +429 -0
  189. package/src/plugins/transpilation/as_js_classic/helpers/babel_plugin_transform_import_meta_url.js +47 -0
  190. package/src/plugins/transpilation/as_js_classic/helpers/systemjs_old.js +43 -0
  191. package/src/plugins/transpilation/as_js_classic/jsenv_plugin_as_js_classic.js +213 -0
  192. package/src/plugins/transpilation/as_js_classic/jsenv_plugin_as_js_classic_html.js +304 -0
  193. package/src/plugins/transpilation/as_js_classic/jsenv_plugin_as_js_classic_workers.js +55 -0
  194. package/src/{omega/core_plugins → plugins/transpilation}/babel/global_this/babel_plugin_global_this_as_jsenv_import.js +0 -0
  195. package/src/{omega/core_plugins → plugins/transpilation}/babel/global_this/client/global_this.js +0 -0
  196. package/src/{omega/core_plugins → plugins/transpilation}/babel/helpers/babel_plugin_babel_helpers_as_jsenv_imports.js +0 -0
  197. package/src/{omega/core_plugins → plugins/transpilation}/babel/helpers/babel_plugin_structure.js +12 -16
  198. package/src/{omega/core_plugins → plugins/transpilation}/babel/helpers/babel_plugins_compatibility.js +0 -0
  199. package/src/{omega/core_plugins → plugins/transpilation}/babel/jsenv_plugin_babel.js +39 -32
  200. package/src/{omega/core_plugins → plugins/transpilation}/babel/new_stylesheet/babel_plugin_new_stylesheet_as_jsenv_import.js +30 -6
  201. package/src/{omega/core_plugins → plugins/transpilation}/babel/new_stylesheet/client/new_stylesheet.js +0 -0
  202. package/src/{omega/core_plugins → plugins/transpilation}/babel/regenerator_runtime/babel_plugin_regenerator_runtime_as_jsenv_import.js +0 -0
  203. package/src/{omega/core_plugins → plugins/transpilation}/babel/regenerator_runtime/client/regenerator_runtime.js +0 -0
  204. package/src/plugins/transpilation/css_parcel/jsenv_plugin_css_parcel.js +18 -0
  205. package/src/plugins/transpilation/import_assertions/jsenv_plugin_import_assertions.js +184 -0
  206. package/src/plugins/transpilation/jsenv_plugin_top_level_await.js +80 -0
  207. package/src/plugins/transpilation/jsenv_plugin_transpilation.js +46 -0
  208. package/src/plugins/url_analysis/css/css_urls.js +49 -0
  209. package/src/plugins/url_analysis/html/html_urls.js +272 -0
  210. package/src/plugins/url_analysis/js/js_urls.js +68 -0
  211. package/src/plugins/url_analysis/jsenv_plugin_url_analysis.js +102 -0
  212. package/src/plugins/url_analysis/webmanifest/webmanifest_urls.js +20 -0
  213. package/src/{omega/core_plugins → plugins}/url_resolution/jsenv_plugin_url_resolution.js +9 -5
  214. package/src/plugins/url_version/jsenv_plugin_url_version.js +28 -0
  215. package/src/test/execute_plan.js +81 -44
  216. package/src/test/execute_test_plan.js +37 -24
  217. package/src/test/execution_steps.js +1 -4
  218. package/src/test/logs_file_execution.js +56 -49
  219. package/src/build/plugins/bundle_js_module/jsenv_plugin_bundle_js_module.js +0 -225
  220. package/src/build/plugins/minify_html/jsenv_plugin_minify_html.js +0 -30
  221. package/src/dev/plugins/autoreload/client/event_source_connection.js +0 -195
  222. package/src/dev/plugins/autoreload/jsenv_plugin_autoreload.js +0 -374
  223. package/src/dev/plugins/autoreload/sse_service.js +0 -149
  224. package/src/execute/runtimes/node/controlled_process.js +0 -316
  225. package/src/omega/core_plugins/babel/new_stylesheet/client/.eslintrc.cjs +0 -24
  226. package/src/omega/core_plugins/file_urls/jsenv_plugin_file_urls.js +0 -67
  227. package/src/omega/core_plugins/filesystem_magic/jsenv_plugin_filesystem_magic.js +0 -58
  228. package/src/omega/core_plugins/html_supervisor/client/html_supervisor_installer.js +0 -168
  229. package/src/omega/core_plugins/html_supervisor/client/html_supervisor_setup.js +0 -77
  230. package/src/omega/core_plugins/import_assertions/helpers/babel_plugin_metadata_import_assertions.js +0 -98
  231. package/src/omega/core_plugins/import_assertions/helpers/json_module.js +0 -12
  232. package/src/omega/core_plugins/import_assertions/helpers/text_module.js +0 -6
  233. package/src/omega/core_plugins/import_assertions/jsenv_plugin_import_assertions.js +0 -211
  234. package/src/omega/core_plugins/inline/jsenv_plugin_inline.js +0 -13
  235. package/src/omega/core_plugins/inline/jsenv_plugin_js_and_css_inside_html.js +0 -142
  236. package/src/omega/core_plugins/inline/jsenv_plugin_new_inline_content.js +0 -207
  237. package/src/omega/core_plugins/leading_slash/jsenv_plugin_leading_slash.js +0 -12
  238. package/src/omega/core_plugins/node_esm_resolution/jsenv_plugin_node_esm_resolution.js +0 -77
  239. package/src/omega/core_plugins/url_version/jsenv_plugin_url_version.js +0 -50
  240. package/src/omega/core_plugins.js +0 -39
  241. package/src/omega/runtime_support/default_runtime_support.js +0 -13
  242. package/src/omega/url_graph/url_graph_sort.js +0 -29
  243. package/src/omega/url_mentions/css_url_mentions.js +0 -63
  244. package/src/omega/url_mentions/html_url_mentions.js +0 -185
  245. package/src/omega/url_mentions/js_module_url_mentions.js +0 -91
  246. package/src/omega/url_mentions/parse_url_mentions.js +0 -37
  247. package/src/omega/url_mentions/worker_classic_url_mentions.js +0 -37
@@ -1,162 +1,222 @@
1
1
  import {
2
2
  urlIsInsideOf,
3
- writeFileSync,
4
- isFileSystemPath,
5
- fileSystemPathToUrl,
6
3
  moveUrl,
7
- fileSystemRootUrl,
8
- } from "@jsenv/filesystem"
4
+ getCallerPosition,
5
+ stringifyUrlSite,
6
+ normalizeUrl,
7
+ setUrlFilename,
8
+ } from "@jsenv/urls"
9
+ import { writeFileSync, ensureWindowsDriveLetter } from "@jsenv/filesystem"
10
+ import { createDetailedMessage } from "@jsenv/logger"
9
11
 
10
- import { stringifyUrlSite } from "@jsenv/utils/urls/url_trace.js"
12
+ import { CONTENT_TYPE } from "@jsenv/utils/content_type/content_type.js"
11
13
 
14
+ import { createPluginController } from "../plugins/plugin_controller.js"
15
+ import { urlSpecifierEncoding } from "./url_specifier_encoding.js"
12
16
  import { createUrlInfoTransformer } from "./url_graph/url_info_transformations.js"
13
- import { RUNTIME_SUPPORT } from "./runtime_support/runtime_support.js"
14
- import { fileUrlConverter } from "./file_url_converter.js"
15
- import { parseUrlMentions } from "./url_mentions/parse_url_mentions.js"
17
+ import { RUNTIME_COMPAT } from "./compat/runtime_compat.js"
16
18
  import {
17
- createResolveError,
18
- createLoadError,
19
- createParseError,
20
- createTransformError,
19
+ createResolveUrlError,
20
+ createFetchUrlContentError,
21
+ createTransformUrlContentError,
22
+ createFinalizeUrlContentError,
21
23
  } from "./errors.js"
22
- import { createPluginController } from "./plugin_controller.js"
24
+ import { assertFetchedContentCompliance } from "./fetched_content_compliance.js"
25
+ import { isWebWorkerEntryPointReference } from "./web_workers.js"
23
26
 
24
27
  export const createKitchen = ({
25
28
  signal,
26
29
  logger,
27
30
  rootDirectoryUrl,
28
31
  urlGraph,
32
+
29
33
  plugins,
30
34
  scenario,
31
-
32
35
  sourcemaps = {
33
36
  dev: "inline", // "programmatic" and "file" also allowed
34
37
  test: "inline",
35
38
  build: "none",
36
39
  }[scenario],
37
- // we don't need sources in sourcemap as long as the url in the
38
- // sourcemap uses file:/// (chrome will understand and read from filesystem)
39
- sourcemapsSources = false,
40
- loadInlineUrlInfos = (urlInfo) => {
41
- return {
42
- contentType: urlInfo.contentType,
43
- content: urlInfo.content,
44
- }
45
- },
46
-
47
- writeOnFileSystem = true,
40
+ sourcemapsSourcesContent = {
41
+ // during dev/test, chrome is able to find the sourcemap sources
42
+ // as long as they use file:// protocol in the sourcemap files
43
+ dev: false,
44
+ test: false,
45
+ build: true,
46
+ }[scenario],
47
+ sourcemapsRelativeSources,
48
+ runtimeCompat,
49
+ writeGeneratedFiles,
48
50
  }) => {
49
51
  const pluginController = createPluginController({
50
52
  plugins,
51
53
  scenario,
52
54
  })
53
55
  const jsenvDirectoryUrl = new URL(".jsenv/", rootDirectoryUrl).href
54
- const baseContext = {
56
+ const kitchenContext = {
55
57
  signal,
56
58
  logger,
57
59
  rootDirectoryUrl,
58
60
  sourcemaps,
59
61
  urlGraph,
60
62
  scenario,
63
+ runtimeCompat,
64
+ isSupportedOnFutureClients: (feature) => {
65
+ return RUNTIME_COMPAT.isSupported(runtimeCompat, feature)
66
+ },
61
67
  }
62
68
  const createReference = ({
63
69
  data = {},
70
+ node,
64
71
  trace,
65
72
  parentUrl,
66
73
  type,
67
74
  subtype,
75
+ expectedContentType,
76
+ expectedType,
77
+ expectedSubtype,
78
+ filename,
79
+ integrity,
80
+ crossorigin,
68
81
  specifier,
82
+ specifierStart,
83
+ specifierEnd,
84
+ specifierLine,
85
+ specifierColumn,
86
+ baseUrl,
87
+ isOriginalPosition,
88
+ shouldHandle,
69
89
  isInline = false,
90
+ injected = false,
91
+ isRessourceHint = false,
70
92
  content,
71
93
  contentType,
94
+ assert,
95
+ assertNode,
96
+ typePropertyNode,
72
97
  }) => {
98
+ if (typeof specifier !== "string") {
99
+ throw new TypeError(`"specifier" must be a string, got ${specifier}`)
100
+ }
73
101
  return {
102
+ original: null,
103
+ prev: null,
104
+ next: null,
74
105
  data,
106
+ node,
75
107
  trace,
76
108
  parentUrl,
77
109
  type,
78
110
  subtype,
111
+ expectedContentType,
112
+ expectedType,
113
+ expectedSubtype,
114
+ filename,
115
+ integrity,
116
+ crossorigin,
79
117
  specifier,
118
+ specifierStart,
119
+ specifierEnd,
120
+ specifierLine,
121
+ specifierColumn,
122
+ baseUrl,
123
+ isOriginalPosition,
124
+ shouldHandle,
80
125
  isInline,
126
+ injected,
127
+ isRessourceHint,
81
128
  // for inline ressources the reference contains the content
82
129
  content,
83
130
  contentType,
131
+ timing: {},
132
+ assert,
133
+ assertNode,
134
+ typePropertyNode,
84
135
  }
85
136
  }
137
+ const mutateReference = (reference, newReference) => {
138
+ reference.next = newReference
139
+ newReference.prev = reference
140
+ newReference.original = reference.original || reference
141
+ }
86
142
  const resolveReference = (reference) => {
87
143
  try {
88
- const resolvedUrl = pluginController.callHooksUntil(
89
- "resolve",
144
+ let resolvedUrl = pluginController.callHooksUntil(
145
+ "resolveUrl",
90
146
  reference,
91
- baseContext,
147
+ kitchenContext,
92
148
  )
93
149
  if (!resolvedUrl) {
94
150
  throw new Error(`NO_RESOLVE`)
95
151
  }
152
+ resolvedUrl = normalizeUrl(resolvedUrl)
96
153
  reference.url = resolvedUrl
97
154
  pluginController.callHooks(
98
- "normalize",
155
+ "redirectUrl",
99
156
  reference,
100
- baseContext,
157
+ kitchenContext,
101
158
  (returnValue) => {
102
- reference.url = returnValue
159
+ const normalizedReturnValue = normalizeUrl(returnValue)
160
+ if (normalizedReturnValue === reference.url) {
161
+ return
162
+ }
163
+ const previousReference = { ...reference }
164
+ reference.url = normalizedReturnValue
165
+ mutateReference(previousReference, reference)
103
166
  },
104
167
  )
105
- // force a last normalization regarding on url search params
106
- // some plugin use URLSearchParams to alter the url search params
107
- // which can result into "file:///file.css?css_module"
108
- // becoming "file:///file.css?css_module="
109
- // we want to get rid of the "=" and consider it's the same url
110
- if (
111
- // disable on data urls (would mess up base64 encoding)
112
- !reference.url.startsWith("data:")
113
- ) {
114
- reference.url = reference.url.replace(/[=](?=&|$)/g, "")
115
- }
168
+
116
169
  const urlInfo = urlGraph.reuseOrCreateUrlInfo(reference.url)
117
- Object.assign(urlInfo.data, reference.data)
170
+ applyReferenceEffectsOnUrlInfo(reference, urlInfo, kitchenContext)
118
171
 
119
- // create a copy because .url will be mutated
120
- const referencedCopy = {
121
- ...reference,
122
- data: urlInfo.data,
123
- }
172
+ const referenceUrlObject = new URL(reference.url)
173
+ reference.searchParams = referenceUrlObject.searchParams
174
+ reference.generatedUrl = reference.url
175
+ // This hook must touch reference.generatedUrl, NOT reference.url
176
+ // And this is because this hook inject query params used to:
177
+ // - bypass browser cache (?v)
178
+ // - convey information (?hmr)
179
+ // But do not represent an other ressource, it is considered as
180
+ // the same ressource under the hood
124
181
  pluginController.callHooks(
125
- "transformReferencedUrl",
126
- referencedCopy,
127
- baseContext,
182
+ "transformUrlSearchParams",
183
+ reference,
184
+ kitchenContext,
128
185
  (returnValue) => {
129
- referencedCopy.url = returnValue
186
+ Object.keys(returnValue).forEach((key) => {
187
+ referenceUrlObject.searchParams.set(key, returnValue[key])
188
+ })
189
+ reference.generatedUrl = normalizeUrl(referenceUrlObject.href)
130
190
  },
131
191
  )
132
- reference.generatedUrl = referencedCopy.url
133
192
  const returnValue = pluginController.callHooksUntil(
134
- "formatReferencedUrl",
135
- referencedCopy,
136
- baseContext,
193
+ "formatUrl",
194
+ reference,
195
+ kitchenContext,
137
196
  )
138
197
  reference.generatedSpecifier = returnValue || reference.generatedUrl
139
- reference.generatedSpecifier = specifierFormat.encode(reference)
198
+ reference.generatedSpecifier = urlSpecifierEncoding.encode(reference)
140
199
  return urlInfo
141
200
  } catch (error) {
142
- throw createResolveError({
201
+ throw createResolveUrlError({
143
202
  pluginController,
144
203
  reference,
145
204
  error,
146
205
  })
147
206
  }
148
207
  }
208
+ kitchenContext.resolveReference = resolveReference
149
209
  const urlInfoTransformer = createUrlInfoTransformer({
150
210
  logger,
151
211
  urlGraph,
152
212
  sourcemaps,
153
- sourcemapsSources,
213
+ sourcemapsSourcesContent,
214
+ sourcemapsRelativeSources,
154
215
  injectSourcemapPlaceholder: ({ urlInfo, specifier }) => {
155
216
  const sourcemapReference = createReference({
156
217
  trace: `sourcemap comment placeholder for ${urlInfo.url}`,
157
218
  type: "sourcemap_comment",
158
- subtype:
159
- urlInfo.contentType === "application/javascript" ? "js" : "css",
219
+ subtype: urlInfo.contentType === "text/javascript" ? "js" : "css",
160
220
  parentUrl: urlInfo.url,
161
221
  specifier,
162
222
  })
@@ -164,19 +224,27 @@ export const createKitchen = ({
164
224
  sourcemapUrlInfo.type = "sourcemap"
165
225
  return [sourcemapReference, sourcemapUrlInfo]
166
226
  },
167
- foundSourcemap: ({ urlInfo, line, column, type, specifier }) => {
227
+ foundSourcemap: ({
228
+ urlInfo,
229
+ type,
230
+ specifier,
231
+ specifierLine,
232
+ specifierColumn,
233
+ }) => {
168
234
  const sourcemapReference = createReference({
169
235
  trace: stringifyUrlSite(
170
236
  adjustUrlSite(urlInfo, {
171
237
  urlGraph,
172
238
  url: urlInfo.url,
173
- line,
174
- column,
239
+ line: specifierLine,
240
+ column: specifierColumn,
175
241
  }),
176
242
  ),
177
243
  type,
178
244
  parentUrl: urlInfo.url,
179
245
  specifier,
246
+ specifierLine,
247
+ specifierColumn,
180
248
  })
181
249
  const sourcemapUrlInfo = resolveReference(sourcemapReference)
182
250
  sourcemapUrlInfo.type = "sourcemap"
@@ -184,61 +252,71 @@ export const createKitchen = ({
184
252
  },
185
253
  })
186
254
 
187
- const load = async ({ reference, urlInfo, context }) => {
255
+ const fetchUrlContent = async (urlInfo, { reference, context }) => {
188
256
  try {
189
- const loadReturnValue = urlInfo.isInline
190
- ? loadInlineUrlInfos(urlInfo)
191
- : await pluginController.callAsyncHooksUntil("load", urlInfo, context)
192
- if (!loadReturnValue) {
193
- throw new Error("NO_LOAD")
257
+ const fetchUrlContentReturnValue =
258
+ await pluginController.callAsyncHooksUntil(
259
+ "fetchUrlContent",
260
+ urlInfo,
261
+ context,
262
+ )
263
+ if (!fetchUrlContentReturnValue) {
264
+ logger.warn(
265
+ createDetailedMessage(
266
+ `no plugin has handled url during "fetchUrlContent" hook -> url will be ignored`,
267
+ {
268
+ "url": urlInfo.url,
269
+ "url reference trace": reference.trace,
270
+ },
271
+ ),
272
+ )
273
+ return
194
274
  }
195
-
196
275
  const {
197
- contentType = "application/octet-stream",
198
- content, // can be a buffer (used for binary files) or a string
199
- sourcemap,
200
- // during build urls info are reused and load returns originalContent
201
- // that we want to keep
202
- originalContent = content,
203
276
  data,
204
- } = loadReturnValue
205
- Object.assign(urlInfo, {
206
- contentType,
277
+ type,
278
+ subtype,
279
+ contentType = "application/octet-stream",
280
+ originalUrl,
207
281
  originalContent,
208
282
  content,
209
283
  sourcemap,
210
- })
284
+ filename,
285
+ } = fetchUrlContentReturnValue
286
+ urlInfo.type =
287
+ type ||
288
+ reference.expectedType ||
289
+ inferUrlInfoType({
290
+ url: urlInfo.url,
291
+ contentType,
292
+ })
293
+ urlInfo.subtype =
294
+ subtype ||
295
+ reference.expectedSubtype ||
296
+ inferUrlInfoSubtype({
297
+ url: urlInfo.url,
298
+ type: urlInfo.type,
299
+ subtype: urlInfo.subtype,
300
+ })
301
+ urlInfo.contentType = contentType
302
+ // during build urls info are reused and load returns originalUrl/originalContent
303
+ urlInfo.originalUrl = originalUrl || urlInfo.originalUrl
304
+ urlInfo.originalContent =
305
+ originalContent === undefined ? content : originalContent
306
+ urlInfo.content = content
307
+ urlInfo.sourcemap = sourcemap
211
308
  if (data) {
212
309
  Object.assign(urlInfo.data, data)
213
310
  }
214
- if (!urlInfo.type) {
215
- const type = inferUrlInfoType(urlInfo)
216
- if (type === "js") {
217
- const urlObject = new URL(urlInfo.url)
218
- if (urlObject.searchParams.has("worker_type_classic")) {
219
- urlInfo.type = "js_classic"
220
- urlInfo.subtype = "worker"
221
- } else if (
222
- urlObject.searchParams.has("service_worker_type_classic")
223
- ) {
224
- urlInfo.type = "js_classic"
225
- urlInfo.subtype = "service_worker"
226
- } else if (urlObject.searchParams.has("js_classic")) {
227
- urlInfo.type = "js_classic"
228
- } else {
229
- urlInfo.type = "js_module"
230
- }
231
- if (urlObject.searchParams.has("worker")) {
232
- urlInfo.subtype = "worker"
233
- } else if (urlObject.searchParams.has("service_worker")) {
234
- urlInfo.subtype = "service_worker"
235
- }
236
- } else {
237
- urlInfo.type = type
238
- }
311
+ if (filename) {
312
+ urlInfo.filename = filename
239
313
  }
314
+ assertFetchedContentCompliance({
315
+ reference,
316
+ urlInfo,
317
+ })
240
318
  } catch (error) {
241
- throw createLoadError({
319
+ throw createFetchUrlContentError({
242
320
  pluginController,
243
321
  urlInfo,
244
322
  reference,
@@ -246,270 +324,239 @@ export const createKitchen = ({
246
324
  })
247
325
  }
248
326
  urlInfo.generatedUrl = determineFileUrlForOutDirectory({
249
- rootDirectoryUrl,
250
- outDirectoryUrl: context.outDirectoryUrl,
251
- url: urlInfo.url,
327
+ urlInfo,
328
+ context,
252
329
  })
253
330
  await urlInfoTransformer.initTransformations(urlInfo, context)
254
331
  }
255
332
 
256
- const _cook = async ({
257
- reference,
258
- urlInfo,
259
- outDirectoryUrl,
260
- runtimeSupport,
261
- cookDuringCook = cook,
262
- }) => {
333
+ const _cook = async (urlInfo, dishContext) => {
334
+ // during dev/test clientRuntimeCompat is a single runtime
335
+ // during build clientRuntimeCompat is runtimeCompat
336
+ const { clientRuntimeCompat = runtimeCompat } = dishContext
337
+ kitchenContext.isSupportedOnCurrentClients = (feature) => {
338
+ return RUNTIME_COMPAT.isSupported(clientRuntimeCompat, feature)
339
+ }
263
340
  const context = {
264
- ...baseContext,
265
- reference,
266
- outDirectoryUrl,
267
- runtimeSupport,
268
- isSupportedOnRuntime: (feature) => {
269
- return RUNTIME_SUPPORT.isSupported(runtimeSupport, feature)
270
- },
271
- cook: (params) => {
272
- return cookDuringCook({
273
- outDirectoryUrl,
274
- runtimeSupport,
275
- ...params,
276
- })
277
- },
278
- load: (params) => {
279
- return load({
280
- context,
281
- ...params,
282
- })
283
- },
341
+ ...kitchenContext,
342
+ ...dishContext,
343
+ clientRuntimeCompat,
284
344
  }
285
-
286
- // "load" hook
287
- await load({ reference, urlInfo, context })
288
-
289
- // parsing
290
- const references = []
291
- const addReference = (props) => {
292
- const reference = createReference({
293
- parentUrl: urlInfo.url,
294
- ...props,
345
+ const { cookDuringCook = cook } = dishContext
346
+ context.cook = (urlInfo, nestedDishContext) => {
347
+ return cookDuringCook(urlInfo, {
348
+ outDirectoryUrl: dishContext.outDirectoryUrl,
349
+ clientRuntimeCompat: dishContext.clientRuntimeCompat,
350
+ ...nestedDishContext,
295
351
  })
296
- references.push(reference)
297
- return [reference, resolveReference(reference)]
298
352
  }
299
- const referenceUtils = {
300
- inject: ({ trace, ...rest }) => {
301
- if (trace === undefined) {
302
- const { prepareStackTrace } = Error
303
- Error.prepareStackTrace = (error, stack) => {
304
- Error.prepareStackTrace = prepareStackTrace
305
- return stack
353
+ context.fetchUrlContent = (urlInfo, { reference }) => {
354
+ return fetchUrlContent(urlInfo, { reference, context })
355
+ }
356
+
357
+ if (urlInfo.shouldHandle) {
358
+ // "fetchUrlContent" hook
359
+ await fetchUrlContent(urlInfo, { reference: context.reference, context })
360
+
361
+ // parsing
362
+ const references = []
363
+ const addReference = (props) => {
364
+ const reference = createReference({
365
+ parentUrl: urlInfo.url,
366
+ ...props,
367
+ })
368
+ references.push(reference)
369
+ const referencedUrlInfo = resolveReference(reference)
370
+ return [reference, referencedUrlInfo]
371
+ }
372
+ const referenceUtils = {
373
+ readGeneratedSpecifier: async (reference) => {
374
+ // "formatReferencedUrl" can be async BUT this is an exception
375
+ // for most cases it will be sync. We want to favor the sync signature to keep things simpler
376
+ // The only case where it needs to be async is when
377
+ // the specifier is a `data:*` url
378
+ // in this case we'll wait for the promise returned by
379
+ // "formatReferencedUrl"
380
+ if (reference.generatedSpecifier.then) {
381
+ return reference.generatedSpecifier.then((value) => {
382
+ reference.generatedSpecifier = value
383
+ return value
384
+ })
385
+ }
386
+ return reference.generatedSpecifier
387
+ },
388
+ found: ({ trace, ...rest }) => {
389
+ if (trace === undefined) {
390
+ trace = stringifyUrlSite(
391
+ adjustUrlSite(urlInfo, {
392
+ urlGraph,
393
+ url: urlInfo.url,
394
+ line: rest.specifierLine,
395
+ column: rest.specifierColumn,
396
+ }),
397
+ )
306
398
  }
307
- const { stack } = new Error()
308
- const callerCallsite = stack[1]
309
- const fileName = callerCallsite.getFileName()
310
- trace = stringifyUrlSite({
311
- url:
312
- fileName && isFileSystemPath(fileName)
313
- ? fileSystemPathToUrl(fileName)
314
- : fileName,
315
- line: callerCallsite.getLineNumber(),
316
- column: callerCallsite.getColumnNumber(),
399
+ // console.log(trace)
400
+ return addReference({
401
+ trace,
402
+ ...rest,
317
403
  })
318
- }
319
- return addReference({
320
- trace,
321
- ...rest,
322
- })
323
- },
324
- foundInline: ({
325
- type,
326
- isOriginal,
327
- line,
328
- column,
329
- specifier,
330
- contentType,
331
- content,
332
- }) => {
333
- const parentUrl = isOriginal ? urlInfo.url : urlInfo.generatedUrl
334
- const parentContent = isOriginal
335
- ? urlInfo.originalContent
336
- : urlInfo.content
337
- const [inlineReference, inlineUrlInfo] = addReference({
338
- trace: stringifyUrlSite({
339
- url: parentUrl,
340
- content: parentContent,
404
+ },
405
+ foundInline: ({ isOriginalPosition, line, column, ...rest }) => {
406
+ const parentUrl = isOriginalPosition
407
+ ? urlInfo.url
408
+ : urlInfo.generatedUrl
409
+ const parentContent = isOriginalPosition
410
+ ? urlInfo.originalContent
411
+ : urlInfo.content
412
+ return addReference({
413
+ trace: stringifyUrlSite({
414
+ url: parentUrl,
415
+ content: parentContent,
416
+ line,
417
+ column,
418
+ }),
419
+ isOriginalPosition,
341
420
  line,
342
421
  column,
343
- }),
344
- type,
345
- specifier,
346
- isInline: true,
347
- contentType,
348
- content,
349
- })
350
- inlineUrlInfo.isInline = true
351
- inlineUrlInfo.inlineUrlSite = {
352
- url: urlInfo.url,
353
- content: parentContent,
354
- line,
355
- column,
356
- }
357
- inlineUrlInfo.contentType = contentType
358
- inlineUrlInfo.originalContent = inlineUrlInfo.content = content
359
- return [inlineReference, inlineUrlInfo]
360
- },
361
- updateSpecifier: (generatedSpecifier, newSpecifier, data) => {
362
- const index = references.findIndex(
363
- (ref) => ref.generatedSpecifier === generatedSpecifier,
364
- )
365
- if (index === -1) {
366
- throw new Error(
367
- `Cannot find a reference for the following generatedSpecifier "${generatedSpecifier}"`,
422
+ isInline: true,
423
+ ...rest,
424
+ })
425
+ },
426
+ update: (currentReference, newReferenceParams) => {
427
+ const index = references.indexOf(currentReference)
428
+ if (index === -1) {
429
+ throw new Error(`reference do not exists`)
430
+ }
431
+ const previousReference = currentReference
432
+ const nextReference = createReference({
433
+ ...previousReference,
434
+ ...newReferenceParams,
435
+ })
436
+ references[index] = nextReference
437
+ mutateReference(previousReference, nextReference)
438
+ const newUrlInfo = resolveReference(nextReference)
439
+ const currentUrlInfo = context.urlGraph.getUrlInfo(
440
+ currentReference.url,
368
441
  )
369
- }
370
- const referenceFound = references[index]
371
- const newReference = createReference({
372
- ...referenceFound,
373
- specifier: newSpecifier,
374
- data: {
375
- ...referenceFound.data,
376
- ...data,
442
+ if (
443
+ currentUrlInfo &&
444
+ currentUrlInfo !== newUrlInfo &&
445
+ currentUrlInfo.dependents.size === 0
446
+ ) {
447
+ context.urlGraph.deleteUrlInfo(currentReference.url)
448
+ }
449
+ return [nextReference, newUrlInfo]
450
+ },
451
+ becomesInline: (
452
+ reference,
453
+ {
454
+ isOriginalPosition,
455
+ specifier,
456
+ specifierLine,
457
+ specifierColumn,
458
+ contentType,
459
+ content,
377
460
  },
378
- })
379
- references[index] = newReference
380
- newReference.data.originalReference = referenceFound
381
- const newUrlInfo = resolveReference(newReference)
382
- return [newReference, newUrlInfo]
383
- },
384
- becomesInline: (
385
- reference,
386
- { isOriginal, line, column, specifier, contentType, content },
387
- ) => {
388
- const parentUrl = isOriginal ? urlInfo.url : urlInfo.generatedUrl
389
- const parentContent = isOriginal
390
- ? urlInfo.originalContent
391
- : urlInfo.content
392
- reference.trace = stringifyUrlSite({
393
- url: parentUrl,
394
- content: parentContent,
395
- line,
396
- column,
397
- })
398
- reference.isInline = true
399
- reference.specifier = specifier
400
- reference.contentType = contentType
401
- reference.content = content
402
- const inlineUrlInfo = resolveReference(reference)
403
- inlineUrlInfo.isInline = true
404
- inlineUrlInfo.inlineUrlSite = {
405
- url: urlInfo.url,
406
- content: parentContent,
407
- line,
408
- column,
409
- }
410
- inlineUrlInfo.contentType = contentType
411
- inlineUrlInfo.content = content
412
- return reference
413
- },
414
- }
415
-
416
- let parseResult
417
- try {
418
- parseResult = await parseUrlMentions({
419
- type: urlInfo.type,
420
- url: urlInfo.data.sourceUrl || urlInfo.url,
421
- generatedUrl: urlInfo.generatedUrl,
422
- content: urlInfo.content,
423
- })
424
- } catch (error) {
425
- throw createParseError({
426
- reference,
427
- urlInfo,
428
- error,
429
- })
430
- }
431
- if (parseResult) {
432
- Object.assign(urlInfo.data, parseResult.data)
433
- const { urlMentions, replaceUrls } = parseResult
434
- for (const urlMention of urlMentions) {
435
- const [reference] = addReference({
436
- trace: stringifyUrlSite(
437
- adjustUrlSite(urlInfo, {
438
- urlGraph,
439
- url: urlInfo.url,
440
- line: urlMention.line,
441
- column: urlMention.column,
461
+ ) => {
462
+ const parentUrl = isOriginalPosition
463
+ ? urlInfo.url
464
+ : urlInfo.generatedUrl
465
+ const parentContent = isOriginalPosition
466
+ ? urlInfo.originalContent
467
+ : urlInfo.content
468
+ return referenceUtils.update(reference, {
469
+ trace: stringifyUrlSite({
470
+ url: parentUrl,
471
+ content: parentContent,
472
+ line: specifierLine,
473
+ column: specifierColumn,
442
474
  }),
443
- ),
444
- type: urlMention.type,
445
- subtype: urlMention.subtype,
446
- specifier: urlMention.specifier,
447
- })
448
- urlMention.reference = reference
475
+ isOriginalPosition,
476
+ isInline: true,
477
+ specifier,
478
+ specifierLine,
479
+ specifierColumn,
480
+ contentType,
481
+ content,
482
+ })
483
+ },
484
+ inject: ({ trace, ...rest }) => {
485
+ if (trace === undefined) {
486
+ const { url, line, column } = getCallerPosition()
487
+ trace = stringifyUrlSite({
488
+ url,
489
+ line,
490
+ column,
491
+ })
492
+ }
493
+ return addReference({
494
+ trace,
495
+ injected: true,
496
+ ...rest,
497
+ })
498
+ },
499
+ findByGeneratedSpecifier: (generatedSpecifier) => {
500
+ const reference = references.find(
501
+ (ref) => ref.generatedSpecifier === generatedSpecifier,
502
+ )
503
+ if (!reference) {
504
+ throw new Error(
505
+ `No reference found using the following generatedSpecifier: "${generatedSpecifier}"`,
506
+ )
507
+ }
508
+ return reference
509
+ },
449
510
  }
450
- if (references.length) {
451
- // "formatReferencedUrl" can be async BUT this is an exception
452
- // for most cases it will be sync. We want to favor the sync signature to keep things simpler
453
- // The only case where it needs to be async is when
454
- // the specifier is a `data:*` url
455
- // in this case we'll wait for the promise returned by
456
- // "formatReferencedUrl"
457
- await Promise.all(
458
- references.map(async (reference) => {
459
- if (reference.generatedSpecifier.then) {
460
- const value = await reference.generatedSpecifier
461
- reference.generatedSpecifier = value
462
- }
463
- }),
511
+
512
+ // "transform" hook
513
+ urlInfo.references = references
514
+ context.referenceUtils = referenceUtils
515
+ try {
516
+ await pluginController.callAsyncHooks(
517
+ "transformUrlContent",
518
+ urlInfo,
519
+ context,
520
+ async (transformReturnValue) => {
521
+ await urlInfoTransformer.applyIntermediateTransformations(
522
+ urlInfo,
523
+ transformReturnValue,
524
+ )
525
+ },
464
526
  )
465
- const replaceReturnValue = await replaceUrls((urlMention) => {
466
- return urlMention.reference.generatedSpecifier
527
+ } catch (error) {
528
+ throw createTransformUrlContentError({
529
+ pluginController,
530
+ reference: context.reference,
531
+ urlInfo,
532
+ error,
467
533
  })
468
- await urlInfoTransformer.applyIntermediateTransformations(
534
+ }
535
+ // after "transform" all references from originalContent
536
+ // and the one injected by plugin are known
537
+ urlGraph.updateReferences(urlInfo, references)
538
+
539
+ // "finalize" hook
540
+ try {
541
+ const finalizeReturnValue = await pluginController.callAsyncHooksUntil(
542
+ "finalizeUrlContent",
543
+ urlInfo,
544
+ context,
545
+ )
546
+ await urlInfoTransformer.applyFinalTransformations(
469
547
  urlInfo,
470
- replaceReturnValue,
548
+ finalizeReturnValue,
471
549
  )
550
+ } catch (error) {
551
+ throw createFinalizeUrlContentError({
552
+ pluginController,
553
+ reference: context.reference,
554
+ urlInfo,
555
+ error,
556
+ })
472
557
  }
473
558
  }
474
559
 
475
- // "transform" hook
476
- urlInfo.references = references
477
- context.referenceUtils = referenceUtils
478
- try {
479
- await pluginController.callAsyncHooks(
480
- "transform",
481
- urlInfo,
482
- context,
483
- async (transformReturnValue) => {
484
- await urlInfoTransformer.applyIntermediateTransformations(
485
- urlInfo,
486
- transformReturnValue,
487
- )
488
- },
489
- )
490
- } catch (error) {
491
- throw createTransformError({
492
- pluginController,
493
- reference,
494
- urlInfo,
495
- error,
496
- })
497
- }
498
- // after "transform" all references from originalContent
499
- // and the one injected by plugin are known
500
- urlGraph.updateReferences(urlInfo, references)
501
-
502
- // "finalize" hook
503
- const finalizeReturnValue = await pluginController.callHooksUntil(
504
- "finalize",
505
- urlInfo,
506
- context,
507
- )
508
- await urlInfoTransformer.applyFinalTransformations(
509
- urlInfo,
510
- finalizeReturnValue,
511
- )
512
-
513
560
  // "cooked" hook
514
561
  pluginController.callHooks(
515
562
  "cooked",
@@ -532,53 +579,163 @@ export const createKitchen = ({
532
579
  },
533
580
  )
534
581
  }
535
- const cook = async ({ urlInfo, outDirectoryUrl, ...rest }) => {
536
- outDirectoryUrl = outDirectoryUrl ? String(outDirectoryUrl) : undefined
537
-
538
- const writeFiles = ({ gotError }) => {
539
- if (!writeOnFileSystem || !outDirectoryUrl) {
540
- return
541
- }
582
+ const cook = memoizeCook(async (urlInfo, context) => {
583
+ if (!writeGeneratedFiles || !context.outDirectoryUrl) {
584
+ await _cook(urlInfo, context)
585
+ return
586
+ }
587
+ // writing result inside ".jsenv" directory (debug purposes)
588
+ try {
589
+ await _cook(urlInfo, context)
590
+ } finally {
542
591
  const { generatedUrl } = urlInfo
543
- // writing result inside ".jsenv" directory (debug purposes)
544
- if (!generatedUrl || !generatedUrl.startsWith("file:")) {
545
- return
546
- }
547
- // use writeSync to avoid concurrency on writing the file
548
- const write = gotError ? writeFileSync : writeFileSync
549
- write(new URL(generatedUrl), urlInfo.content)
550
- const { sourcemapGeneratedUrl, sourcemap } = urlInfo
551
- if (sourcemapGeneratedUrl && sourcemap) {
552
- write(
553
- new URL(sourcemapGeneratedUrl),
554
- JSON.stringify(sourcemap, null, " "),
555
- )
592
+ if (generatedUrl && generatedUrl.startsWith("file:")) {
593
+ if (urlInfo.type === "directory") {
594
+ // no need to write the directory
595
+ } else {
596
+ writeFileSync(new URL(generatedUrl), urlInfo.content)
597
+ const { sourcemapGeneratedUrl, sourcemap } = urlInfo
598
+ if (sourcemapGeneratedUrl && sourcemap) {
599
+ writeFileSync(
600
+ new URL(sourcemapGeneratedUrl),
601
+ JSON.stringify(sourcemap, null, " "),
602
+ )
603
+ }
604
+ }
556
605
  }
557
606
  }
607
+ })
608
+ kitchenContext.fetchUrlContent = fetchUrlContent
609
+ kitchenContext.cook = cook
558
610
 
559
- try {
560
- await _cook({
561
- urlInfo,
562
- outDirectoryUrl,
563
- ...rest,
564
- })
565
- writeFiles({ gotError: false })
566
- } catch (e) {
567
- writeFiles({ gotError: true })
568
- throw e
569
- }
611
+ const prepareEntryPoint = (params) => {
612
+ const entryReference = createReference(params)
613
+ const entryUrlInfo = resolveReference(entryReference)
614
+ return [entryReference, entryUrlInfo]
570
615
  }
571
616
 
572
- baseContext.cook = cook
617
+ const injectReference = (params) => {
618
+ const ref = createReference(params)
619
+ const urlInfo = resolveReference(ref)
620
+ return [ref, urlInfo]
621
+ }
622
+
623
+ const fetchOriginalUrlInfo = async ({
624
+ urlInfo,
625
+ context,
626
+ searchParam,
627
+ expectedType,
628
+ }) => {
629
+ const urlObject = new URL(urlInfo.url)
630
+ const { searchParams } = urlObject
631
+ if (!searchParams.has(searchParam)) {
632
+ return null
633
+ }
634
+ searchParams.delete(searchParam)
635
+ const originalUrl = urlObject.href
636
+ const originalReference = {
637
+ ...(context.reference.original || context.reference),
638
+ expectedType,
639
+ }
640
+ originalReference.url = originalUrl
641
+ const originalUrlInfo = context.urlGraph.reuseOrCreateUrlInfo(
642
+ originalReference.url,
643
+ )
644
+ if (originalUrlInfo.originalUrl === undefined) {
645
+ applyReferenceEffectsOnUrlInfo(
646
+ originalReference,
647
+ originalUrlInfo,
648
+ context,
649
+ )
650
+ }
651
+ await context.fetchUrlContent(originalUrlInfo, {
652
+ reference: originalReference,
653
+ })
654
+ if (originalUrlInfo.dependents.size === 0) {
655
+ context.urlGraph.deleteUrlInfo(originalUrlInfo.url)
656
+ }
657
+ return originalUrlInfo
658
+ }
659
+ kitchenContext.fetchOriginalUrlInfo = fetchOriginalUrlInfo
573
660
 
574
661
  return {
575
662
  pluginController,
576
663
  urlInfoTransformer,
577
664
  rootDirectoryUrl,
578
665
  jsenvDirectoryUrl,
579
- createReference,
580
- resolveReference,
666
+ kitchenContext,
581
667
  cook,
668
+ prepareEntryPoint,
669
+ injectReference,
670
+ }
671
+ }
672
+
673
+ const memoizeCook = (cook) => {
674
+ const pendingDishes = new Map()
675
+ return async (urlInfo, context) => {
676
+ const { url, modifiedTimestamp } = urlInfo
677
+ const pendingDish = pendingDishes.get(url)
678
+ if (pendingDish) {
679
+ if (!modifiedTimestamp) {
680
+ await pendingDish.promise
681
+ return
682
+ }
683
+ if (pendingDish.timestamp > modifiedTimestamp) {
684
+ await pendingDish.promise
685
+ return
686
+ }
687
+ pendingDishes.delete(url)
688
+ }
689
+ const timestamp = Date.now()
690
+ const promise = cook(urlInfo, context)
691
+ pendingDishes.set(url, {
692
+ timestamp,
693
+ promise,
694
+ })
695
+ try {
696
+ await promise
697
+ } finally {
698
+ pendingDishes.delete(url)
699
+ }
700
+ }
701
+ }
702
+
703
+ const applyReferenceEffectsOnUrlInfo = (reference, urlInfo, context) => {
704
+ if (reference.shouldHandle) {
705
+ urlInfo.shouldHandle = true
706
+ }
707
+ urlInfo.originalUrl = urlInfo.originalUrl || reference.url
708
+
709
+ Object.assign(urlInfo.data, reference.data)
710
+ Object.assign(urlInfo.timing, reference.timing)
711
+ if (reference.injected) {
712
+ urlInfo.data.injected = true
713
+ }
714
+ if (reference.filename) {
715
+ urlInfo.filename = reference.filename
716
+ }
717
+ if (reference.isInline) {
718
+ urlInfo.isInline = true
719
+ const parentUrlInfo = context.urlGraph.getUrlInfo(reference.parentUrl)
720
+ urlInfo.inlineUrlSite = {
721
+ url: parentUrlInfo.url,
722
+ content: reference.isOriginalPosition
723
+ ? parentUrlInfo.originalContent
724
+ : parentUrlInfo.content,
725
+ line: reference.specifierLine,
726
+ column: reference.specifierColumn,
727
+ }
728
+ urlInfo.contentType = reference.contentType
729
+ urlInfo.originalContent =
730
+ context === "build"
731
+ ? urlInfo.originalContent === undefined
732
+ ? reference.content
733
+ : urlInfo.originalContent
734
+ : reference.content
735
+ urlInfo.content = reference.content
736
+ }
737
+ if (isWebWorkerEntryPointReference(reference)) {
738
+ urlInfo.data.isWebWorkerEntryPoint = true
582
739
  }
583
740
  }
584
741
 
@@ -616,104 +773,77 @@ const adjustUrlSite = (urlInfo, { urlGraph, url, line, column }) => {
616
773
  )
617
774
  }
618
775
 
619
- const inferUrlInfoType = ({ contentType }) => {
776
+ const inferUrlInfoType = ({ url, contentType }) => {
620
777
  if (contentType === "text/html") {
621
778
  return "html"
622
779
  }
623
780
  if (contentType === "text/css") {
624
781
  return "css"
625
782
  }
626
- if (contentType === "application/javascript") {
627
- return "js"
628
- }
629
- if (contentType === "application/json") {
630
- return "json"
783
+ if (contentType === "text/javascript") {
784
+ const urlObject = new URL(url)
785
+ if (urlObject.searchParams.has("js_classic")) {
786
+ return "js_classic"
787
+ }
788
+ return "js_module"
631
789
  }
632
790
  if (contentType === "application/importmap+json") {
633
791
  return "importmap"
634
792
  }
635
- return "other"
636
- }
637
-
638
- const determineFileUrlForOutDirectory = ({
639
- rootDirectoryUrl,
640
- outDirectoryUrl,
641
- url,
642
- }) => {
643
- if (!outDirectoryUrl) {
644
- return url
793
+ if (contentType === "application/manifest+json") {
794
+ return "webmanifest"
645
795
  }
646
- if (!url.startsWith("file:")) {
647
- return url
796
+ if (contentType === "image/svg+xml") {
797
+ return "svg"
648
798
  }
649
- if (!urlIsInsideOf(url, rootDirectoryUrl)) {
650
- url = `${rootDirectoryUrl}@fs/${url.slice(fileSystemRootUrl.length)}`
799
+ if (CONTENT_TYPE.isJson(contentType)) {
800
+ return "json"
651
801
  }
652
- return moveUrl({
653
- url: fileUrlConverter.asUrlWithoutSpecialParams(url),
654
- from: rootDirectoryUrl,
655
- to: outDirectoryUrl,
656
- preferAbsolute: true,
657
- })
802
+ if (CONTENT_TYPE.isTextual(contentType)) {
803
+ return "text"
804
+ }
805
+ return "other"
658
806
  }
659
807
 
660
- const specifierFormat = {
661
- encode: (reference) => {
662
- const { generatedSpecifier } = reference
663
- if (generatedSpecifier.then) {
664
- return generatedSpecifier.then((value) => {
665
- reference.generatedSpecifier = value
666
- return specifierFormat.encode(reference)
667
- })
808
+ const inferUrlInfoSubtype = ({ type, subtype, url }) => {
809
+ if (type === "js_classic" || type === "js_module") {
810
+ const urlObject = new URL(url)
811
+ if (urlObject.searchParams.has("worker")) {
812
+ return "worker"
668
813
  }
669
- // allow plugin to return a function to bypas default formatting
670
- // (which is to use JSON.stringify when url is referenced inside js)
671
- if (typeof generatedSpecifier === "function") {
672
- return generatedSpecifier()
814
+ if (urlObject.searchParams.has("service_worker")) {
815
+ return "service_worker"
673
816
  }
674
- const formatter = formatters[reference.type]
675
- const value = formatter
676
- ? formatter.encode(generatedSpecifier)
677
- : generatedSpecifier
678
- if (reference.escape) {
679
- return reference.escape(value)
817
+ if (urlObject.searchParams.has("shared_worker")) {
818
+ return "shared_worker"
680
819
  }
681
- return value
682
- },
683
- decode: (reference) => {
684
- const formatter = formatters[reference.type]
685
- return formatter
686
- ? formatter.decode(reference.generatedSpecifier)
687
- : reference.generatedSpecifier
688
- },
820
+ // if we are currently inside a worker, all deps are consider inside worker too
821
+ return subtype
822
+ }
823
+ return ""
689
824
  }
690
- const formatters = {
691
- js_import_export: { encode: JSON.stringify, decode: JSON.parse },
692
- js_import_meta_url_pattern: { encode: JSON.stringify, decode: JSON.parse },
693
- // https://github.com/webpack-contrib/css-loader/pull/627/files
694
- css_url: {
695
- encode: (url) => {
696
- // If url is already wrapped in quotes, remove them
697
- url = formatters.css_url.decode(url)
698
- // Should url be wrapped?
699
- // See https://drafts.csswg.org/css-values-3/#urls
700
- if (/["'() \t\n]/.test(url)) {
701
- return `"${url.replace(/"/g, '\\"').replace(/\n/g, "\\n")}"`
702
- }
703
- return url
704
- },
705
- decode: (url) => {
706
- const firstChar = url[0]
707
- const lastChar = url[url.length - 1]
708
- if (firstChar === `"` && lastChar === `"`) {
709
- return url.slice(1, -1)
710
- }
711
- if (firstChar === `'` && lastChar === `'`) {
712
- return url.slice(1, -1)
713
- }
714
- return url
715
- },
716
- },
825
+
826
+ const determineFileUrlForOutDirectory = ({ urlInfo, context }) => {
827
+ if (!context.outDirectoryUrl) {
828
+ return urlInfo.url
829
+ }
830
+ if (!urlInfo.url.startsWith("file:")) {
831
+ return urlInfo.url
832
+ }
833
+ let url = urlInfo.url
834
+ if (!urlIsInsideOf(urlInfo.url, context.rootDirectoryUrl)) {
835
+ const fsRootUrl = ensureWindowsDriveLetter("file:///", urlInfo.url)
836
+ url = `${context.rootDirectoryUrl}@fs/${url.slice(fsRootUrl.length)}`
837
+ }
838
+ if (urlInfo.filename) {
839
+ url = setUrlFilename(url, urlInfo.filename)
840
+ }
841
+ return moveUrl({
842
+ url,
843
+ from: context.rootDirectoryUrl,
844
+ to: context.outDirectoryUrl,
845
+ preferAbsolute: true,
846
+ })
717
847
  }
718
848
 
719
849
  // import { getOriginalPosition } from "@jsenv/core/src/utils/sourcemap/original_position.js"