@jsenv/core 27.0.0-alpha.2 → 27.0.0-alpha.22

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 (219) hide show
  1. package/main.js +4 -0
  2. package/package.json +20 -15
  3. package/readme.md +4 -12
  4. package/src/build/build.js +512 -304
  5. package/src/build/build_urls_generator.js +33 -21
  6. package/src/build/graph_utils.js +31 -0
  7. package/src/build/{inject_version_mappings.js → inject_global_version_mappings.js} +33 -15
  8. package/src/build/inject_service_worker_urls.js +79 -0
  9. package/src/build/resync_ressource_hints.js +83 -0
  10. package/src/build/start_build_server.js +196 -0
  11. package/src/dev/plugins/explorer/jsenv_plugin_explorer.js +2 -2
  12. package/src/dev/plugins/toolbar/jsenv_plugin_toolbar.js +3 -1
  13. package/src/dev/start_dev_server.js +56 -26
  14. package/src/execute/execute.js +23 -4
  15. package/src/execute/run.js +17 -54
  16. package/src/execute/runtimes/browsers/from_playwright.js +167 -146
  17. package/src/execute/runtimes/node/node_process.js +281 -37
  18. package/src/omega/{runtime_support/default_runtime_support.js → compat/default_runtime_compat.js} +3 -5
  19. package/src/omega/{runtime_support/features_compatibility.js → compat/features_compats.js} +66 -4
  20. package/src/omega/compat/runtime_compat.js +50 -0
  21. package/src/omega/errors.js +51 -58
  22. package/src/omega/fetched_content_compliance.js +24 -0
  23. package/src/omega/file_url_converter.js +8 -50
  24. package/src/omega/kitchen.js +409 -286
  25. package/src/omega/server/file_service.js +9 -11
  26. package/src/omega/url_graph/url_graph_load.js +14 -7
  27. package/src/omega/url_graph/url_graph_report.js +7 -5
  28. package/src/omega/url_graph.js +22 -9
  29. package/src/omega/web_workers.js +42 -0
  30. package/src/{dev/plugins/autoreload → plugins/autoreload/dev_sse}/client/autoreload_preference.js +0 -0
  31. package/src/{dev/plugins/autoreload → plugins/autoreload/dev_sse}/client/event_source_client.js +2 -2
  32. package/src/{dev/plugins/autoreload → plugins/autoreload/dev_sse}/client/reload.js +0 -0
  33. package/src/{dev/plugins/autoreload → plugins/autoreload/dev_sse}/client/url_helpers.js +0 -0
  34. package/src/plugins/autoreload/dev_sse/jsenv_plugin_dev_sse_client.js +41 -0
  35. package/src/{dev/plugins/autoreload/jsenv_plugin_autoreload.js → plugins/autoreload/dev_sse/jsenv_plugin_dev_sse_server.js} +27 -168
  36. package/src/plugins/autoreload/jsenv_plugin_autoreload.js +25 -0
  37. package/src/plugins/autoreload/jsenv_plugin_hmr.js +35 -0
  38. package/src/plugins/bundling/css/bundle_css.js +21 -0
  39. package/src/plugins/bundling/js_classic_workers/bundle_js_classic_workers.js +13 -0
  40. package/src/{build/plugins/bundle_js_module/jsenv_plugin_bundle_js_module.js → plugins/bundling/js_module/bundle_js_module.js} +105 -78
  41. package/src/plugins/bundling/jsenv_plugin_bundling.js +51 -0
  42. package/src/{omega/core_plugins → plugins}/commonjs_globals/jsenv_plugin_commonjs_globals.js +48 -41
  43. package/src/plugins/file_urls/jsenv_plugin_file_urls.js +66 -0
  44. package/src/{omega/core_plugins → plugins}/filesystem_magic/jsenv_plugin_filesystem_magic.js +7 -4
  45. package/src/{omega/core_plugins → plugins}/html_supervisor/client/error_in_document.js +0 -0
  46. package/src/{omega/core_plugins → plugins}/html_supervisor/client/error_in_notification.js +0 -0
  47. package/src/{omega/core_plugins → plugins}/html_supervisor/client/html_supervisor_installer.js +3 -2
  48. package/src/{omega/core_plugins → plugins}/html_supervisor/client/html_supervisor_setup.js +0 -0
  49. package/src/{omega/core_plugins → plugins}/html_supervisor/client/perf_browser.js +0 -0
  50. package/src/{omega/core_plugins → plugins}/html_supervisor/client/uneval_exception.js +0 -0
  51. package/src/{omega/core_plugins → plugins}/html_supervisor/jsenv_plugin_html_supervisor.js +38 -46
  52. package/src/plugins/http_urls/jsenv_plugin_http_urls.js +12 -0
  53. package/src/{dev/plugins/autoreload → plugins/import_meta_hot}/babel_plugin_metadata_import_meta_hot.js +4 -5
  54. package/src/{dev/plugins/autoreload → plugins/import_meta_hot}/client/import_meta_hot.js +3 -1
  55. package/src/{dev/plugins/autoreload → plugins/import_meta_hot}/html_hot_dependencies.js +2 -2
  56. package/src/plugins/import_meta_hot/jsenv_plugin_import_meta_hot.js +98 -0
  57. package/src/{omega/core_plugins → plugins}/import_meta_scenarios/jsenv_plugin_import_meta_scenarios.js +41 -13
  58. package/src/plugins/import_meta_url/client/import_meta_url_browser.js +52 -0
  59. package/src/plugins/import_meta_url/client/import_meta_url_commonjs.mjs +9 -0
  60. package/src/{omega/core_plugins → plugins}/importmap/jsenv_plugin_importmap.js +37 -31
  61. package/src/plugins/inject_globals/jsenv_plugin_inject_globals.js +25 -0
  62. package/src/{omega/core_plugins → plugins}/inline/client/inline_content.js +0 -0
  63. package/src/{omega/core_plugins → plugins}/inline/jsenv_plugin_data_urls.js +18 -14
  64. package/src/{omega/core_plugins/inline/jsenv_plugin_js_and_css_inside_html.js → plugins/inline/jsenv_plugin_html_inline_content.js} +61 -40
  65. package/src/plugins/inline/jsenv_plugin_inline.js +36 -0
  66. package/src/{omega/core_plugins → plugins}/inline/jsenv_plugin_inline_query_param.js +6 -6
  67. package/src/plugins/inline/jsenv_plugin_js_inline_content.js +263 -0
  68. package/src/plugins/leading_slash/jsenv_plugin_leading_slash.js +13 -0
  69. package/src/plugins/minification/css/minify_css.js +9 -0
  70. package/src/plugins/minification/html/minify_html.js +15 -0
  71. package/src/{build/plugins/minify_js/jsenv_plugin_minify_js.js → plugins/minification/js/minify_js.js} +6 -22
  72. package/src/plugins/minification/jsenv_plugin_minification.js +78 -0
  73. package/src/plugins/minification/json/minify_json.js +8 -0
  74. package/src/{omega/core_plugins → plugins}/node_esm_resolution/jsenv_plugin_node_esm_resolution.js +15 -15
  75. package/src/{omega → plugins}/plugin_controller.js +18 -10
  76. package/src/plugins/plugins.js +73 -0
  77. package/src/plugins/transpilation/as_js_classic/client/s.js +808 -0
  78. package/src/plugins/transpilation/as_js_classic/client/s.js.md +1 -0
  79. package/src/plugins/transpilation/as_js_classic/helpers/babel_plugin_transform_import_meta_url.js +47 -0
  80. package/src/plugins/transpilation/as_js_classic/helpers/systemjs_old.js +43 -0
  81. package/src/plugins/transpilation/as_js_classic/jsenv_plugin_as_js_classic.js +191 -0
  82. package/src/plugins/transpilation/as_js_classic/jsenv_plugin_script_type_module_as_classic.js +156 -0
  83. package/src/plugins/transpilation/as_js_classic/jsenv_plugin_top_level_await.js +37 -0
  84. package/src/plugins/transpilation/as_js_classic/jsenv_plugin_workers_type_module_as_classic.js +133 -0
  85. package/src/{omega/core_plugins → plugins/transpilation}/babel/global_this/babel_plugin_global_this_as_jsenv_import.js +0 -0
  86. package/src/{omega/core_plugins → plugins/transpilation}/babel/global_this/client/global_this.js +0 -0
  87. package/src/{omega/core_plugins/babel/babel_helper → plugins/transpilation/babel/helpers}/babel_plugin_babel_helpers_as_jsenv_imports.js +1 -2
  88. package/src/plugins/transpilation/babel/helpers/babel_plugin_structure.js +158 -0
  89. package/src/{omega/core_plugins → plugins/transpilation}/babel/helpers/babel_plugins_compatibility.js +0 -0
  90. package/src/{omega/core_plugins → plugins/transpilation}/babel/jsenv_plugin_babel.js +38 -22
  91. package/src/{omega/core_plugins → plugins/transpilation}/babel/new_stylesheet/babel_plugin_new_stylesheet_as_jsenv_import.js +0 -0
  92. package/src/{omega/core_plugins → plugins/transpilation}/babel/new_stylesheet/client/.eslintrc.cjs +0 -0
  93. package/src/{omega/core_plugins → plugins/transpilation}/babel/new_stylesheet/client/new_stylesheet.js +0 -0
  94. package/src/{omega/core_plugins → plugins/transpilation}/babel/regenerator_runtime/babel_plugin_regenerator_runtime_as_jsenv_import.js +0 -0
  95. package/src/{omega/core_plugins → plugins/transpilation}/babel/regenerator_runtime/client/regenerator_runtime.js +0 -0
  96. package/src/plugins/transpilation/css_parcel/jsenv_plugin_css_parcel.js +18 -0
  97. package/src/{omega/core_plugins → plugins/transpilation}/import_assertions/helpers/babel_plugin_metadata_import_assertions.js +0 -0
  98. package/src/plugins/transpilation/import_assertions/jsenv_plugin_import_assertions.js +243 -0
  99. package/src/plugins/transpilation/jsenv_plugin_transpilation.js +40 -0
  100. package/src/plugins/url_references/css/css_urls.js +49 -0
  101. package/src/plugins/url_references/html/html_urls.js +273 -0
  102. package/src/plugins/url_references/js/js_urls.js +170 -0
  103. package/src/plugins/url_references/jsenv_plugin_url_references.js +18 -0
  104. package/src/plugins/url_references/webmanifest/webmanifest_urls.js +17 -0
  105. package/src/{omega/core_plugins → plugins}/url_resolution/jsenv_plugin_url_resolution.js +12 -5
  106. package/src/{omega/core_plugins → plugins}/url_version/jsenv_plugin_url_version.js +8 -8
  107. package/src/test/execute_plan.js +25 -11
  108. package/src/test/execute_test_plan.js +14 -1
  109. package/src/test/logs_file_execution.js +8 -7
  110. package/src/build/plugins/minify_html/jsenv_plugin_minify_html.js +0 -30
  111. package/src/dev/plugins/autoreload/client/event_source_connection.js +0 -195
  112. package/src/dev/plugins/autoreload/sse_service.js +0 -149
  113. package/src/execute/runtimes/node/controlled_process.js +0 -316
  114. package/src/omega/core_plugins/babel/babel_helper/babel_helper_directory.js +0 -29
  115. package/src/omega/core_plugins/babel/babel_helper/client/.eslintrc.cjs +0 -24
  116. package/src/omega/core_plugins/babel/babel_helper/client/AsyncGenerator/AsyncGenerator.js +0 -81
  117. package/src/omega/core_plugins/babel/babel_helper/client/AwaitValue/AwaitValue.js +0 -3
  118. package/src/omega/core_plugins/babel/babel_helper/client/applyDecoratorDescriptor/applyDecoratorDescriptor.js +0 -33
  119. package/src/omega/core_plugins/babel/babel_helper/client/arrayLikeToArray/arrayLikeToArray.js +0 -7
  120. package/src/omega/core_plugins/babel/babel_helper/client/arrayWithHoles/arrayWithHoles.js +0 -4
  121. package/src/omega/core_plugins/babel/babel_helper/client/arrayWithoutHoles/arrayWithoutHoles.js +0 -6
  122. package/src/omega/core_plugins/babel/babel_helper/client/assertThisInitialized/assertThisInitialized.js +0 -7
  123. package/src/omega/core_plugins/babel/babel_helper/client/asyncGeneratorDelegate/asyncGeneratorDelegate.js +0 -40
  124. package/src/omega/core_plugins/babel/babel_helper/client/asyncIterator/asyncIterator.js +0 -65
  125. package/src/omega/core_plugins/babel/babel_helper/client/asyncToGenerator/asyncToGenerator.js +0 -34
  126. package/src/omega/core_plugins/babel/babel_helper/client/awaitAsyncGenerator/awaitAsyncGenerator.js +0 -5
  127. package/src/omega/core_plugins/babel/babel_helper/client/classApplyDescriptorDestructureSet/classApplyDescriptorDestructureSet.js +0 -20
  128. package/src/omega/core_plugins/babel/babel_helper/client/classApplyDescriptorGet/classApplyDescriptorGet.js +0 -6
  129. package/src/omega/core_plugins/babel/babel_helper/client/classApplyDescriptorSet/classApplyDescriptorSet.js +0 -13
  130. package/src/omega/core_plugins/babel/babel_helper/client/classCallCheck/classCallCheck.js +0 -5
  131. package/src/omega/core_plugins/babel/babel_helper/client/classCheckPrivateStaticAccess/classCheckPrivateStaticAccess.js +0 -5
  132. package/src/omega/core_plugins/babel/babel_helper/client/classCheckPrivateStaticFieldDescriptor/classCheckPrivateStaticFieldDescriptor.js +0 -6
  133. package/src/omega/core_plugins/babel/babel_helper/client/classExtractFieldDescriptor/classExtractFieldDescriptor.js +0 -7
  134. package/src/omega/core_plugins/babel/babel_helper/client/classNameTDZError/classNameTDZError.js +0 -4
  135. package/src/omega/core_plugins/babel/babel_helper/client/classPrivateFieldDestructureSet/classPrivateFieldDestructureSet.js +0 -7
  136. package/src/omega/core_plugins/babel/babel_helper/client/classPrivateFieldGet/classPrivateFieldGet.js +0 -7
  137. package/src/omega/core_plugins/babel/babel_helper/client/classPrivateFieldLooseBase/classPrivateFieldLooseBase.js +0 -6
  138. package/src/omega/core_plugins/babel/babel_helper/client/classPrivateFieldLooseKey/classPrivateFieldLooseKey.js +0 -5
  139. package/src/omega/core_plugins/babel/babel_helper/client/classPrivateFieldSet/classPrivateFieldSet.js +0 -8
  140. package/src/omega/core_plugins/babel/babel_helper/client/classPrivateMethodGet/classPrivateMethodGet.js +0 -6
  141. package/src/omega/core_plugins/babel/babel_helper/client/classPrivateMethodSet/classPrivateMethodSet.js +0 -3
  142. package/src/omega/core_plugins/babel/babel_helper/client/classStaticPrivateFieldSpecGet/classStaticPrivateFieldSpecGet.js +0 -9
  143. package/src/omega/core_plugins/babel/babel_helper/client/classStaticPrivateFieldSpecSet/classStaticPrivateFieldSpecSet.js +0 -15
  144. package/src/omega/core_plugins/babel/babel_helper/client/classStaticPrivateMethodGet/classStaticPrivateMethodGet.js +0 -6
  145. package/src/omega/core_plugins/babel/babel_helper/client/classStaticPrivateMethodSet/classStaticPrivateMethodSet.js +0 -3
  146. package/src/omega/core_plugins/babel/babel_helper/client/construct/construct.js +0 -16
  147. package/src/omega/core_plugins/babel/babel_helper/client/createClass/createClass.js +0 -15
  148. package/src/omega/core_plugins/babel/babel_helper/client/createForOfIteratorHelper/createForOfIteratorHelper.js +0 -60
  149. package/src/omega/core_plugins/babel/babel_helper/client/createForOfIteratorHelperLoose/createForOfIteratorHelperLoose.js +0 -23
  150. package/src/omega/core_plugins/babel/babel_helper/client/createRawReactElement/createRawReactElement.js +0 -50
  151. package/src/omega/core_plugins/babel/babel_helper/client/createSuper/createSuper.js +0 -22
  152. package/src/omega/core_plugins/babel/babel_helper/client/decorate/decorate.js +0 -403
  153. package/src/omega/core_plugins/babel/babel_helper/client/defaults/defaults.js +0 -11
  154. package/src/omega/core_plugins/babel/babel_helper/client/defineEnumerableProperties/defineEnumerableProperties.js +0 -23
  155. package/src/omega/core_plugins/babel/babel_helper/client/defineProperty/defineProperty.js +0 -18
  156. package/src/omega/core_plugins/babel/babel_helper/client/extends/extends.js +0 -14
  157. package/src/omega/core_plugins/babel/babel_helper/client/get/get.js +0 -19
  158. package/src/omega/core_plugins/babel/babel_helper/client/getPrototypeOf/getPrototypeOf.js +0 -4
  159. package/src/omega/core_plugins/babel/babel_helper/client/inherits/inherits.js +0 -19
  160. package/src/omega/core_plugins/babel/babel_helper/client/inheritsLoose/inheritsLoose.js +0 -7
  161. package/src/omega/core_plugins/babel/babel_helper/client/initializerDefineProperty/initializerDefineProperty.js +0 -10
  162. package/src/omega/core_plugins/babel/babel_helper/client/initializerWarningHelper/initializerWarningHelper.js +0 -6
  163. package/src/omega/core_plugins/babel/babel_helper/client/instanceof/instanceof.js +0 -6
  164. package/src/omega/core_plugins/babel/babel_helper/client/interopRequireDefault/interopRequireDefault.js +0 -3
  165. package/src/omega/core_plugins/babel/babel_helper/client/interopRequireWildcard/interopRequireWildcard.js +0 -37
  166. package/src/omega/core_plugins/babel/babel_helper/client/isNativeFunction/isNativeFunction.js +0 -4
  167. package/src/omega/core_plugins/babel/babel_helper/client/isNativeReflectConstruct/isNativeReflectConstruct.js +0 -21
  168. package/src/omega/core_plugins/babel/babel_helper/client/iterableToArray/iterableToArray.js +0 -7
  169. package/src/omega/core_plugins/babel/babel_helper/client/iterableToArrayLimit/iterableToArrayLimit.js +0 -36
  170. package/src/omega/core_plugins/babel/babel_helper/client/iterableToArrayLimitLoose/iterableToArrayLimitLoose.js +0 -10
  171. package/src/omega/core_plugins/babel/babel_helper/client/jsx/jsx.js +0 -50
  172. package/src/omega/core_plugins/babel/babel_helper/client/maybeArrayLike/maybeArrayLike.js +0 -10
  173. package/src/omega/core_plugins/babel/babel_helper/client/newArrowCheck/newArrowCheck.js +0 -5
  174. package/src/omega/core_plugins/babel/babel_helper/client/nonIterableRest/nonIterableRest.js +0 -5
  175. package/src/omega/core_plugins/babel/babel_helper/client/nonIterableSpread/nonIterableSpread.js +0 -5
  176. package/src/omega/core_plugins/babel/babel_helper/client/objectDestructuringEmpty/objectDestructuringEmpty.js +0 -3
  177. package/src/omega/core_plugins/babel/babel_helper/client/objectSpread/objectSpread.js +0 -23
  178. package/src/omega/core_plugins/babel/babel_helper/client/objectSpread2/objectSpread2.js +0 -41
  179. package/src/omega/core_plugins/babel/babel_helper/client/objectWithoutProperties/objectWithoutProperties.js +0 -19
  180. package/src/omega/core_plugins/babel/babel_helper/client/objectWithoutPropertiesLoose/objectWithoutPropertiesLoose.js +0 -13
  181. package/src/omega/core_plugins/babel/babel_helper/client/possibleConstructorReturn/possibleConstructorReturn.js +0 -10
  182. package/src/omega/core_plugins/babel/babel_helper/client/readOnlyError/readOnlyError.js +0 -4
  183. package/src/omega/core_plugins/babel/babel_helper/client/readme.md +0 -8
  184. package/src/omega/core_plugins/babel/babel_helper/client/set/set.js +0 -44
  185. package/src/omega/core_plugins/babel/babel_helper/client/setPrototypeOf/setPrototypeOf.js +0 -6
  186. package/src/omega/core_plugins/babel/babel_helper/client/skipFirstGeneratorNext/skipFirstGeneratorNext.js +0 -8
  187. package/src/omega/core_plugins/babel/babel_helper/client/slicedToArray/slicedToArray.js +0 -10
  188. package/src/omega/core_plugins/babel/babel_helper/client/slicedToArrayLoose/slicedToArrayLoose.js +0 -13
  189. package/src/omega/core_plugins/babel/babel_helper/client/superPropBase/superPropBase.js +0 -10
  190. package/src/omega/core_plugins/babel/babel_helper/client/taggedTemplateLiteral/taggedTemplateLiteral.js +0 -10
  191. package/src/omega/core_plugins/babel/babel_helper/client/taggedTemplateLiteralLoose/taggedTemplateLiteralLoose.js +0 -7
  192. package/src/omega/core_plugins/babel/babel_helper/client/tdz/tdz.js +0 -4
  193. package/src/omega/core_plugins/babel/babel_helper/client/temporalRef/temporalRef.js +0 -6
  194. package/src/omega/core_plugins/babel/babel_helper/client/temporalUndefined/temporalUndefined.js +0 -3
  195. package/src/omega/core_plugins/babel/babel_helper/client/toArray/toArray.js +0 -10
  196. package/src/omega/core_plugins/babel/babel_helper/client/toConsumableArray/toConsumableArray.js +0 -10
  197. package/src/omega/core_plugins/babel/babel_helper/client/toPrimitive/toPrimitive.js +0 -10
  198. package/src/omega/core_plugins/babel/babel_helper/client/toPropertyKey/toPropertyKey.js +0 -6
  199. package/src/omega/core_plugins/babel/babel_helper/client/typeof/typeof.js +0 -14
  200. package/src/omega/core_plugins/babel/babel_helper/client/unsupportedIterableToArray/unsupportedIterableToArray.js +0 -12
  201. package/src/omega/core_plugins/babel/babel_helper/client/wrapAsyncGenerator/wrapAsyncGenerator.js +0 -8
  202. package/src/omega/core_plugins/babel/babel_helper/client/wrapNativeSuper/wrapNativeSuper.js +0 -30
  203. package/src/omega/core_plugins/babel/babel_helper/client/wrapRegExp/wrapRegExp.js +0 -63
  204. package/src/omega/core_plugins/babel/babel_helper/client/writeOnlyError/writeOnlyError.js +0 -4
  205. package/src/omega/core_plugins/babel/helpers/babel_plugin_structure.js +0 -187
  206. package/src/omega/core_plugins/file_urls/jsenv_plugin_file_urls.js +0 -67
  207. package/src/omega/core_plugins/import_assertions/helpers/json_module.js +0 -12
  208. package/src/omega/core_plugins/import_assertions/helpers/text_module.js +0 -6
  209. package/src/omega/core_plugins/import_assertions/jsenv_plugin_import_assertions.js +0 -211
  210. package/src/omega/core_plugins/inline/jsenv_plugin_inline.js +0 -13
  211. package/src/omega/core_plugins/inline/jsenv_plugin_new_inline_content.js +0 -210
  212. package/src/omega/core_plugins/leading_slash/jsenv_plugin_leading_slash.js +0 -12
  213. package/src/omega/core_plugins.js +0 -39
  214. package/src/omega/runtime_support/runtime_support.js +0 -20
  215. package/src/omega/url_mentions/css_url_mentions.js +0 -63
  216. package/src/omega/url_mentions/html_url_mentions.js +0 -185
  217. package/src/omega/url_mentions/js_module_url_mentions.js +0 -91
  218. package/src/omega/url_mentions/parse_url_mentions.js +0 -37
  219. package/src/omega/url_mentions/worker_classic_url_mentions.js +0 -37
