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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (247) hide show
  1. package/dist/babel_helpers/AsyncGenerator/AsyncGenerator.js +95 -0
  2. package/dist/babel_helpers/AwaitValue/AwaitValue.js +3 -0
  3. package/dist/babel_helpers/applyDecoratorDescriptor/applyDecoratorDescriptor.js +29 -0
  4. package/dist/babel_helpers/arrayLikeToArray/arrayLikeToArray.js +9 -0
  5. package/dist/babel_helpers/arrayWithHoles/arrayWithHoles.js +4 -0
  6. package/dist/babel_helpers/arrayWithoutHoles/arrayWithoutHoles.js +5 -0
  7. package/dist/babel_helpers/assertThisInitialized/assertThisInitialized.js +8 -0
  8. package/dist/babel_helpers/asyncGeneratorDelegate/asyncGeneratorDelegate.js +52 -0
  9. package/dist/babel_helpers/asyncIterator/asyncIterator.js +78 -0
  10. package/dist/babel_helpers/asyncToGenerator/asyncToGenerator.js +39 -0
  11. package/dist/babel_helpers/awaitAsyncGenerator/awaitAsyncGenerator.js +4 -0
  12. package/dist/babel_helpers/classApplyDescriptorDestructureSet/classApplyDescriptorDestructureSet.js +24 -0
  13. package/dist/babel_helpers/classApplyDescriptorGet/classApplyDescriptorGet.js +7 -0
  14. package/dist/babel_helpers/classApplyDescriptorSet/classApplyDescriptorSet.js +14 -0
  15. package/dist/babel_helpers/classCallCheck/classCallCheck.js +5 -0
  16. package/dist/babel_helpers/classCheckPrivateStaticAccess/classCheckPrivateStaticAccess.js +5 -0
  17. package/dist/babel_helpers/classCheckPrivateStaticFieldDescriptor/classCheckPrivateStaticFieldDescriptor.js +6 -0
  18. package/dist/babel_helpers/classExtractFieldDescriptor/classExtractFieldDescriptor.js +8 -0
  19. package/dist/babel_helpers/classNameTDZError/classNameTDZError.js +4 -0
  20. package/dist/babel_helpers/classPrivateFieldDestructureSet/classPrivateFieldDestructureSet.js +6 -0
  21. package/dist/babel_helpers/classPrivateFieldGet/classPrivateFieldGet.js +6 -0
  22. package/dist/babel_helpers/classPrivateFieldLooseBase/classPrivateFieldLooseBase.js +7 -0
  23. package/dist/babel_helpers/classPrivateFieldLooseKey/classPrivateFieldLooseKey.js +5 -0
  24. package/dist/babel_helpers/classPrivateFieldSet/classPrivateFieldSet.js +7 -0
  25. package/dist/babel_helpers/classPrivateMethodGet/classPrivateMethodGet.js +7 -0
  26. package/dist/babel_helpers/classPrivateMethodSet/classPrivateMethodSet.js +3 -0
  27. package/dist/babel_helpers/classStaticPrivateFieldSpecGet/classStaticPrivateFieldSpecGet.js +8 -0
  28. package/dist/babel_helpers/classStaticPrivateFieldSpecSet/classStaticPrivateFieldSpecSet.js +9 -0
  29. package/dist/babel_helpers/classStaticPrivateMethodGet/classStaticPrivateMethodGet.js +5 -0
  30. package/dist/babel_helpers/classStaticPrivateMethodSet/classStaticPrivateMethodSet.js +3 -0
  31. package/dist/babel_helpers/construct/construct.js +15 -0
  32. package/dist/babel_helpers/createClass/createClass.js +18 -0
  33. package/dist/babel_helpers/createForOfIteratorHelper/createForOfIteratorHelper.js +63 -0
  34. package/dist/babel_helpers/createForOfIteratorHelperLoose/createForOfIteratorHelperLoose.js +22 -0
  35. package/dist/babel_helpers/createRawReactElement/createRawReactElement.js +50 -0
  36. package/dist/babel_helpers/createSuper/createSuper.js +22 -0
  37. package/dist/babel_helpers/decorate/decorate.js +622 -0
  38. package/dist/babel_helpers/defaults/defaults.js +14 -0
  39. package/dist/babel_helpers/defineEnumerableProperties/defineEnumerableProperties.js +26 -0
  40. package/dist/babel_helpers/defineProperty/defineProperty.js +19 -0
  41. package/dist/babel_helpers/extends/extends.js +16 -0
  42. package/dist/babel_helpers/get/get.js +21 -0
  43. package/dist/babel_helpers/getPrototypeOf/getPrototypeOf.js +2 -0
  44. package/dist/babel_helpers/inherits/inherits.js +21 -0
  45. package/dist/babel_helpers/inheritsLoose/inheritsLoose.js +6 -0
  46. package/dist/babel_helpers/initializerDefineProperty/initializerDefineProperty.js +10 -0
  47. package/dist/babel_helpers/initializerWarningHelper/initializerWarningHelper.js +3 -0
  48. package/dist/babel_helpers/instanceof/instanceof.js +7 -0
  49. package/dist/babel_helpers/interopRequireDefault/interopRequireDefault.js +5 -0
  50. package/dist/babel_helpers/interopRequireWildcard/interopRequireWildcard.js +49 -0
  51. package/dist/babel_helpers/isNativeFunction/isNativeFunction.js +4 -0
  52. package/dist/babel_helpers/isNativeReflectConstruct/isNativeReflectConstruct.js +21 -0
  53. package/dist/babel_helpers/iterableToArray/iterableToArray.js +3 -0
  54. package/dist/babel_helpers/iterableToArrayLimit/iterableToArrayLimit.js +38 -0
  55. package/dist/babel_helpers/iterableToArrayLimitLoose/iterableToArrayLimitLoose.js +13 -0
  56. package/dist/babel_helpers/jsx/jsx.js +49 -0
  57. package/dist/babel_helpers/maybeArrayLike/maybeArrayLike.js +10 -0
  58. package/dist/babel_helpers/newArrowCheck/newArrowCheck.js +5 -0
  59. package/dist/babel_helpers/nonIterableRest/nonIterableRest.js +3 -0
  60. package/dist/babel_helpers/nonIterableSpread/nonIterableSpread.js +3 -0
  61. package/dist/babel_helpers/objectDestructuringEmpty/objectDestructuringEmpty.js +3 -0
  62. package/dist/babel_helpers/objectSpread/objectSpread.js +22 -0
  63. package/dist/babel_helpers/objectSpread2/objectSpread2.js +41 -0
  64. package/dist/babel_helpers/objectWithoutProperties/objectWithoutProperties.js +20 -0
  65. package/dist/babel_helpers/objectWithoutPropertiesLoose/objectWithoutPropertiesLoose.js +15 -0
  66. package/dist/babel_helpers/possibleConstructorReturn/possibleConstructorReturn.js +10 -0
  67. package/dist/babel_helpers/readOnlyError/readOnlyError.js +4 -0
  68. package/dist/babel_helpers/readme.md +8 -0
  69. package/dist/babel_helpers/set/set.js +51 -0
  70. package/dist/babel_helpers/setPrototypeOf/setPrototypeOf.js +5 -0
  71. package/dist/babel_helpers/skipFirstGeneratorNext/skipFirstGeneratorNext.js +8 -0
  72. package/dist/babel_helpers/slicedToArray/slicedToArray.js +5 -0
  73. package/dist/babel_helpers/slicedToArrayLoose/slicedToArrayLoose.js +7 -0
  74. package/dist/babel_helpers/superPropBase/superPropBase.js +10 -0
  75. package/dist/babel_helpers/taggedTemplateLiteral/taggedTemplateLiteral.js +11 -0
  76. package/dist/babel_helpers/taggedTemplateLiteralLoose/taggedTemplateLiteralLoose.js +8 -0
  77. package/dist/babel_helpers/tdz/tdz.js +4 -0
  78. package/dist/babel_helpers/temporalRef/temporalRef.js +5 -0
  79. package/dist/babel_helpers/temporalUndefined/temporalUndefined.js +3 -0
  80. package/dist/babel_helpers/toArray/toArray.js +5 -0
  81. package/dist/babel_helpers/toConsumableArray/toConsumableArray.js +5 -0
  82. package/dist/babel_helpers/toPrimitive/toPrimitive.js +14 -0
  83. package/dist/babel_helpers/toPropertyKey/toPropertyKey.js +5 -0
  84. package/dist/babel_helpers/typeof/typeof.js +7 -0
  85. package/dist/babel_helpers/unsupportedIterableToArray/unsupportedIterableToArray.js +10 -0
  86. package/dist/babel_helpers/wrapAsyncGenerator/wrapAsyncGenerator.js +7 -0
  87. package/dist/babel_helpers/wrapNativeSuper/wrapNativeSuper.js +35 -0
  88. package/dist/babel_helpers/wrapRegExp/wrapRegExp.js +67 -0
  89. package/dist/babel_helpers/writeOnlyError/writeOnlyError.js +4 -0
  90. package/dist/html/explorer.html +557 -0
  91. package/dist/js/controllable_file.mjs +227 -0
  92. package/dist/js/event_source_client.js +324 -0
  93. package/dist/js/global_this.js +32 -0
  94. package/dist/js/html_supervisor_installer.js +522 -0
  95. package/dist/js/html_supervisor_setup.js +79 -0
  96. package/dist/js/import_meta_hot.js +84 -0
  97. package/dist/js/inline_content.js +8 -0
  98. package/dist/js/new_stylesheet.js +409 -0
  99. package/dist/js/regenerator_runtime.js +721 -0
  100. package/dist/js/s.js +429 -0
  101. package/dist/main.js +13452 -0
  102. package/dist/other/jsenv.png +0 -0
  103. package/dist/s.js +626 -0
  104. package/dist/s.js.map +204 -0
  105. package/main.js +9 -1
  106. package/package.json +44 -32
  107. package/readme.md +6 -14
  108. package/src/build/build.js +1080 -562
  109. package/src/build/build_urls_generator.js +65 -24
  110. package/src/build/graph_utils.js +31 -0
  111. package/src/build/{inject_version_mappings.js → inject_global_version_mappings.js} +49 -18
  112. package/src/build/inject_service_worker_urls.js +79 -0
  113. package/src/build/resync_ressource_hints.js +115 -0
  114. package/src/build/start_build_server.js +211 -0
  115. package/src/dev/plugins/explorer/client/explorer.html +1 -1
  116. package/src/dev/plugins/explorer/jsenv_plugin_explorer.js +8 -12
  117. package/src/dev/plugins/toolbar/jsenv_plugin_toolbar.js +3 -1
  118. package/src/dev/start_dev_server.js +170 -38
  119. package/src/execute/execute.js +36 -6
  120. package/src/execute/run.js +21 -57
  121. package/src/execute/runtimes/browsers/from_playwright.js +218 -148
  122. package/src/execute/runtimes/node/controllable_file.mjs +26 -10
  123. package/src/execute/runtimes/node/node_execution_performance.js +67 -0
  124. package/src/execute/runtimes/node/node_process.js +288 -39
  125. package/src/omega/{runtime_support/features_compatibility.js → compat/features_compats.js} +30 -7
  126. package/src/omega/{runtime_support/runtime_support.js → compat/runtime_compat.js} +14 -16
  127. package/src/omega/errors.js +62 -66
  128. package/src/omega/fetched_content_compliance.js +24 -0
  129. package/src/omega/file_url_converter.js +9 -51
  130. package/src/omega/kitchen.js +593 -463
  131. package/src/omega/omega_server.js +2 -3
  132. package/src/omega/server/file_service.js +86 -38
  133. package/src/omega/server/user_agent.js +4 -2
  134. package/src/omega/url_graph/url_graph_load.js +31 -23
  135. package/src/omega/url_graph/url_graph_report.js +94 -51
  136. package/src/omega/url_graph/url_info_transformations.js +37 -17
  137. package/src/omega/url_graph.js +88 -19
  138. package/src/omega/url_specifier_encoding.js +59 -0
  139. package/src/omega/web_workers.js +42 -0
  140. package/src/{dev/plugins/autoreload → plugins/autoreload/dev_sse}/client/autoreload_preference.js +0 -0
  141. package/src/{dev/plugins/autoreload → plugins/autoreload/dev_sse}/client/event_source_client.js +19 -12
  142. package/src/{dev/plugins/autoreload → plugins/autoreload/dev_sse}/client/reload.js +0 -0
  143. package/src/{dev/plugins/autoreload → plugins/autoreload/dev_sse}/client/url_helpers.js +0 -0
  144. package/src/plugins/autoreload/dev_sse/jsenv_plugin_dev_sse_client.js +41 -0
  145. package/src/plugins/autoreload/dev_sse/jsenv_plugin_dev_sse_server.js +204 -0
  146. package/src/plugins/autoreload/jsenv_plugin_autoreload.js +25 -0
  147. package/src/plugins/autoreload/jsenv_plugin_hmr.js +35 -0
  148. package/src/plugins/bundling/css/bundle_css.js +140 -0
  149. package/src/plugins/bundling/js_classic_workers/bundle_js_classic_workers.js +13 -0
  150. package/src/plugins/bundling/js_module/bundle_js_module.js +342 -0
  151. package/src/plugins/bundling/jsenv_plugin_bundling.js +54 -0
  152. package/src/plugins/cache_control/jsenv_plugin_cache_control.js +34 -0
  153. package/src/{omega/core_plugins → plugins}/commonjs_globals/jsenv_plugin_commonjs_globals.js +54 -41
  154. package/src/plugins/file_urls/jsenv_plugin_file_urls.js +198 -0
  155. package/src/{omega/core_plugins → plugins}/html_supervisor/client/error_in_document.js +0 -0
  156. package/src/{omega/core_plugins → plugins}/html_supervisor/client/error_in_notification.js +0 -0
  157. package/src/plugins/html_supervisor/client/html_supervisor_installer.js +254 -0
  158. package/src/plugins/html_supervisor/client/html_supervisor_setup.js +79 -0
  159. package/src/{omega/core_plugins → plugins}/html_supervisor/client/perf_browser.js +0 -0
  160. package/src/{omega/core_plugins → plugins}/html_supervisor/client/uneval_exception.js +0 -0
  161. package/src/{omega/core_plugins → plugins}/html_supervisor/jsenv_plugin_html_supervisor.js +73 -55
  162. package/src/plugins/http_urls/jsenv_plugin_http_urls.js +12 -0
  163. package/src/{dev/plugins/autoreload → plugins/import_meta_hot}/babel_plugin_metadata_import_meta_hot.js +4 -5
  164. package/src/{dev/plugins/autoreload → plugins/import_meta_hot}/client/import_meta_hot.js +3 -1
  165. package/src/{dev/plugins/autoreload → plugins/import_meta_hot}/html_hot_dependencies.js +7 -4
  166. package/src/plugins/import_meta_hot/jsenv_plugin_import_meta_hot.js +100 -0
  167. package/src/{omega/core_plugins → plugins}/import_meta_scenarios/jsenv_plugin_import_meta_scenarios.js +33 -8
  168. package/src/plugins/import_meta_url/client/import_meta_url_browser.js +52 -0
  169. package/src/plugins/import_meta_url/client/import_meta_url_commonjs.mjs +9 -0
  170. package/src/{omega/core_plugins → plugins}/importmap/jsenv_plugin_importmap.js +40 -36
  171. package/src/plugins/inject_globals/jsenv_plugin_inject_globals.js +76 -0
  172. package/src/{omega/core_plugins → plugins}/inline/client/inline_content.js +0 -0
  173. package/src/{omega/core_plugins → plugins}/inline/jsenv_plugin_data_urls.js +19 -18
  174. package/src/plugins/inline/jsenv_plugin_html_inline_content.js +161 -0
  175. package/src/plugins/inline/jsenv_plugin_inline.js +36 -0
  176. package/src/{omega/core_plugins → plugins}/inline/jsenv_plugin_inline_query_param.js +7 -10
  177. package/src/plugins/inline/jsenv_plugin_js_inline_content.js +294 -0
  178. package/src/plugins/leading_slash/jsenv_plugin_leading_slash.js +13 -0
  179. package/src/plugins/minification/css/minify_css.js +9 -0
  180. package/src/plugins/minification/html/minify_html.js +15 -0
  181. package/src/{build/plugins/minify_js/jsenv_plugin_minify_js.js → plugins/minification/js/minify_js.js} +6 -22
  182. package/src/plugins/minification/jsenv_plugin_minification.js +78 -0
  183. package/src/plugins/minification/json/minify_json.js +8 -0
  184. package/src/plugins/node_esm_resolution/jsenv_plugin_node_esm_resolution.js +160 -0
  185. package/src/plugins/node_runtime/jsenv_plugin_node_runtime.js +12 -0
  186. package/src/{omega → plugins}/plugin_controller.js +56 -11
  187. package/src/plugins/plugins.js +92 -0
  188. package/src/plugins/transpilation/as_js_classic/client/s.js +429 -0
  189. package/src/plugins/transpilation/as_js_classic/helpers/babel_plugin_transform_import_meta_url.js +47 -0
  190. package/src/plugins/transpilation/as_js_classic/helpers/systemjs_old.js +43 -0
  191. package/src/plugins/transpilation/as_js_classic/jsenv_plugin_as_js_classic.js +213 -0
  192. package/src/plugins/transpilation/as_js_classic/jsenv_plugin_as_js_classic_html.js +304 -0
  193. package/src/plugins/transpilation/as_js_classic/jsenv_plugin_as_js_classic_workers.js +55 -0
  194. package/src/{omega/core_plugins → plugins/transpilation}/babel/global_this/babel_plugin_global_this_as_jsenv_import.js +0 -0
  195. package/src/{omega/core_plugins → plugins/transpilation}/babel/global_this/client/global_this.js +0 -0
  196. package/src/{omega/core_plugins → plugins/transpilation}/babel/helpers/babel_plugin_babel_helpers_as_jsenv_imports.js +0 -0
  197. package/src/{omega/core_plugins → plugins/transpilation}/babel/helpers/babel_plugin_structure.js +12 -16
  198. package/src/{omega/core_plugins → plugins/transpilation}/babel/helpers/babel_plugins_compatibility.js +0 -0
  199. package/src/{omega/core_plugins → plugins/transpilation}/babel/jsenv_plugin_babel.js +39 -32
  200. package/src/{omega/core_plugins → plugins/transpilation}/babel/new_stylesheet/babel_plugin_new_stylesheet_as_jsenv_import.js +30 -6
  201. package/src/{omega/core_plugins → plugins/transpilation}/babel/new_stylesheet/client/new_stylesheet.js +0 -0
  202. package/src/{omega/core_plugins → plugins/transpilation}/babel/regenerator_runtime/babel_plugin_regenerator_runtime_as_jsenv_import.js +0 -0
  203. package/src/{omega/core_plugins → plugins/transpilation}/babel/regenerator_runtime/client/regenerator_runtime.js +0 -0
  204. package/src/plugins/transpilation/css_parcel/jsenv_plugin_css_parcel.js +18 -0
  205. package/src/plugins/transpilation/import_assertions/jsenv_plugin_import_assertions.js +184 -0
  206. package/src/plugins/transpilation/jsenv_plugin_top_level_await.js +80 -0
  207. package/src/plugins/transpilation/jsenv_plugin_transpilation.js +46 -0
  208. package/src/plugins/url_analysis/css/css_urls.js +49 -0
  209. package/src/plugins/url_analysis/html/html_urls.js +272 -0
  210. package/src/plugins/url_analysis/js/js_urls.js +68 -0
  211. package/src/plugins/url_analysis/jsenv_plugin_url_analysis.js +102 -0
  212. package/src/plugins/url_analysis/webmanifest/webmanifest_urls.js +20 -0
  213. package/src/{omega/core_plugins → plugins}/url_resolution/jsenv_plugin_url_resolution.js +9 -5
  214. package/src/plugins/url_version/jsenv_plugin_url_version.js +28 -0
  215. package/src/test/execute_plan.js +81 -44
  216. package/src/test/execute_test_plan.js +37 -24
  217. package/src/test/execution_steps.js +1 -4
  218. package/src/test/logs_file_execution.js +56 -49
  219. package/src/build/plugins/bundle_js_module/jsenv_plugin_bundle_js_module.js +0 -225
  220. package/src/build/plugins/minify_html/jsenv_plugin_minify_html.js +0 -30
  221. package/src/dev/plugins/autoreload/client/event_source_connection.js +0 -195
  222. package/src/dev/plugins/autoreload/jsenv_plugin_autoreload.js +0 -374
  223. package/src/dev/plugins/autoreload/sse_service.js +0 -149
  224. package/src/execute/runtimes/node/controlled_process.js +0 -316
  225. package/src/omega/core_plugins/babel/new_stylesheet/client/.eslintrc.cjs +0 -24
  226. package/src/omega/core_plugins/file_urls/jsenv_plugin_file_urls.js +0 -67
  227. package/src/omega/core_plugins/filesystem_magic/jsenv_plugin_filesystem_magic.js +0 -58
  228. package/src/omega/core_plugins/html_supervisor/client/html_supervisor_installer.js +0 -168
  229. package/src/omega/core_plugins/html_supervisor/client/html_supervisor_setup.js +0 -77
  230. package/src/omega/core_plugins/import_assertions/helpers/babel_plugin_metadata_import_assertions.js +0 -98
  231. package/src/omega/core_plugins/import_assertions/helpers/json_module.js +0 -12
  232. package/src/omega/core_plugins/import_assertions/helpers/text_module.js +0 -6
  233. package/src/omega/core_plugins/import_assertions/jsenv_plugin_import_assertions.js +0 -211
  234. package/src/omega/core_plugins/inline/jsenv_plugin_inline.js +0 -13
  235. package/src/omega/core_plugins/inline/jsenv_plugin_js_and_css_inside_html.js +0 -142
  236. package/src/omega/core_plugins/inline/jsenv_plugin_new_inline_content.js +0 -207
  237. package/src/omega/core_plugins/leading_slash/jsenv_plugin_leading_slash.js +0 -12
  238. package/src/omega/core_plugins/node_esm_resolution/jsenv_plugin_node_esm_resolution.js +0 -77
  239. package/src/omega/core_plugins/url_version/jsenv_plugin_url_version.js +0 -50
  240. package/src/omega/core_plugins.js +0 -39
  241. package/src/omega/runtime_support/default_runtime_support.js +0 -13
  242. package/src/omega/url_graph/url_graph_sort.js +0 -29
  243. package/src/omega/url_mentions/css_url_mentions.js +0 -63
  244. package/src/omega/url_mentions/html_url_mentions.js +0 -185
  245. package/src/omega/url_mentions/js_module_url_mentions.js +0 -91
  246. package/src/omega/url_mentions/parse_url_mentions.js +0 -37
  247. package/src/omega/url_mentions/worker_classic_url_mentions.js +0 -37
