@jsenv/core 27.0.0-alpha.8 → 27.0.0-alpha.82

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