@@ -4,23 +4,22 @@ import { memoizeByUrl } from "@jsenv/utils/memoize/memoize_by_url.js"
4
4
 
5
5
  export const createBuilUrlsGenerator = ({ buildDirectoryUrl }) => {
6
6
  const cache = {}
7
- const generate = memoizeByUrl((url, urlInfo, parentUrlInfo) => {
8
- const directoryPath = determineDirectoryPath(urlInfo, parentUrlInfo)
9
- let name = urlToFilename(url)
10
- const { searchParams } = new URL(url)
11
- if (
12
- searchParams.has("css_module") ||
13
- searchParams.has("json_module") ||
14
- searchParams.has("text_module")
15
- ) {
16
- name = `${name}.js`
17
- }
7
+ const generate = memoizeByUrl((url, { urlInfo, parentUrlInfo }) => {
8
+ const directoryPath = determineDirectoryPath({
9
+ urlInfo,
10
+ parentUrlInfo,
11
+ })
18
12
  let names = cache[directoryPath]
19
13
  if (!names) {
20
14
  names = []
21
15
  cache[directoryPath] = names
22
16
  }
23
-
17
+ const urlObject = new URL(url)
18
+ let { search, hash } = urlObject
19
+ let name = urlInfo
20
+ ? urlInfo.filename || urlToFilename(url)
21
+ : urlToFilename(url)
22
+ const [basename, extension] = splitFileExtension(name)
24
23
  let nameCandidate = name
25
24
  let integer = 1
26
25
  // eslint-disable-next-line no-constant-condition
@@ -30,9 +29,9 @@ export const createBuilUrlsGenerator = ({ buildDirectoryUrl }) => {
30
29
  break
31
30
  }
32
31
  integer++
33
- nameCandidate = `${name}${integer}`
32
+ nameCandidate = `${basename}${integer}${extension}`
34
33
  }
35
- return `${buildDirectoryUrl}${directoryPath}${nameCandidate}`
34
+ return `${buildDirectoryUrl}${directoryPath}${nameCandidate}${search}${hash}`
36
35
  })
37
36
 
38
37
  return {
@@ -40,12 +39,25 @@ export const createBuilUrlsGenerator = ({ buildDirectoryUrl }) => {
40
39
  }
41
40
  }
42
41
 
43
- const determineDirectoryPath = (urlInfo, parentUrlInfo) => {
42
+ const splitFileExtension = (filename) => {
43
+ const dotLastIndex = filename.lastIndexOf(".")
44
+ if (dotLastIndex === -1) {
45
+ return [filename, ""]
46
+ }
47
+ return [filename.slice(0, dotLastIndex), filename.slice(dotLastIndex)]
48
+ }
49
+
50
+ const determineDirectoryPath = ({ urlInfo, parentUrlInfo }) => {
44
51
  if (urlInfo.isInline) {
45
- const parentDirectoryPath = determineDirectoryPath(parentUrlInfo)
52
+ const parentDirectoryPath = determineDirectoryPath({
53
+ urlInfo: parentUrlInfo,
54
+ })
46
55
  return parentDirectoryPath
47
56
  }
48
- if (urlInfo.data.isEntryPoint) {
57
+ if (urlInfo.data.isEntryPoint || urlInfo.data.isWebWorkerEntryPoint) {
58
+ return ""
59
+ }
60
+ if (urlInfo.type === "importmap") {
49
61
  return ""
50
62
  }
51
63
  if (urlInfo.type === "html") {
@@ -55,10 +67,10 @@ const determineDirectoryPath = (urlInfo, parentUrlInfo) => {
55
67
  return "css/"
56
68
  }
57
69
  if (urlInfo.type === "js_module" || urlInfo.type === "js_classic") {
58
- if (urlInfo.subtype === "service_worker") {
59
- return ""
60
- }
61
70
  return "js/"
62
71
  }
63
- return "assets/"
72
+ if (urlInfo.type === "json") {
73
+ return "json/"
74
+ }
75
+ return "other/"
64
76
  }
@@ -0,0 +1,31 @@
1
+ export const GRAPH = {
2
+ map: (graph, callback) => {
3
+ return Object.keys(graph.urlInfos).map((url) => {
4
+ return callback(graph.urlInfos[url])
5
+ })
6
+ },
7
+
8
+ forEach: (graph, callback) => {
9
+ Object.keys(graph.urlInfos).forEach((url) => {
10
+ callback(graph.urlInfos[url], url)
11
+ })
12
+ },
13
+
14
+ filter: (graph, callback) => {
15
+ const urlInfos = []
16
+ Object.keys(graph.urlInfos).forEach((url) => {
17
+ const urlInfo = graph.urlInfos[url]
18
+ if (callback(urlInfo)) {
19
+ urlInfos.push(urlInfo)
20
+ }
21
+ })
22
+ return urlInfos
23
+ },
24
+
25
+ find: (graph, callback) => {
26
+ const urlFound = Object.keys(graph.urlInfos).find((url) => {
27
+ return callback(graph.urlInfos[url])
28
+ })
29
+ return graph.urlInfos[urlFound]
30
+ },
31
+ }
@@ -8,10 +8,27 @@ import {
8
8
  } from "@jsenv/utils/html_ast/html_ast.js"
9
9
  import { createMagicSource } from "@jsenv/utils/sourcemap/magic_source.js"
10
10
 
11
- export const injectVersionMappings = async (
12
- urlInfo,
13
- { kitchen, versionMappings },
14
- ) => {
11
+ import { GRAPH } from "./graph_utils.js"
12
+
13
+ export const injectGlobalVersionMapping = async ({
14
+ finalGraphKitchen,
15
+ finalGraph,
16
+ versionMappings,
17
+ }) => {
18
+ await Promise.all(
19
+ GRAPH.map(finalGraph, async (urlInfo) => {
20
+ if (urlInfo.data.isEntryPoint || urlInfo.data.isWebWorkerEntryPoint) {
21
+ await injectVersionMappings({
22
+ urlInfo,
23
+ kitchen: finalGraphKitchen,
24
+ versionMappings,
25
+ })
26
+ }
27
+ }),
28
+ )
29
+ }
30
+
31
+ const injectVersionMappings = async ({ urlInfo, kitchen, versionMappings }) => {
15
32
  const injector = injectors[urlInfo.type]
16
33
  if (injector) {
17
34
  const { content, sourcemap } = injector(urlInfo, { versionMappings })
@@ -22,6 +39,12 @@ export const injectVersionMappings = async (
22
39
  }
23
40
  }
24
41
 
42
+ const jsInjector = (urlInfo, { versionMappings }) => {
43
+ const magicSource = createMagicSource(urlInfo.content)
44
+ magicSource.prepend(generateClientCodeForVersionMappings(versionMappings))
45
+ return magicSource.toContentAndSourcemap()
46
+ }
47
+
25
48
  const injectors = {
26
49
  html: (urlInfo, { versionMappings }) => {
27
50
  // ideally we would inject an importmap but browser support is too low
@@ -39,24 +62,19 @@ const injectors = {
39
62
  }),
40
63
  )
41
64
  return {
42
- content: stringifyHtmlAst(htmlAst, {
43
- removeOriginalPositionAttributes: true,
44
- }),
65
+ content: stringifyHtmlAst(htmlAst),
45
66
  }
46
67
  },
47
- js_module: (urlInfo, { versionMappings }) => {
48
- const magicSource = createMagicSource(urlInfo.content)
49
- magicSource.prepend(generateClientCodeForVersionMappings(versionMappings))
50
- return magicSource.toContentAndSourcemap()
51
- },
68
+ js_classic: jsInjector,
69
+ js_module: jsInjector,
52
70
  }
53
71
 
54
72
  const generateClientCodeForVersionMappings = (versionMappings) => {
55
73
  return `
56
- var __versionMappings__ = ${JSON.stringify(versionMappings, null, " ")}
57
- var __envGlobal__ = typeof self === 'undefined' ? global : self
74
+ var __versionMappings__ = ${JSON.stringify(versionMappings, null, " ")};
75
+ var __envGlobal__ = typeof self === 'undefined' ? global : self;
58
76
  __envGlobal__.__v__ = function (specifier) {
59
77
  return __versionMappings__[specifier] || specifier
60
- }
78
+ };
61
79
  `
62
80
  }
@@ -0,0 +1,79 @@
1
+ import { createMagicSource } from "@jsenv/utils/sourcemap/magic_source.js"
2
+ import { createVersionGenerator } from "@jsenv/utils/versioning/version_generator.js"
3
+
4
+ import { GRAPH } from "./graph_utils.js"
5
+
6
+ export const injectServiceWorkerUrls = async ({
7
+ finalGraph,
8
+ finalGraphKitchen,
9
+ lineBreakNormalization,
10
+ }) => {
11
+ const serviceWorkerEntryUrlInfos = GRAPH.filter(
12
+ finalGraph,
13
+ (finalUrlInfo) => {
14
+ return (
15
+ finalUrlInfo.subtype === "service_worker" &&
16
+ finalUrlInfo.data.isWebWorkerEntryPoint
17
+ )
18
+ },
19
+ )
20
+ if (serviceWorkerEntryUrlInfos.length === 0) {
21
+ return
22
+ }
23
+ const serviceWorkerUrls = {}
24
+ GRAPH.forEach(finalGraph, (urlInfo) => {
25
+ if (urlInfo.isInline || urlInfo.external) {
26
+ return
27
+ }
28
+ if (!urlInfo.url.startsWith("file:")) {
29
+ return
30
+ }
31
+ if (urlInfo.data.buildUrlIsVersioned) {
32
+ serviceWorkerUrls[urlInfo.data.buildUrlSpecifier] = {
33
+ versioned: true,
34
+ }
35
+ return
36
+ }
37
+ if (!urlInfo.data.version) {
38
+ // when url is not versioned we compute a "version" for that url anyway
39
+ // so that service worker source still changes and navigator
40
+ // detect there is a change
41
+ const versionGenerator = createVersionGenerator()
42
+ versionGenerator.augmentWithContent({
43
+ content: urlInfo.content,
44
+ contentType: urlInfo.contentType,
45
+ lineBreakNormalization,
46
+ })
47
+ const version = versionGenerator.generate()
48
+ urlInfo.data.version = version
49
+ }
50
+ serviceWorkerUrls[urlInfo.data.buildUrlSpecifier] = {
51
+ versioned: false,
52
+ version: urlInfo.data.version,
53
+ }
54
+ })
55
+ await Promise.all(
56
+ serviceWorkerEntryUrlInfos.map(async (serviceWorkerEntryUrlInfo) => {
57
+ const magicSource = createMagicSource(serviceWorkerEntryUrlInfo.content)
58
+ const urlsWithoutSelf = {
59
+ ...serviceWorkerUrls,
60
+ }
61
+ delete urlsWithoutSelf[serviceWorkerEntryUrlInfo.data.buildUrlSpecifier]
62
+ magicSource.prepend(generateClientCode(urlsWithoutSelf))
63
+ const { content, sourcemap } = magicSource.toContentAndSourcemap()
64
+ await finalGraphKitchen.urlInfoTransformer.applyFinalTransformations(
65
+ serviceWorkerEntryUrlInfo,
66
+ {
67
+ content,
68
+ sourcemap,
69
+ },
70
+ )
71
+ }),
72
+ )
73
+ }
74
+
75
+ const generateClientCode = (serviceWorkerUrls) => {
76
+ return `
77
+ self.serviceWorkerUrls = ${JSON.stringify(serviceWorkerUrls, null, " ")};
78
+ `
79
+ }
@@ -0,0 +1,83 @@
1
+ import {
2
+ parseHtmlString,
3
+ visitHtmlAst,
4
+ stringifyHtmlAst,
5
+ getHtmlNodeAttributeByName,
6
+ assignHtmlNodeAttributes,
7
+ removeHtmlNode,
8
+ } from "@jsenv/utils/html_ast/html_ast.js"
9
+
10
+ import { GRAPH } from "./graph_utils.js"
11
+
12
+ // update ressource hint that where targeting a file that has changed during build
13
+ // (happens for import assertions and file modified by "?as_js_classic")
14
+ export const resyncRessourceHints = async ({
15
+ finalGraphKitchen,
16
+ finalGraph,
17
+ buildUrls,
18
+ buildUrlRedirections,
19
+ }) => {
20
+ const ressourceHintActions = []
21
+ GRAPH.forEach(finalGraph, (urlInfo) => {
22
+ if (urlInfo.type !== "html") {
23
+ return
24
+ }
25
+ ressourceHintActions.push(async () => {
26
+ const htmlAst = parseHtmlString(urlInfo.content, {
27
+ storeOriginalPositions: false,
28
+ })
29
+ const visitLinkWithHref = (linkNode, hrefAttribute) => {
30
+ const href = hrefAttribute.value
31
+ if (!href || href.startsWith("data:")) {
32
+ return
33
+ }
34
+ const buildUrl = buildUrls[href]
35
+ const urlInfo = finalGraph.getUrlInfo(buildUrl)
36
+ if (!urlInfo) {
37
+ return
38
+ }
39
+ if (urlInfo.dependents.size === 0) {
40
+ removeHtmlNode(linkNode)
41
+ return
42
+ }
43
+ const buildUrlRedirected = buildUrlRedirections[buildUrl]
44
+ if (buildUrlRedirected) {
45
+ const urlInfoRedirected = finalGraph.getUrlInfo(buildUrlRedirected)
46
+ hrefAttribute.value = urlInfoRedirected.data.buildUrlSpecifier
47
+
48
+ if (
49
+ urlInfo.type === "js_module" &&
50
+ urlInfoRedirected.type === "js_classic"
51
+ ) {
52
+ const relAttribute = getHtmlNodeAttributeByName(linkNode, "rel")
53
+ if (relAttribute && relAttribute.value === "modulepreload") {
54
+ assignHtmlNodeAttributes(linkNode, {
55
+ rel: "preload",
56
+ as: "script",
57
+ })
58
+ }
59
+ }
60
+ }
61
+ }
62
+ visitHtmlAst(htmlAst, (node) => {
63
+ if (node.nodeName !== "link") {
64
+ return
65
+ }
66
+ const hrefAttribute = getHtmlNodeAttributeByName(node, "href")
67
+ if (!hrefAttribute) {
68
+ return
69
+ }
70
+ visitLinkWithHref(node, hrefAttribute)
71
+ })
72
+ await finalGraphKitchen.urlInfoTransformer.applyFinalTransformations(
73
+ urlInfo,
74
+ {
75
+ content: stringifyHtmlAst(htmlAst),
76
+ },
77
+ )
78
+ })
79
+ })
80
+ await Promise.all(
81
+ ressourceHintActions.map((ressourceHintAction) => ressourceHintAction()),
82
+ )
83
+ }
@@ -0,0 +1,196 @@
1
+ /*
2
+ * startBuildServer is mean to interact with the build files;
3
+ * files that will be deployed to production server(s).
4
+ * We want to be as close as possible from the production in order to:
5
+ * - run lighthouse
6
+ * - run an automated test tool such as cypress, playwright
7
+ * - see exactly how build file behaves (debug, measure perf, etc)
8
+ * For these reasons "startBuildServer" must be as close as possible from a static file server.
9
+ * It is not meant to provide a nice developper experience: this is the role "startDevServer".
10
+ *
11
+ * Conclusion:
12
+ * "startBuildServer" must be as close as possible from a static file server because
13
+ * we want to be in the user shoes and we should not alter build files.
14
+ */
15
+
16
+ import {
17
+ jsenvAccessControlAllowedHeaders,
18
+ startServer,
19
+ pluginServerTiming,
20
+ pluginRequestWaitingCheck,
21
+ pluginCORS,
22
+ fetchFileSystem,
23
+ } from "@jsenv/server"
24
+ import { createLogger } from "@jsenv/logger"
25
+
26
+ import { initProcessAutorestart } from "@jsenv/utils/file_watcher/process_auto_restart.js"
27
+ import { createTaskLog } from "@jsenv/utils/logs/task_log.js"
28
+ import { watchFiles } from "@jsenv/utils/file_watcher/file_watcher.js"
29
+ import { executeCommand } from "@jsenv/utils/command/command.js"
30
+
31
+ export const startBuildServer = async ({
32
+ signal = new AbortController().signal,
33
+ handleSIGINT = true,
34
+ logLevel,
35
+ buildCommandLogLevel = "warn",
36
+ protocol = "http",
37
+ http2,
38
+ certificate,
39
+ privateKey,
40
+ listenAnyIp,
41
+ ip,
42
+ port = 9779,
43
+
44
+ rootDirectoryUrl,
45
+ buildDirectoryUrl,
46
+ buildCommand,
47
+ mainBuildFile,
48
+ watchedFilePatterns,
49
+ cooldownBetweenFileEvents,
50
+ autorestart,
51
+ }) => {
52
+ const autorestartProcess = await initProcessAutorestart({
53
+ signal,
54
+ handleSIGINT,
55
+ ...(autorestart
56
+ ? {
57
+ enabled: true,
58
+ logLevel: autorestart.logLevel,
59
+ urlToRestart: autorestart.url,
60
+ urlsToWatch: [
61
+ ...(autorestart.urlsToWatch || []),
62
+ new URL("package.json", rootDirectoryUrl),
63
+ new URL("jsenv.config.mjs", rootDirectoryUrl),
64
+ ],
65
+ }
66
+ : {
67
+ enabled: false,
68
+ }),
69
+ })
70
+ if (autorestartProcess.isPrimary) {
71
+ return {
72
+ origin: `${protocol}://127.0.0.1:${port}`,
73
+ stop: () => {
74
+ autorestartProcess.stop()
75
+ },
76
+ }
77
+ }
78
+ signal = autorestartProcess.signal
79
+ const logger = createLogger({ logLevel })
80
+
81
+ let buildPromise
82
+ let abortController
83
+ const runBuild = async () => {
84
+ const buildTask = createTaskLog(logger, `execute build command`)
85
+ buildPromise = executeCommand(buildCommand, {
86
+ cwd: rootDirectoryUrl,
87
+ logLevel: buildCommandLogLevel,
88
+ signal,
89
+ })
90
+ try {
91
+ await buildPromise
92
+ buildTask.done()
93
+ } catch (e) {
94
+ if (e.code === "ABORT_ERR") {
95
+ buildTask.fail(`execute build command aborted`)
96
+ } else {
97
+ buildTask.fail()
98
+ throw e
99
+ }
100
+ }
101
+ }
102
+
103
+ const startServerTask = createTaskLog(logger, "start build server")
104
+ const server = await startServer({
105
+ signal,
106
+ stopOnExit: false,
107
+ stopOnSIGINT: false,
108
+ stopOnInternalError: false,
109
+ keepProcessAlive: true,
110
+ logLevel,
111
+ startLog: false,
112
+
113
+ protocol,
114
+ http2,
115
+ certificate,
116
+ privateKey,
117
+ listenAnyIp,
118
+ ip,
119
+ port,
120
+ plugins: {
121
+ ...pluginCORS({
122
+ accessControlAllowRequestOrigin: true,
123
+ accessControlAllowRequestMethod: true,
124
+ accessControlAllowRequestHeaders: true,
125
+ accessControlAllowedRequestHeaders: [
126
+ ...jsenvAccessControlAllowedHeaders,
127
+ "x-jsenv-execution-id",
128
+ ],
129
+ accessControlAllowCredentials: true,
130
+ }),
131
+ ...pluginServerTiming(),
132
+ ...pluginRequestWaitingCheck({
133
+ requestWaitingMs: 60 * 1000,
134
+ }),
135
+ },
136
+ sendErrorDetails: true,
137
+ requestToResponse: async (request) => {
138
+ await buildPromise
139
+ const urlIsVersioned = new URL(
140
+ request.ressource,
141
+ request.origin,
142
+ ).searchParams.has("v")
143
+ if (mainBuildFile && request.ressource === "/") {
144
+ request = {
145
+ ...request,
146
+ ressource: `/${mainBuildFile}`,
147
+ }
148
+ }
149
+ return fetchFileSystem(
150
+ new URL(request.ressource.slice(1), buildDirectoryUrl),
151
+ {
152
+ headers: request.headers,
153
+ cacheControl: urlIsVersioned
154
+ ? `private,max-age=${SECONDS_IN_30_DAYS},immutable`
155
+ : "private,max-age=0,must-revalidate",
156
+ etagEnabled: true,
157
+ compressionEnabled: !request.pathname.endsWith(".mp4"),
158
+ rootDirectoryUrl: buildDirectoryUrl,
159
+ canReadDirectory: true,
160
+ },
161
+ )
162
+ },
163
+ })
164
+ startServerTask.done()
165
+ logger.info(``)
166
+ Object.keys(server.origins).forEach((key) => {
167
+ logger.info(`- ${server.origins[key]}`)
168
+ })
169
+ logger.info(``)
170
+
171
+ const unregisterDirectoryLifecyle = watchFiles({
172
+ rootDirectoryUrl,
173
+ watchedFilePatterns,
174
+ cooldownBetweenFileEvents,
175
+ fileChangeCallback: ({ url, event }) => {
176
+ abortController.abort()
177
+ // setTimeout is to ensure the abortController.abort() above
178
+ // is properly taken into account so that logs about abort comes first
179
+ // then logs about re-running the build happens
180
+ setTimeout(() => {
181
+ logger.info(`${url.slice(rootDirectoryUrl.length)} ${event} -> rebuild`)
182
+ runBuild()
183
+ })
184
+ },
185
+ })
186
+ signal.addEventListener("abort", () => {
187
+ unregisterDirectoryLifecyle()
188
+ })
189
+ runBuild()
190
+ return {
191
+ origin: server.origin,
192
+ stop: () => server.stop(),
193
+ }
194
+ }
195
+
196
+ const SECONDS_IN_30_DAYS = 60 * 60 * 24 * 30
@@ -1,8 +1,8 @@
1
1
  import { readFileSync } from "node:fs"
2
- import { urlToContentType } from "@jsenv/server"
3
2
  import { collectFiles, normalizeStructuredMetaMap } from "@jsenv/filesystem"
4
3
 
5
4
  import { DataUrl } from "@jsenv/utils/urls/data_url.js"
5
+ import { CONTENT_TYPE } from "@jsenv/utils/content_type/content_type.js"
6
6
 
7
7
  export const jsenvPluginExplorer = ({ groups }) => {
8
8
  const htmlClientFileUrl = new URL("./client/explorer.html", import.meta.url)
@@ -43,7 +43,7 @@ export const jsenvPluginExplorer = ({ groups }) => {
43
43
  html = html.replace(
44
44
  "FAVICON_HREF",
45
45
  DataUrl.stringify({
46
- contentType: urlToContentType(faviconClientFileUrl),
46
+ contentType: CONTENT_TYPE.fromUrlExtension(faviconClientFileUrl),
47
47
  base64Flag: true,
48
48
  data: readFileSync(new URL(faviconClientFileUrl)).toString("base64"),
49
49
  }),
@@ -20,7 +20,7 @@ export const jsenvPluginToolbar = ({ logs = false } = {}) => {
20
20
  appliesDuring: {
21
21
  dev: true,
22
22
  },
23
- transform: {
23
+ transformUrlContent: {
24
24
  html: ({ url, content }, { referenceUtils }) => {
25
25
  if (url === toolbarHtmlClientFileUrl) {
26
26
  return null
@@ -28,10 +28,12 @@ export const jsenvPluginToolbar = ({ logs = false } = {}) => {
28
28
  const htmlAst = parseHtmlString(content)
29
29
  const [toolbarInjectorReference] = referenceUtils.inject({
30
30
  type: "js_import_export",
31
+ expectedType: "js_module",
31
32
  specifier: toolbarInjectorClientFileUrl,
32
33
  })
33
34
  const [toolbarClientFileReference] = referenceUtils.inject({
34
35
  type: "iframe_src",
36
+ expectedType: "html",
35
37
  specifier: toolbarHtmlClientFileUrl,
36
38
  })
37
39
  injectScriptAsEarlyAsPossible(