@@ -1,10 +1,22 @@
1
- import { createCallbackList } from "@jsenv/abort"
2
- import { urlToRelativeUrl } from "@jsenv/filesystem"
1
+ import { urlToRelativeUrl } from "@jsenv/urls"
2
+ import { urlSpecifierEncoding } from "./url_specifier_encoding.js"
3
3
 
4
- export const createUrlGraph = () => {
4
+ export const createUrlGraph = ({
5
+ clientFileChangeCallbackList,
6
+ clientFilesPruneCallbackList,
7
+ } = {}) => {
5
8
  const urlInfos = {}
6
9
  const getUrlInfo = (url) => urlInfos[url]
7
- const deleteUrlInfo = (url) => delete urlInfos[url]
10
+ const deleteUrlInfo = (url) => {
11
+ const urlInfo = urlInfos[url]
12
+ if (urlInfo) {
13
+ delete urlInfos[url]
14
+ if (urlInfo.sourcemapReference) {
15
+ deleteUrlInfo(urlInfo.sourcemapReference.url)
16
+ }
17
+ }
18
+ }
19
+
8
20
  const reuseOrCreateUrlInfo = (url) => {
9
21
  const existingUrlInfo = urlInfos[url]
10
22
  if (existingUrlInfo) return existingUrlInfo
@@ -12,13 +24,15 @@ export const createUrlGraph = () => {
12
24
  urlInfos[url] = urlInfo
13
25
  return urlInfo
14
26
  }
15
- const inferReference = (url, parentUrl) => {
27
+ const inferReference = (specifier, parentUrl) => {
16
28
  const parentUrlInfo = urlInfos[parentUrl]
17
29
  if (!parentUrlInfo) {
18
30
  return null
19
31
  }
20
32
  const firstReferenceOnThatUrl = parentUrlInfo.references.find(
21
- (reference) => reference.url === url,
33
+ (reference) => {
34
+ return urlSpecifierEncoding.decode(reference) === specifier
35
+ },
22
36
  )
23
37
  return firstReferenceOnThatUrl
24
38
  }
@@ -40,13 +54,22 @@ export const createUrlGraph = () => {
40
54
  return visitDependents(urlInfo)
41
55
  }
42
56
 
43
- const prunedCallbackList = createCallbackList()
44
57
  const updateReferences = (urlInfo, references) => {
45
58
  const dependencyUrls = []
46
59
  references.forEach((reference) => {
47
- if (!dependencyUrls.includes(reference.url)) {
48
- dependencyUrls.push(reference.url)
60
+ if (reference.isRessourceHint) {
61
+ // ressource hint are a special kind of reference.
62
+ // They are a sort of weak reference to an url.
63
+ // We ignore them so that url referenced only by ressource hints
64
+ // have url.dependents.size === 0 and can be considered as not used
65
+ // It means html won't consider url referenced solely
66
+ // by <link> as dependency and it's fine
67
+ return
68
+ }
69
+ if (dependencyUrls.includes(reference.url)) {
70
+ return
49
71
  }
72
+ dependencyUrls.push(reference.url)
50
73
  })
51
74
  pruneDependencies(
52
75
  urlInfo,
@@ -82,7 +105,47 @@ export const createUrlGraph = () => {
82
105
  if (prunedUrlInfos.length === 0) {
83
106
  return
84
107
  }
85
- prunedCallbackList.notify({ prunedUrlInfos, firstUrlInfo })
108
+ prunedUrlInfos.forEach((prunedUrlInfo) => {
109
+ prunedUrlInfo.modifiedTimestamp = Date.now()
110
+ // should we delete?
111
+ // delete urlInfos[prunedUrlInfo.url]
112
+ })
113
+ if (clientFilesPruneCallbackList) {
114
+ clientFilesPruneCallbackList.forEach((callback) => {
115
+ callback({
116
+ firstUrlInfo,
117
+ prunedUrlInfos,
118
+ })
119
+ })
120
+ }
121
+ }
122
+
123
+ if (clientFileChangeCallbackList) {
124
+ const updateModifiedTimestamp = (urlInfo, modifiedTimestamp) => {
125
+ const seen = []
126
+ const iterate = (urlInfo) => {
127
+ if (seen.includes(urlInfo.url)) {
128
+ return
129
+ }
130
+ seen.push(urlInfo.url)
131
+ urlInfo.modifiedTimestamp = modifiedTimestamp
132
+ urlInfo.dependents.forEach((dependentUrl) => {
133
+ const dependentUrlInfo = urlInfos[dependentUrl]
134
+ const { hotAcceptDependencies = [] } = dependentUrlInfo.data
135
+ if (!hotAcceptDependencies.includes(urlInfo.url)) {
136
+ iterate(dependentUrlInfo)
137
+ }
138
+ })
139
+ }
140
+ iterate(urlInfo)
141
+ }
142
+ clientFileChangeCallbackList.push(({ url }) => {
143
+ const urlInfo = urlInfos[url]
144
+ if (urlInfo) {
145
+ updateModifiedTimestamp(urlInfo, Date.now())
146
+ urlInfo.contentEtag = null
147
+ }
148
+ })
86
149
  }
87
150
 
88
151
  return {
@@ -92,8 +155,6 @@ export const createUrlGraph = () => {
92
155
  deleteUrlInfo,
93
156
  inferReference,
94
157
  findDependent,
95
-
96
- prunedCallbackList,
97
158
  updateReferences,
98
159
 
99
160
  toJSON: (rootDirectoryUrl) => {
@@ -114,19 +175,27 @@ export const createUrlGraph = () => {
114
175
 
115
176
  const createUrlInfo = (url) => {
116
177
  return {
178
+ modifiedTimestamp: 0,
117
179
  data: {}, // plugins can put whatever they want here
180
+ references: [],
181
+ dependencies: new Set(),
182
+ dependents: new Set(),
183
+ type: undefined, // "html", "css", "js_classic", "js_module", "importmap", "json", "webmanifest", ...
184
+ subtype: undefined, // "worker", "service_worker", "shared_worker" for js, otherwise undefined
185
+ contentType: "", // "text/html", "text/css", "text/javascript", "application/json", ...
118
186
  url,
187
+ originalUrl: undefined,
119
188
  generatedUrl: null,
189
+ filename: "",
120
190
  isInline: false,
121
191
  inlineUrlSite: null,
122
- contentType: "",
123
- originalContent: "",
124
- content: "",
192
+ shouldHandle: undefined,
193
+ originalContent: undefined,
194
+ content: undefined,
195
+ contentEtag: null,
125
196
  sourcemap: null,
126
197
  sourcemapReference: null,
127
- type: "",
128
- references: [],
129
- dependencies: new Set(),
130
- dependents: new Set(),
198
+ timing: {},
199
+ responseHeaders: {},
131
200
  }
132
201
  }
@@ -0,0 +1,59 @@
1
+ export const urlSpecifierEncoding = {
2
+ encode: (reference) => {
3
+ const { generatedSpecifier } = reference
4
+ if (generatedSpecifier.then) {
5
+ return generatedSpecifier.then((value) => {
6
+ reference.generatedSpecifier = value
7
+ return urlSpecifierEncoding.encode(reference)
8
+ })
9
+ }
10
+ // allow plugin to return a function to bypas default formatting
11
+ // (which is to use JSON.stringify when url is referenced inside js)
12
+ if (typeof generatedSpecifier === "function") {
13
+ return generatedSpecifier()
14
+ }
15
+ const formatter = formatters[reference.type]
16
+ const value = formatter
17
+ ? formatter.encode(generatedSpecifier)
18
+ : generatedSpecifier
19
+ if (reference.escape) {
20
+ return reference.escape(value)
21
+ }
22
+ return value
23
+ },
24
+ decode: (reference) => {
25
+ const formatter = formatters[reference.type]
26
+ return formatter
27
+ ? formatter.decode(reference.generatedSpecifier)
28
+ : reference.generatedSpecifier
29
+ },
30
+ }
31
+ const formatters = {
32
+ "js_import_export": { encode: JSON.stringify, decode: JSON.parse },
33
+ "js_url_specifier": { encode: JSON.stringify, decode: JSON.parse },
34
+ "css_@import": { encode: JSON.stringify, code: JSON.stringify },
35
+ // https://github.com/webpack-contrib/css-loader/pull/627/files
36
+ "css_url": {
37
+ encode: (url) => {
38
+ // If url is already wrapped in quotes, remove them
39
+ url = formatters.css_url.decode(url)
40
+ // Should url be wrapped?
41
+ // See https://drafts.csswg.org/css-values-3/#urls
42
+ if (/["'() \t\n]/.test(url)) {
43
+ return `"${url.replace(/"/g, '\\"').replace(/\n/g, "\\n")}"`
44
+ }
45
+ return url
46
+ },
47
+ decode: (url) => {
48
+ const firstChar = url[0]
49
+ const lastChar = url[url.length - 1]
50
+ if (firstChar === `"` && lastChar === `"`) {
51
+ return url.slice(1, -1)
52
+ }
53
+ if (firstChar === `'` && lastChar === `'`) {
54
+ return url.slice(1, -1)
55
+ }
56
+ return url
57
+ },
58
+ },
59
+ }
@@ -0,0 +1,42 @@
1
+ // the following apis are creating js entry points:
2
+ // - new Worker()
3
+ // - new SharedWorker()
4
+ // - navigator.serviceWorker.register()
5
+ export const isWebWorkerEntryPointReference = (reference) => {
6
+ if (reference.subtype === "new_url_first_arg") {
7
+ return ["worker", "service_worker", "shared_worker"].includes(
8
+ reference.expectedSubtype,
9
+ )
10
+ }
11
+ return [
12
+ "new_worker_first_arg",
13
+ "new_shared_worker_first_arg",
14
+ "service_worker_register_first_arg",
15
+ ].includes(reference.subtype)
16
+ }
17
+
18
+ export const isWebWorkerUrlInfo = (urlInfo) => {
19
+ return (
20
+ urlInfo.subtype === "worker" ||
21
+ urlInfo.subtype === "service_worker" ||
22
+ urlInfo.subtype === "shared_worker"
23
+ )
24
+ }
25
+
26
+ // export const isEntryPoint = (urlInfo, urlGraph) => {
27
+ // if (urlInfo.data.isEntryPoint) {
28
+ // return true
29
+ // }
30
+ // if (isWebWorker(urlInfo)) {
31
+ // // - new Worker("a.js") -> "a.js" is an entry point
32
+ // // - self.importScripts("b.js") -> "b.js" is not an entry point
33
+ // // So the following logic applies to infer if the file is a web worker entry point
34
+ // // "When a non-webworker file references a worker file, the worker file is an entry point"
35
+ // const dependents = Array.from(urlInfo.dependents)
36
+ // return dependents.some((dependentUrl) => {
37
+ // const dependentUrlInfo = urlGraph.getUrlInfo(dependentUrl)
38
+ // return !isWebWorker(dependentUrlInfo)
39
+ // })
40
+ // }
41
+ // return false
42
+ // }
@@ -1,4 +1,5 @@
1
- import { createEventSourceConnection } from "./event_source_connection.js"
1
+ import { createEventSourceConnection } from "@jsenv/utils/event_source/event_source.js"
2
+ import { urlHotMetas } from "../../../import_meta_hot/client/import_meta_hot.js"
2
3
  import {
3
4
  isAutoreloadEnabled,
4
5
  setAutoreloadPreference,
@@ -9,7 +10,6 @@ import {
9
10
  reloadDOMNodesUsingUrl,
10
11
  reloadJsImport,
11
12
  } from "./reload.js"
12
- import { urlHotMetas } from "./import_meta_hot.js"
13
13
 
14
14
  const reloadMessages = []
15
15
  const reloadMessagesSignal = { onchange: () => {} }
@@ -26,13 +26,16 @@ const dequeue = async () => {
26
26
  const callbacks = pendingCallbacks.slice()
27
27
  pendingCallbacks = []
28
28
  running = true
29
- await callbacks.reduce(async (previous, callback) => {
30
- await previous
31
- await callback()
32
- }, Promise.resolve())
33
- running = false
34
- if (pendingCallbacks.length) {
35
- dequeue()
29
+ try {
30
+ await callbacks.reduce(async (previous, callback) => {
31
+ await previous
32
+ await callback()
33
+ }, Promise.resolve())
34
+ } finally {
35
+ running = false
36
+ if (pendingCallbacks.length) {
37
+ dequeue()
38
+ }
36
39
  }
37
40
  }
38
41
 
@@ -93,11 +96,15 @@ const applyHotReload = async ({ hotInstructions }) => {
93
96
  // if (!urlHotMeta) {return }
94
97
 
95
98
  if (type === "prune") {
96
- console.group(`[jsenv] prune: ${boundary} (inside ${acceptedBy})`)
99
+ console.groupCollapsed(
100
+ `[jsenv] prune: ${boundary} (inside ${acceptedBy})`,
101
+ )
97
102
  } else if (acceptedBy === boundary) {
98
- console.group(`[jsenv] hot reloading: ${boundary}`)
103
+ console.groupCollapsed(`[jsenv] hot reloading: ${boundary}`)
99
104
  } else {
100
- console.group(`[jsenv] hot reloading: ${acceptedBy} inside ${boundary}`)
105
+ console.groupCollapsed(
106
+ `[jsenv] hot reloading: ${acceptedBy} inside ${boundary}`,
107
+ )
101
108
  }
102
109
  if (urlHotMeta && urlHotMeta.disposeCallback) {
103
110
  console.log(`call dispose callback`)
@@ -0,0 +1,41 @@
1
+ import {
2
+ parseHtmlString,
3
+ stringifyHtmlAst,
4
+ injectScriptAsEarlyAsPossible,
5
+ createHtmlNode,
6
+ } from "@jsenv/utils/html_ast/html_ast.js"
7
+
8
+ export const jsenvPluginDevSSEClient = () => {
9
+ const eventSourceClientFileUrl = new URL(
10
+ "./client/event_source_client.js",
11
+ import.meta.url,
12
+ ).href
13
+
14
+ return {
15
+ name: "jsenv:dev_sse_client",
16
+ appliesDuring: { dev: true },
17
+ transformUrlContent: {
18
+ html: (htmlUrlInfo, context) => {
19
+ const htmlAst = parseHtmlString(htmlUrlInfo.content)
20
+ const [eventSourceClientReference] = context.referenceUtils.inject({
21
+ type: "script_src",
22
+ expectedType: "js_module",
23
+ specifier: eventSourceClientFileUrl,
24
+ })
25
+ injectScriptAsEarlyAsPossible(
26
+ htmlAst,
27
+ createHtmlNode({
28
+ "tagName": "script",
29
+ "type": "module",
30
+ "src": eventSourceClientReference.generatedSpecifier,
31
+ "injected-by": "jsenv:dev_sse_client",
32
+ }),
33
+ )
34
+ const htmlModified = stringifyHtmlAst(htmlAst)
35
+ return {
36
+ content: htmlModified,
37
+ }
38
+ },
39
+ },
40
+ }
41
+ }
@@ -0,0 +1,204 @@
1
+ import { urlToRelativeUrl } from "@jsenv/urls"
2
+ import { createCallbackList } from "@jsenv/abort"
3
+
4
+ import { createSSEService } from "@jsenv/utils/event_source/sse_service.js"
5
+
6
+ export const jsenvPluginDevSSEServer = ({
7
+ rootDirectoryUrl,
8
+ urlGraph,
9
+ clientFileChangeCallbackList,
10
+ clientFilesPruneCallbackList,
11
+ }) => {
12
+ const serverEventCallbackList = createCallbackList()
13
+ const sseService = createSSEService({ serverEventCallbackList })
14
+
15
+ const notifyDeclined = ({ cause, reason, declinedBy }) => {
16
+ serverEventCallbackList.notify({
17
+ type: "reload",
18
+ data: JSON.stringify({
19
+ cause,
20
+ type: "full",
21
+ typeReason: reason,
22
+ declinedBy,
23
+ }),
24
+ })
25
+ }
26
+ const notifyAccepted = ({ cause, reason, instructions }) => {
27
+ serverEventCallbackList.notify({
28
+ type: "reload",
29
+ data: JSON.stringify({
30
+ cause,
31
+ type: "hot",
32
+ typeReason: reason,
33
+ hotInstructions: instructions,
34
+ }),
35
+ })
36
+ }
37
+ const propagateUpdate = (firstUrlInfo) => {
38
+ const urlInfos = urlGraph.urlInfos
39
+ const iterate = (urlInfo, trace) => {
40
+ if (urlInfo.data.hotAcceptSelf) {
41
+ return {
42
+ accepted: true,
43
+ reason:
44
+ urlInfo === firstUrlInfo
45
+ ? `file accepts hot reload`
46
+ : `a dependent file accepts hot reload`,
47
+ instructions: [
48
+ {
49
+ type: urlInfo.type,
50
+ boundary: urlToRelativeUrl(urlInfo.url, rootDirectoryUrl),
51
+ acceptedBy: urlToRelativeUrl(urlInfo.url, rootDirectoryUrl),
52
+ },
53
+ ],
54
+ }
55
+ }
56
+ const { dependents } = urlInfo
57
+ const instructions = []
58
+ for (const dependentUrl of dependents) {
59
+ const dependentUrlInfo = urlInfos[dependentUrl]
60
+ if (dependentUrlInfo.data.hotDecline) {
61
+ return {
62
+ declined: true,
63
+ reason: `a dependent file declines hot reload`,
64
+ declinedBy: dependentUrl,
65
+ }
66
+ }
67
+ const { hotAcceptDependencies = [] } = dependentUrlInfo.data
68
+ if (hotAcceptDependencies.includes(urlInfo.url)) {
69
+ instructions.push({
70
+ type: dependentUrlInfo.type,
71
+ boundary: urlToRelativeUrl(dependentUrl, rootDirectoryUrl),
72
+ acceptedBy: urlToRelativeUrl(urlInfo.url, rootDirectoryUrl),
73
+ })
74
+ continue
75
+ }
76
+ if (trace.includes(dependentUrl)) {
77
+ return {
78
+ declined: true,
79
+ reason: "circular dependency",
80
+ declinedBy: urlToRelativeUrl(dependentUrl, rootDirectoryUrl),
81
+ }
82
+ }
83
+ const dependentPropagationResult = iterate(dependentUrlInfo, [
84
+ ...trace,
85
+ dependentUrl,
86
+ ])
87
+ if (dependentPropagationResult.accepted) {
88
+ instructions.push(...dependentPropagationResult.instructions)
89
+ continue
90
+ }
91
+ if (
92
+ // declined explicitely by an other file, it must decline the whole update
93
+ dependentPropagationResult.declinedBy
94
+ ) {
95
+ return dependentPropagationResult
96
+ }
97
+ // declined by absence of boundary, we can keep searching
98
+ continue
99
+ }
100
+ if (instructions.length === 0) {
101
+ return {
102
+ declined: true,
103
+ reason: `there is no file accepting hot reload while propagating update`,
104
+ }
105
+ }
106
+ return {
107
+ accepted: true,
108
+ reason: `${instructions.length} dependent file(s) accepts hot reload`,
109
+ instructions,
110
+ }
111
+ }
112
+ const trace = []
113
+ return iterate(firstUrlInfo, trace)
114
+ }
115
+ clientFileChangeCallbackList.push(({ url, event }) => {
116
+ const urlInfo = urlGraph.getUrlInfo(url)
117
+ // file not part of dependency graph
118
+ if (!urlInfo) {
119
+ return
120
+ }
121
+ const relativeUrl = urlToRelativeUrl(url, rootDirectoryUrl)
122
+ const hotUpdate = propagateUpdate(urlInfo)
123
+ if (hotUpdate.declined) {
124
+ notifyDeclined({
125
+ cause: `${relativeUrl} ${event}`,
126
+ reason: hotUpdate.reason,
127
+ declinedBy: hotUpdate.declinedBy,
128
+ })
129
+ } else {
130
+ notifyAccepted({
131
+ cause: `${relativeUrl} ${event}`,
132
+ reason: hotUpdate.reason,
133
+ instructions: hotUpdate.instructions,
134
+ })
135
+ }
136
+ })
137
+ clientFilesPruneCallbackList.push(({ prunedUrlInfos, firstUrlInfo }) => {
138
+ const mainHotUpdate = propagateUpdate(firstUrlInfo)
139
+ const cause = `following files are no longer referenced: ${prunedUrlInfos.map(
140
+ (prunedUrlInfo) => urlToRelativeUrl(prunedUrlInfo.url, rootDirectoryUrl),
141
+ )}`
142
+ // now check if we can hot update the main ressource
143
+ // then if we can hot update all dependencies
144
+ if (mainHotUpdate.declined) {
145
+ notifyDeclined({
146
+ cause,
147
+ reason: mainHotUpdate.reason,
148
+ declinedBy: mainHotUpdate.declinedBy,
149
+ })
150
+ return
151
+ }
152
+ // main can hot update
153
+ let i = 0
154
+ const instructions = []
155
+ while (i < prunedUrlInfos.length) {
156
+ const prunedUrlInfo = prunedUrlInfos[i++]
157
+ if (prunedUrlInfo.data.hotDecline) {
158
+ notifyDeclined({
159
+ cause,
160
+ reason: `a pruned file declines hot reload`,
161
+ declinedBy: urlToRelativeUrl(prunedUrlInfo.url, rootDirectoryUrl),
162
+ })
163
+ return
164
+ }
165
+ instructions.push({
166
+ type: "prune",
167
+ boundary: urlToRelativeUrl(prunedUrlInfo.url, rootDirectoryUrl),
168
+ acceptedBy: urlToRelativeUrl(firstUrlInfo.url, rootDirectoryUrl),
169
+ })
170
+ }
171
+ notifyAccepted({
172
+ cause,
173
+ reason: mainHotUpdate.reason,
174
+ instructions,
175
+ })
176
+ })
177
+
178
+ return {
179
+ name: "jsenv:sse_server",
180
+ appliesDuring: { dev: true },
181
+ serve: (request) => {
182
+ if (request.ressource === "/__graph__") {
183
+ const graphJson = JSON.stringify(urlGraph.toJSON(rootDirectoryUrl))
184
+ return {
185
+ status: 200,
186
+ headers: {
187
+ "content-type": "application/json",
188
+ "content-length": Buffer.byteLength(graphJson),
189
+ },
190
+ body: graphJson,
191
+ }
192
+ }
193
+ const { accept } = request.headers
194
+ if (accept && accept.includes("text/event-stream")) {
195
+ const room = sseService.getOrCreateSSERoom(request)
196
+ return room.join(request)
197
+ }
198
+ return null
199
+ },
200
+ destroy: () => {
201
+ sseService.destroy()
202
+ },
203
+ }
204
+ }
@@ -0,0 +1,25 @@
1
+ import { jsenvPluginHmr } from "./jsenv_plugin_hmr.js"
2
+ import { jsenvPluginDevSSEClient } from "./dev_sse/jsenv_plugin_dev_sse_client.js"
3
+ import { jsenvPluginDevSSEServer } from "./dev_sse/jsenv_plugin_dev_sse_server.js"
4
+
5
+ export const jsenvPluginAutoreload = ({
6
+ rootDirectoryUrl,
7
+ urlGraph,
8
+ scenario,
9
+ clientFileChangeCallbackList,
10
+ clientFilesPruneCallbackList,
11
+ }) => {
12
+ if (scenario === "build") {
13
+ return []
14
+ }
15
+ return [
16
+ jsenvPluginHmr(),
17
+ jsenvPluginDevSSEClient(),
18
+ jsenvPluginDevSSEServer({
19
+ rootDirectoryUrl,
20
+ urlGraph,
21
+ clientFileChangeCallbackList,
22
+ clientFilesPruneCallbackList,
23
+ }),
24
+ ]
25
+ }
@@ -0,0 +1,35 @@
1
+ export const jsenvPluginHmr = () => {
2
+ return {
3
+ name: "jsenv:hmr",
4
+ appliesDuring: { dev: true },
5
+ redirectUrl: (reference) => {
6
+ const urlObject = new URL(reference.url)
7
+ if (!urlObject.searchParams.has("hmr")) {
8
+ reference.data.hmr = false
9
+ return null
10
+ }
11
+ reference.data.hmr = true
12
+ // "hmr" search param goal is to mark url as enabling hmr:
13
+ // this goal is achieved when we reach this part of the code
14
+ // We get rid of this params so that urlGraph and other parts of the code
15
+ // recognize the url (it is not considered as a different url)
16
+ urlObject.searchParams.delete("hmr")
17
+ urlObject.searchParams.delete("v")
18
+ return urlObject.href
19
+ },
20
+ transformUrlSearchParams: (reference, context) => {
21
+ const parentUrlInfo = context.urlGraph.getUrlInfo(reference.parentUrl)
22
+ if (!parentUrlInfo || !parentUrlInfo.data.hmr) {
23
+ return null
24
+ }
25
+ const urlInfo = context.urlGraph.getUrlInfo(reference.url)
26
+ if (!urlInfo.modifiedTimestamp) {
27
+ return null
28
+ }
29
+ return {
30
+ hmr: "",
31
+ v: urlInfo.modifiedTimestamp,
32
+ }
33
+ },
34
+ }
35
+ }