@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,28 +1,37 @@
1
- import { urlToFilename } from "@jsenv/filesystem"
1
+ import { urlToFilename, urlToRelativeUrl } from "@jsenv/urls"
2
2
 
3
- import { memoizeByUrl } from "@jsenv/utils/memoize/memoize_by_url.js"
3
+ import { memoizeByFirstArgument } from "@jsenv/utils/memoize/memoize_by_first_argument.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)
7
+
8
+ const getUrlName = (url, urlInfo) => {
9
+ if (!urlInfo) {
10
+ return urlToFilename(url)
11
+ }
12
+ if (urlInfo.filename) {
13
+ return urlInfo.filename
14
+ }
15
+ return urlToFilename(url)
16
+ }
17
+
18
+ const generate = memoizeByFirstArgument((url, { urlInfo, parentUrlInfo }) => {
19
+ const directoryPath = determineDirectoryPath({
20
+ buildDirectoryUrl,
21
+ urlInfo,
22
+ parentUrlInfo,
23
+ })
9
24
  let names = cache[directoryPath]
10
25
  if (!names) {
11
26
  names = []
12
27
  cache[directoryPath] = names
13
28
  }
14
-
15
- let name = urlToFilename(url)
16
- const { searchParams } = new URL(url)
17
- if (
18
- searchParams.has("css_module") ||
19
- searchParams.has("json_module") ||
20
- searchParams.has("text_module")
21
- ) {
22
- name = `${name}.js`
23
- }
24
- const [basename, extension] = splitFileExtension(name)
25
- let nameCandidate = name
29
+ const urlObject = new URL(url)
30
+ let { search, hash } = urlObject
31
+ let name = getUrlName(url, urlInfo)
32
+ let [basename, extension] = splitFileExtension(name)
33
+ extension = extensionMappings[extension] || extension
34
+ let nameCandidate = `${basename}${extension}` // reconstruct name in case extension was normalized
26
35
  let integer = 1
27
36
  // eslint-disable-next-line no-constant-condition
28
37
  while (true) {
@@ -33,7 +42,7 @@ export const createBuilUrlsGenerator = ({ buildDirectoryUrl }) => {
33
42
  integer++
34
43
  nameCandidate = `${basename}${integer}${extension}`
35
44
  }
36
- return `${buildDirectoryUrl}${directoryPath}${nameCandidate}`
45
+ return `${buildDirectoryUrl}${directoryPath}${nameCandidate}${search}${hash}`
37
46
  })
38
47
 
39
48
  return {
@@ -41,6 +50,18 @@ export const createBuilUrlsGenerator = ({ buildDirectoryUrl }) => {
41
50
  }
42
51
  }
43
52
 
53
+ // It's best to generate files with an extension representing what is inside the file
54
+ // and after build js files contains solely js (js or typescript is gone).
55
+ // This way a static file server is already configured to server the correct content-type
56
+ // (otherwise one would have to configure that ".jsx" is "text/javascript")
57
+ // To keep in mind: if you have "user.jsx" and "user.js" AND both file are not bundled
58
+ // you end up with "dist/js/user.js" and "dist/js/user2.js"
59
+ const extensionMappings = {
60
+ ".jsx": ".js",
61
+ ".ts": ".js",
62
+ ".tsx": ".js",
63
+ }
64
+
44
65
  const splitFileExtension = (filename) => {
45
66
  const dotLastIndex = filename.lastIndexOf(".")
46
67
  if (dotLastIndex === -1) {
@@ -49,12 +70,32 @@ const splitFileExtension = (filename) => {
49
70
  return [filename.slice(0, dotLastIndex), filename.slice(dotLastIndex)]
50
71
  }
51
72
 
52
- const determineDirectoryPath = (urlInfo, parentUrlInfo) => {
73
+ const determineDirectoryPath = ({
74
+ buildDirectoryUrl,
75
+ urlInfo,
76
+ parentUrlInfo,
77
+ }) => {
78
+ if (urlInfo.type === "directory") {
79
+ return ""
80
+ }
81
+ if (parentUrlInfo && parentUrlInfo.type === "directory") {
82
+ const parentDirectoryPath = urlToRelativeUrl(
83
+ parentUrlInfo.url,
84
+ buildDirectoryUrl,
85
+ )
86
+ return parentDirectoryPath
87
+ }
53
88
  if (urlInfo.isInline) {
54
- const parentDirectoryPath = determineDirectoryPath(parentUrlInfo)
89
+ const parentDirectoryPath = determineDirectoryPath({
90
+ buildDirectoryUrl,
91
+ urlInfo: parentUrlInfo,
92
+ })
55
93
  return parentDirectoryPath
56
94
  }
57
- if (urlInfo.data.isEntryPoint) {
95
+ if (urlInfo.data.isEntryPoint || urlInfo.data.isWebWorkerEntryPoint) {
96
+ return ""
97
+ }
98
+ if (urlInfo.type === "importmap") {
58
99
  return ""
59
100
  }
60
101
  if (urlInfo.type === "html") {
@@ -64,10 +105,10 @@ const determineDirectoryPath = (urlInfo, parentUrlInfo) => {
64
105
  return "css/"
65
106
  }
66
107
  if (urlInfo.type === "js_module" || urlInfo.type === "js_classic") {
67
- if (urlInfo.subtype === "service_worker") {
68
- return ""
69
- }
70
108
  return "js/"
71
109
  }
72
- return "assets/"
110
+ if (urlInfo.type === "json") {
111
+ return "json/"
112
+ }
113
+ return "other/"
73
114
  }
@@ -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,16 @@ export const injectVersionMappings = async (
22
39
  }
23
40
  }
24
41
 
42
+ const jsInjector = (urlInfo, { versionMappings }) => {
43
+ const magicSource = createMagicSource(urlInfo.content)
44
+ magicSource.prepend(
45
+ generateClientCodeForVersionMappings(versionMappings, {
46
+ globalName: urlInfo.data.isWebWorkerEntryPoint ? "self" : "window",
47
+ }),
48
+ )
49
+ return magicSource.toContentAndSourcemap()
50
+ }
51
+
25
52
  const injectors = {
26
53
  html: (urlInfo, { versionMappings }) => {
27
54
  // ideally we would inject an importmap but browser support is too low
@@ -34,29 +61,33 @@ const injectors = {
34
61
  htmlAst,
35
62
  createHtmlNode({
36
63
  "tagName": "script",
37
- "textContent": generateClientCodeForVersionMappings(versionMappings),
64
+ "textContent": generateClientCodeForVersionMappings(versionMappings, {
65
+ globalName: "window",
66
+ }),
38
67
  "injected-by": "jsenv:versioning",
39
68
  }),
40
69
  )
41
70
  return {
42
- content: stringifyHtmlAst(htmlAst, {
43
- removeOriginalPositionAttributes: true,
44
- }),
71
+ content: stringifyHtmlAst(htmlAst),
45
72
  }
46
73
  },
47
- js_module: (urlInfo, { versionMappings }) => {
48
- const magicSource = createMagicSource(urlInfo.content)
49
- magicSource.prepend(generateClientCodeForVersionMappings(versionMappings))
50
- return magicSource.toContentAndSourcemap()
51
- },
74
+ js_classic: jsInjector,
75
+ js_module: jsInjector,
52
76
  }
53
77
 
54
- const generateClientCodeForVersionMappings = (versionMappings) => {
78
+ const generateClientCodeForVersionMappings = (
79
+ versionMappings,
80
+ { globalName },
81
+ ) => {
55
82
  return `
56
- var __versionMappings__ = ${JSON.stringify(versionMappings, null, " ")}
57
- var __envGlobal__ = typeof self === 'undefined' ? global : self
58
- __envGlobal__.__v__ = function (specifier) {
83
+ ;(function() {
84
+
85
+ var __versionMappings__ = ${JSON.stringify(versionMappings, null, " ")};
86
+ ${globalName}.__v__ = function (specifier) {
59
87
  return __versionMappings__[specifier] || specifier
60
- }
88
+ };
89
+
90
+ })();
91
+
61
92
  `
62
93
  }
@@ -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.shouldHandle) {
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,115 @@
1
+ /*
2
+ * Update <link rel="preload"> and friends after build (once we know everything)
3
+ *
4
+ * - Used to remove ressource hint targeting an url that is no longer used:
5
+ * - Happens because of import assertions transpilation (file is inlined into JS)
6
+ */
7
+
8
+ import {
9
+ parseHtmlString,
10
+ visitHtmlAst,
11
+ stringifyHtmlAst,
12
+ getHtmlNodeAttributeByName,
13
+ removeHtmlNode,
14
+ } from "@jsenv/utils/html_ast/html_ast.js"
15
+
16
+ import { GRAPH } from "./graph_utils.js"
17
+
18
+ export const resyncRessourceHints = async ({
19
+ logger,
20
+ finalGraphKitchen,
21
+ finalGraph,
22
+ rawUrls,
23
+ postBuildRedirections,
24
+ }) => {
25
+ const ressourceHintActions = []
26
+ GRAPH.forEach(finalGraph, (urlInfo) => {
27
+ if (urlInfo.type !== "html") {
28
+ return
29
+ }
30
+ ressourceHintActions.push(async () => {
31
+ const htmlAst = parseHtmlString(urlInfo.content, {
32
+ storeOriginalPositions: false,
33
+ })
34
+ const actions = []
35
+ const visitLinkWithHref = (linkNode, hrefAttribute) => {
36
+ const href = hrefAttribute.value
37
+ if (!href || href.startsWith("data:")) {
38
+ return
39
+ }
40
+ const relAttribute = getHtmlNodeAttributeByName(linkNode, "rel")
41
+ const rel = relAttribute ? relAttribute.value : undefined
42
+ const isRessourceHint = [
43
+ "preconnect",
44
+ "dns-prefetch",
45
+ "prefetch",
46
+ "preload",
47
+ "modulepreload",
48
+ ].includes(rel)
49
+ if (!isRessourceHint) {
50
+ return
51
+ }
52
+
53
+ let buildUrl
54
+ for (const key of Object.keys(rawUrls)) {
55
+ if (rawUrls[key] === href) {
56
+ buildUrl = key
57
+ break
58
+ }
59
+ }
60
+ if (!buildUrl) {
61
+ logger.warn(`remove ressource hint because cannot find "${href}"`)
62
+ actions.push(() => {
63
+ removeHtmlNode(linkNode)
64
+ })
65
+ return
66
+ }
67
+ buildUrl = postBuildRedirections[buildUrl] || buildUrl
68
+ const urlInfo = finalGraph.getUrlInfo(buildUrl)
69
+ if (!urlInfo) {
70
+ logger.warn(
71
+ `remove ressource hint because cannot find "${buildUrl}" in the graph`,
72
+ )
73
+ actions.push(() => {
74
+ removeHtmlNode(linkNode)
75
+ })
76
+ return
77
+ }
78
+ if (urlInfo.dependents.size === 0) {
79
+ logger.info(
80
+ `remove ressource hint because "${href}" not used anymore`,
81
+ )
82
+ actions.push(() => {
83
+ removeHtmlNode(linkNode)
84
+ })
85
+ return
86
+ }
87
+ actions.push(() => {
88
+ hrefAttribute.value = urlInfo.data.buildUrlSpecifier
89
+ })
90
+ }
91
+ visitHtmlAst(htmlAst, (node) => {
92
+ if (node.nodeName !== "link") {
93
+ return
94
+ }
95
+ const hrefAttribute = getHtmlNodeAttributeByName(node, "href")
96
+ if (!hrefAttribute) {
97
+ return
98
+ }
99
+ visitLinkWithHref(node, hrefAttribute)
100
+ })
101
+ if (actions.length) {
102
+ actions.forEach((action) => action())
103
+ await finalGraphKitchen.urlInfoTransformer.applyFinalTransformations(
104
+ urlInfo,
105
+ {
106
+ content: stringifyHtmlAst(htmlAst),
107
+ },
108
+ )
109
+ }
110
+ })
111
+ })
112
+ await Promise.all(
113
+ ressourceHintActions.map((ressourceHintAction) => ressourceHintAction()),
114
+ )
115
+ }
@@ -0,0 +1,210 @@
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 { parentPort } from "node:worker_threads"
17
+ import {
18
+ jsenvAccessControlAllowedHeaders,
19
+ startServer,
20
+ pluginServerTiming,
21
+ pluginRequestWaitingCheck,
22
+ pluginCORS,
23
+ fetchFileSystem,
24
+ composeServices,
25
+ } from "@jsenv/server"
26
+
27
+ import {
28
+ assertAndNormalizeDirectoryUrl,
29
+ registerDirectoryLifecycle,
30
+ } from "@jsenv/filesystem"
31
+ import { createLogger, loggerToLevels, createTaskLog } from "@jsenv/log"
32
+ import { getCallerPosition } from "@jsenv/urls"
33
+ import { initReloadableProcess } from "@jsenv/utils/process_reload/process_reload.js"
34
+
35
+ export const startBuildServer = async ({
36
+ signal = new AbortController().signal,
37
+ handleSIGINT = true,
38
+ logLevel,
39
+ serverLogLevel = "warn",
40
+ protocol = "http",
41
+ http2,
42
+ certificate,
43
+ privateKey,
44
+ listenAnyIp,
45
+ ip,
46
+ port = 9779,
47
+ services = {},
48
+
49
+ rootDirectoryUrl,
50
+ buildDirectoryUrl,
51
+ mainBuildFileUrl = "/index.html",
52
+ buildServerFiles = {
53
+ "./package.json": true,
54
+ "./jsenv.config.mjs": true,
55
+ },
56
+ buildServerMainFile = getCallerPosition().url,
57
+ // force disable server autoreload when this code is executed:
58
+ // - inside a forked child process
59
+ // - inside a worker thread
60
+ // (because node cluster won't work)
61
+ buildServerAutoreload = typeof process.send !== "function" &&
62
+ !parentPort &&
63
+ !process.env.VSCODE_INSPECTOR_OPTIONS,
64
+ cooldownBetweenFileEvents,
65
+ }) => {
66
+ const logger = createLogger({ logLevel })
67
+ rootDirectoryUrl = assertAndNormalizeDirectoryUrl(rootDirectoryUrl)
68
+ buildDirectoryUrl = assertAndNormalizeDirectoryUrl(buildDirectoryUrl)
69
+
70
+ const reloadableProcess = await initReloadableProcess({
71
+ signal,
72
+ handleSIGINT,
73
+ ...(buildServerAutoreload
74
+ ? {
75
+ enabled: true,
76
+ logLevel: "info",
77
+ fileToRestart: buildServerMainFile,
78
+ }
79
+ : {
80
+ enabled: false,
81
+ }),
82
+ })
83
+ if (reloadableProcess.isPrimary) {
84
+ const buildServerFileChangeCallback = ({ relativeUrl, event }) => {
85
+ const url = new URL(relativeUrl, rootDirectoryUrl).href
86
+ if (buildServerAutoreload) {
87
+ logger.info(`file ${event} ${url} -> restarting server...`)
88
+ reloadableProcess.reload()
89
+ }
90
+ }
91
+ const stopWatchingBuildServerFiles = registerDirectoryLifecycle(
92
+ rootDirectoryUrl,
93
+ {
94
+ watchPatterns: {
95
+ [buildServerMainFile]: true,
96
+ ...buildServerFiles,
97
+ },
98
+ cooldownBetweenFileEvents,
99
+ keepProcessAlive: false,
100
+ recursive: true,
101
+ added: ({ relativeUrl }) => {
102
+ buildServerFileChangeCallback({ relativeUrl, event: "added" })
103
+ },
104
+ updated: ({ relativeUrl }) => {
105
+ buildServerFileChangeCallback({ relativeUrl, event: "modified" })
106
+ },
107
+ removed: ({ relativeUrl }) => {
108
+ buildServerFileChangeCallback({ relativeUrl, event: "removed" })
109
+ },
110
+ },
111
+ )
112
+ signal.addEventListener("abort", () => {
113
+ stopWatchingBuildServerFiles()
114
+ })
115
+ return {
116
+ origin: `${protocol}://127.0.0.1:${port}`,
117
+ stop: () => {
118
+ stopWatchingBuildServerFiles()
119
+
120
+ reloadableProcess.stop()
121
+ },
122
+ }
123
+ }
124
+ signal = reloadableProcess.signal
125
+
126
+ const startBuildServerTask = createTaskLog("start build server", {
127
+ disabled: !loggerToLevels(logger).info,
128
+ })
129
+ const server = await startServer({
130
+ signal,
131
+ stopOnExit: false,
132
+ stopOnSIGINT: false,
133
+ stopOnInternalError: false,
134
+ keepProcessAlive: true,
135
+ logLevel: serverLogLevel,
136
+ startLog: false,
137
+
138
+ protocol,
139
+ http2,
140
+ certificate,
141
+ privateKey,
142
+ listenAnyIp,
143
+ ip,
144
+ port,
145
+ plugins: {
146
+ ...pluginCORS({
147
+ accessControlAllowRequestOrigin: true,
148
+ accessControlAllowRequestMethod: true,
149
+ accessControlAllowRequestHeaders: true,
150
+ accessControlAllowedRequestHeaders: jsenvAccessControlAllowedHeaders,
151
+ accessControlAllowCredentials: true,
152
+ }),
153
+ ...pluginServerTiming(),
154
+ ...pluginRequestWaitingCheck({
155
+ requestWaitingMs: 60 * 1000,
156
+ }),
157
+ },
158
+ sendErrorDetails: true,
159
+ requestToResponse: composeServices({
160
+ ...services,
161
+ build_files_service: createBuildFilesService({
162
+ buildDirectoryUrl,
163
+ mainBuildFileUrl,
164
+ }),
165
+ }),
166
+ })
167
+ startBuildServerTask.done()
168
+ logger.info(``)
169
+ Object.keys(server.origins).forEach((key) => {
170
+ logger.info(`- ${server.origins[key]}`)
171
+ })
172
+ logger.info(``)
173
+
174
+ return {
175
+ origin: server.origin,
176
+ stop: () => {
177
+ server.stop()
178
+ },
179
+ }
180
+ }
181
+
182
+ const createBuildFilesService = ({ buildDirectoryUrl, mainBuildFileUrl }) => {
183
+ return (request) => {
184
+ const urlIsVersioned = new URL(
185
+ request.ressource,
186
+ request.origin,
187
+ ).searchParams.has("v")
188
+ if (mainBuildFileUrl && request.ressource === "/") {
189
+ request = {
190
+ ...request,
191
+ ressource: mainBuildFileUrl,
192
+ }
193
+ }
194
+ return fetchFileSystem(
195
+ new URL(request.ressource.slice(1), buildDirectoryUrl),
196
+ {
197
+ headers: request.headers,
198
+ cacheControl: urlIsVersioned
199
+ ? `private,max-age=${SECONDS_IN_30_DAYS},immutable`
200
+ : "private,max-age=0,must-revalidate",
201
+ etagEnabled: true,
202
+ compressionEnabled: !request.pathname.endsWith(".mp4"),
203
+ rootDirectoryUrl: buildDirectoryUrl,
204
+ canReadDirectory: true,
205
+ },
206
+ )
207
+ }
208
+ }
209
+
210
+ const SECONDS_IN_30_DAYS = 60 * 60 * 24 * 30
@@ -4,7 +4,7 @@
4
4
  <title>Exploring</title>
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1" />
6
6
  <meta charset="utf-8" />
7
- <link rel="icon" href="FAVICON_HREF" />
7
+ <link rel="icon" href="virtual:FAVICON_HREF" />
8
8
  <style>
9
9
  button:focus,
10
10
  a:focus,