@jsenv/core 24.2.2 → 24.4.0

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 (156) hide show
  1. package/dist/browser_runtime/browser_runtime-fbd309a1.js +5137 -0
  2. package/dist/browser_runtime/browser_runtime-fbd309a1.js.map +1064 -0
  3. package/dist/{jsenv_browser_system.js → browser_system/browser_system-29eda202.js} +12 -12
  4. package/dist/{jsenv_browser_system.js.map → browser_system/browser_system-29eda202.js.map} +64 -64
  5. package/dist/build_manifest.js +12 -0
  6. package/dist/compile_proxy/assets/s.js-749702e8.map +242 -0
  7. package/dist/compile_proxy/compile_proxy-405777e6.html +2074 -0
  8. package/dist/compile_proxy/compile_proxy.html__inline__20-39c0801c.js.map +385 -0
  9. package/dist/{jsenv_event_source_client.js → event_source_client/event_source_client-9f14c8b9.js} +39 -21
  10. package/dist/event_source_client/event_source_client-9f14c8b9.js.map +127 -0
  11. package/dist/redirector/assets/s.js-749702e8.map +242 -0
  12. package/dist/redirector/redirector-237cd168.html +2118 -0
  13. package/dist/redirector/redirector.html__inline__15-33acb0b9.js.map +390 -0
  14. package/dist/toolbar/assets/compilation.css-209d68b4.map +12 -0
  15. package/dist/toolbar/assets/eventsource.css-38cd0a36.map +12 -0
  16. package/dist/toolbar/assets/execution.css-0ebe522f.map +12 -0
  17. package/dist/toolbar/assets/focus.css-3f9c156d.map +12 -0
  18. package/dist/toolbar/assets/light-theme.css-78b19a80.map +12 -0
  19. package/dist/toolbar/assets/overflow-menu.css-d9688a1c.map +12 -0
  20. package/dist/toolbar/assets/s.js-749702e8.map +242 -0
  21. package/dist/toolbar/assets/settings.css-2b81b245.map +12 -0
  22. package/dist/toolbar/assets/toolbar.main.css-846920e9.map +28 -0
  23. package/dist/toolbar/assets/tooltip.css-03395ee6.map +12 -0
  24. package/dist/toolbar/toolbar-29e91dcd.html +4779 -0
  25. package/dist/toolbar/toolbar.main-53e1ab2b.js.map +795 -0
  26. package/dist/toolbar_injector/assets/jsenv-logo-188b9ca6.svg +95 -0
  27. package/dist/{jsenv_toolbar_injector.js → toolbar_injector/toolbar_injector-0af91b43.js} +87 -65
  28. package/dist/toolbar_injector/toolbar_injector-0af91b43.js.map +294 -0
  29. package/main.js +0 -1
  30. package/package.json +2 -1
  31. package/readme.md +10 -7
  32. package/src/buildProject.js +6 -2
  33. package/src/dev_server.js +22 -130
  34. package/src/execute.js +7 -10
  35. package/src/executeTestPlan.js +7 -1
  36. package/src/importUsingChildProcess.js +1 -1
  37. package/src/internal/{runtime/detectBrowser/detectBrowser.js → browser_detection/browser_detection.js} +0 -0
  38. package/src/internal/{runtime/detectBrowser → browser_detection}/detectAndroid.js +0 -0
  39. package/src/internal/{runtime/detectBrowser → browser_detection}/detectChrome.js +0 -0
  40. package/src/internal/{runtime/detectBrowser → browser_detection}/detectEdge.js +0 -0
  41. package/src/internal/{runtime/detectBrowser → browser_detection}/detectElectron.js +0 -0
  42. package/src/internal/{runtime/detectBrowser → browser_detection}/detectFirefox.js +0 -0
  43. package/src/internal/{runtime/detectBrowser → browser_detection}/detectIOS.js +0 -0
  44. package/src/internal/{runtime/detectBrowser → browser_detection}/detectInternetExplorer.js +0 -0
  45. package/src/internal/{runtime/detectBrowser → browser_detection}/detectOpera.js +0 -0
  46. package/src/internal/{runtime/detectBrowser → browser_detection}/detectSafari.js +0 -0
  47. package/src/internal/{runtime/detectBrowser → browser_detection}/util.js +0 -0
  48. package/src/internal/{runtime/createBrowserRuntime/scanBrowserRuntimeFeatures.js → browser_feature_detection/browser_feature_detection.js} +116 -81
  49. package/src/internal/browser_feature_detection/compile_proxy.html +27 -0
  50. package/src/internal/browser_launcher/browser_runtime_report.js +75 -0
  51. package/src/internal/{browser-launcher → browser_launcher}/executeHtmlFile.js +13 -16
  52. package/src/internal/browser_launcher/from_playwright.js +314 -0
  53. package/src/internal/{browser-launcher → browser_launcher}/trackPageToNotify.js +0 -0
  54. package/src/internal/{browser-launcher/jsenv-browser-system.js → browser_runtime/browser_runtime.js} +4 -4
  55. package/src/internal/{runtime/createBrowserRuntime/createBrowserSystem.js → browser_runtime/browser_system.js} +3 -2
  56. package/src/internal/{runtime/createBrowserRuntime → browser_runtime}/createBrowserRuntime.js +7 -5
  57. package/src/internal/{browser-launcher → browser_runtime}/displayErrorInDocument.js +0 -0
  58. package/src/internal/{browser-launcher → browser_runtime}/displayErrorNotification.js +2 -4
  59. package/src/internal/{runtime/createBrowserRuntime → browser_runtime}/evalSource.js +2 -0
  60. package/src/internal/{runtime/createBrowserRuntime → browser_runtime}/makeNamespaceTransferable.js +0 -0
  61. package/src/internal/{browser-utils → browser_utils}/fetch-browser.js +2 -0
  62. package/src/internal/{browser-utils → browser_utils}/fetchAndEvalUsingFetch.js +3 -0
  63. package/src/internal/{browser-utils → browser_utils}/fetchAndEvalUsingScript.js +2 -0
  64. package/src/internal/{browser-utils → browser_utils}/fetchJson.js +0 -0
  65. package/src/internal/{browser-utils → browser_utils}/fetchUsingXHR.js +4 -4
  66. package/src/internal/building/buildUsingRollup.js +4 -0
  67. package/src/internal/building/createJsenvRollupPlugin.js +19 -9
  68. package/src/internal/building/css/applyPostCss.js +19 -8
  69. package/src/internal/building/css/moveCssUrls.js +44 -0
  70. package/src/internal/building/css/parseCssRessource.js +67 -17
  71. package/src/internal/building/css/parseCssUrls.js +29 -23
  72. package/src/internal/building/css/postcss_plugin_url_visitor.js +11 -20
  73. package/src/internal/building/css/replaceCssUrls.js +38 -19
  74. package/src/internal/building/css_module.js +6 -10
  75. package/src/internal/building/html/parseHtmlRessource.js +37 -11
  76. package/src/internal/building/parseRessource.js +3 -0
  77. package/src/internal/building/ressource_builder.js +12 -3
  78. package/src/internal/compiling/babel_plugin_import_assertions.js +1 -2
  79. package/src/internal/compiling/html_source_file_service.js +23 -21
  80. package/src/internal/compiling/jsenvCompilerForHtml.js +15 -22
  81. package/src/internal/compiling/startCompileServer.js +37 -32
  82. package/src/internal/dev_server/event_source_client/event_source_connection.js +28 -19
  83. package/src/internal/dev_server/exploring/exploring.html +7 -2
  84. package/src/internal/dev_server/exploring/fetchExploringJson.js +4 -9
  85. package/src/internal/dev_server/redirector/redirector.html +37 -2
  86. package/src/internal/dev_server/toolbar/compilation/toolbar.compilation.js +4 -7
  87. package/src/internal/dev_server/toolbar/eventsource/toolbar.eventsource.js +2 -2
  88. package/src/internal/dev_server/toolbar/notification/toolbar.notification.js +75 -44
  89. package/src/internal/dev_server/toolbar/toolbar.html +31 -5
  90. package/src/internal/dev_server/toolbar/toolbar.injector.js +55 -36
  91. package/src/internal/dev_server/toolbar/toolbar.main.js +45 -31
  92. package/src/internal/dev_server/toolbar/util/fetching.js +1 -1
  93. package/src/internal/executing/executeConcurrently.js +15 -11
  94. package/src/internal/executing/executePlan.js +3 -2
  95. package/src/internal/generateGroupMap/one_runtime_compat.js +1 -1
  96. package/src/internal/generateGroupMap/runtime_compat_composition.js +1 -1
  97. package/src/internal/generateGroupMap/runtime_support.js +1 -1
  98. package/src/internal/jsenvInternalFiles.js +0 -26
  99. package/src/internal/jsenv_builds.js +19 -0
  100. package/src/internal/{runtime/node-feature-detect/feature-detect-dynamic-import.mjs → node_feature_detection/feature_detect_dynamic_import.mjs} +0 -0
  101. package/src/internal/{runtime/node-feature-detect/feature-detect-top-level-await.mjs → node_feature_detection/feature_detect_top_level_await.mjs} +0 -0
  102. package/src/internal/{runtime/node-feature-detect → node_feature_detection}/nodeSupportsDynamicImport.js +0 -0
  103. package/src/internal/node_feature_detection/nodeSupportsTopLevelAwait.js +16 -0
  104. package/src/internal/{runtime/createNodeRuntime/scanNodeRuntimeFeatures.js → node_feature_detection/node_feature_detection.js} +12 -13
  105. package/src/internal/{node-launcher → node_launcher}/createChildProcessOptions.js +0 -0
  106. package/src/internal/{node-launcher → node_launcher}/createControllableNodeProcess.js +9 -14
  107. package/src/internal/{node-launcher → node_launcher}/kill_process_tree.js +0 -0
  108. package/src/internal/node_launcher/node_runtime_report.js +71 -0
  109. package/src/internal/{node-launcher → node_launcher}/processOptions.js +0 -0
  110. package/src/internal/{runtime/detectNode → node_runtime}/detectNode.js +0 -0
  111. package/src/internal/{runtime/createNodeRuntime → node_runtime}/evalSource.js +1 -1
  112. package/src/internal/{runtime/createNodeRuntime → node_runtime}/fetchSource.js +1 -1
  113. package/src/internal/{node-launcher → node_runtime}/nodeControllableFile.mjs +14 -11
  114. package/src/internal/{runtime/createNodeRuntime/createNodeExecutionWithDynamicImport.js → node_runtime/node_execution_dynamic_import.js} +34 -6
  115. package/src/internal/node_runtime/node_execution_performance.js +67 -0
  116. package/src/internal/{runtime/createNodeRuntime/createNodeExecutionWithSystemJs.js → node_runtime/node_execution_systemjs.js} +38 -24
  117. package/src/internal/{runtime/createNodeRuntime/createNodeSystem.js → node_runtime/node_system.js} +4 -4
  118. package/src/internal/runtime/computeCompileIdFromGroupId.js +1 -0
  119. package/src/internal/runtime/resolveGroup.js +1 -1
  120. package/src/internal/runtime/resolveRuntimeGroup.js +2 -2
  121. package/src/internal/{semantic-versioning → semantic_versioning}/findHighestVersion.js +0 -0
  122. package/src/internal/{semantic-versioning → semantic_versioning}/findLowestVersion.js +0 -0
  123. package/src/internal/{semantic-versioning → semantic_versioning}/index.js +0 -0
  124. package/src/internal/{semantic-versioning → semantic_versioning}/valueToVersion.js +0 -0
  125. package/src/internal/{semantic-versioning → semantic_versioning}/versionCompare.js +0 -0
  126. package/src/internal/{semantic-versioning → semantic_versioning}/versionIsAbove.js +0 -0
  127. package/src/internal/{semantic-versioning → semantic_versioning}/versionIsBelow.js +0 -0
  128. package/src/internal/{semantic-versioning → semantic_versioning}/versionIsEqual.js +0 -0
  129. package/src/launchBrowser.js +33 -492
  130. package/src/launchNode.js +36 -7
  131. package/src/requireUsingChildProcess.js +1 -1
  132. package/dist/jsenv_compile_proxy.js +0 -1339
  133. package/dist/jsenv_compile_proxy.js.map +0 -378
  134. package/dist/jsenv_event_source_client.js.map +0 -126
  135. package/dist/jsenv_exploring_index.js +0 -1092
  136. package/dist/jsenv_exploring_index.js.map +0 -353
  137. package/dist/jsenv_exploring_redirector.js +0 -1386
  138. package/dist/jsenv_exploring_redirector.js.map +0 -384
  139. package/dist/jsenv_redirector.js +0 -1388
  140. package/dist/jsenv_redirector.js.map +0 -384
  141. package/dist/jsenv_toolbar.js +0 -2880
  142. package/dist/jsenv_toolbar.js.map +0 -771
  143. package/dist/jsenv_toolbar_injector.js.map +0 -301
  144. package/src/internal/browser-launcher/createSharing.js +0 -70
  145. package/src/internal/browser-launcher/jsenv_compile_proxy.html +0 -13
  146. package/src/internal/browser-launcher/jsenv_compile_proxy.js +0 -5
  147. package/src/internal/dev_server/event_source_client/event_source_client_file_info.js +0 -17
  148. package/src/internal/dev_server/exploring/exploring_file_info.js +0 -21
  149. package/src/internal/dev_server/redirector/redirector.js +0 -30
  150. package/src/internal/dev_server/redirector/redirector_file_info.js +0 -24
  151. package/src/internal/dev_server/toolbar/backtolist/toolbar.backtolist.js +0 -33
  152. package/src/internal/dev_server/toolbar/toolbar_file_info.js +0 -37
  153. package/src/internal/node-launcher/node-js-file.js +0 -110
  154. package/src/internal/runtime/createNodeRuntime/createNodeRuntime.js +0 -32
  155. package/src/internal/runtime/node-feature-detect/nodeSupportsTopLevelAwait.js +0 -18
  156. package/src/nodeRuntime.js +0 -5
@@ -1,25 +1,56 @@
1
1
  import { createPreference } from "../util/preferences.js"
2
+ import { enableVariant } from "../variant/variant.js"
2
3
 
4
+ const notificationAvailable = typeof window.Notification === "function"
3
5
  const notificationPreference = createPreference("notification")
4
6
 
5
7
  const arrayOfOpenedNotifications = []
6
8
  export const renderToolbarNotification = () => {
7
9
  const notifCheckbox = document.querySelector("#toggle-notifs")
8
- notifCheckbox.checked = getNotificationPreference()
9
- notifCheckbox.onchange = () => {
10
- setNotificationPreference(notifCheckbox.checked)
11
- if (notifCheckbox.checked) {
12
- // request permission early
13
- // especially useful on firefox where you can request permission
14
- // only inside a user generated event such as this onchange handler
15
- requestPermission()
16
- } else {
17
- // slice because arrayOfOpenedNotifications can be mutated while looping
18
- arrayOfOpenedNotifications.slice().forEach((notification) => {
19
- notification.close()
20
- })
10
+ if (!notificationAvailable) {
11
+ const notifSetting = document.querySelector(".settings-notification")
12
+ notifSetting.setAttribute("data-disabled", "true")
13
+ notifSetting.setAttribute(
14
+ "title",
15
+ `Notification not available in the browser`,
16
+ )
17
+ notifCheckbox.disabled = true
18
+ return
19
+ }
20
+
21
+ const updatePermission = () => {
22
+ if (Notification.permission === "denied") {
23
+ const notifSetting = document.querySelector(".settings-notification")
24
+ notifSetting.setAttribute("data-disabled", "true")
25
+ notifSetting.setAttribute("title", `Notification denied`)
26
+ notifCheckbox.disabled = true
27
+ return
28
+ }
29
+
30
+ notifCheckbox.checked = getNotificationPreference()
31
+ notifCheckbox.onchange = () => {
32
+ setNotificationPreference(notifCheckbox.checked)
33
+ if (!notifCheckbox.checked) {
34
+ // slice because arrayOfOpenedNotifications can be mutated while looping
35
+ arrayOfOpenedNotifications.slice().forEach((notification) => {
36
+ notification.close()
37
+ })
38
+ }
39
+ }
40
+ const notifPermission = Notification.permission
41
+ enableVariant(document.querySelector(".notification-text"), {
42
+ notif_permission: notifPermission === "granted" ? "yes" : "no",
43
+ })
44
+ if (notifPermission === "default") {
45
+ document.querySelector("a.request_notification_permission").onclick =
46
+ () => {
47
+ requestPermission().then(() => {
48
+ updatePermission()
49
+ })
50
+ }
21
51
  }
22
52
  }
53
+ updatePermission()
23
54
  }
24
55
 
25
56
  export const notifyExecutionResult = (
@@ -64,8 +95,6 @@ export const notifyExecutionResult = (
64
95
  }
65
96
  }
66
97
 
67
- const notificationAvailable = typeof window.Notification === "function"
68
-
69
98
  const getNotificationPreference = () =>
70
99
  notificationPreference.has() ? notificationPreference.get() : true
71
100
 
@@ -76,46 +105,48 @@ const getFaviconHref = () => {
76
105
  return link ? link.href : undefined
77
106
  }
78
107
 
108
+ let permission = "default"
109
+
79
110
  const notify = notificationAvailable
80
111
  ? async (
81
112
  title,
82
113
  { clickToFocus = false, clickToClose = false, ...options } = {},
83
114
  ) => {
84
- const permission = await requestPermission()
85
- if (permission === "granted") {
86
- const notification = new Notification(title, options)
87
- arrayOfOpenedNotifications.push(notification)
88
- notification.onclick = () => {
89
- // but if the user navigated inbetween
90
- // focusing window will show something else
91
- // in that case it could be great to do something
92
- // maybe like showing a message saying this execution
93
- // is no longer visible
94
- // we could also navigauate to this file execution but
95
- // there is no guarantee re-executing the file would give same output
96
- // and it would also trigger an other notification
97
- if (clickToFocus) window.focus()
98
- if (clickToClose) notification.close()
99
- }
100
- notification.onclose = () => {
101
- const index = arrayOfOpenedNotifications.indexOf(notification)
102
- if (index > -1) {
103
- arrayOfOpenedNotifications.splice(index, 1)
104
- }
115
+ if (permission !== "granted") {
116
+ return null
117
+ }
118
+
119
+ const notification = new Notification(title, options)
120
+ arrayOfOpenedNotifications.push(notification)
121
+ notification.onclick = () => {
122
+ // but if the user navigated inbetween
123
+ // focusing window will show something else
124
+ // in that case it could be great to do something
125
+ // maybe like showing a message saying this execution
126
+ // is no longer visible
127
+ // we could also navigauate to this file execution but
128
+ // there is no guarantee re-executing the file would give same output
129
+ // and it would also trigger an other notification
130
+ if (clickToFocus) window.focus()
131
+ if (clickToClose) notification.close()
132
+ }
133
+ notification.onclose = () => {
134
+ const index = arrayOfOpenedNotifications.indexOf(notification)
135
+ if (index > -1) {
136
+ arrayOfOpenedNotifications.splice(index, 1)
105
137
  }
106
- return notification
107
138
  }
108
- return null
139
+ return notification
109
140
  }
110
141
  : () => {}
111
142
 
112
- let permissionPromise
143
+ let requestPromise
113
144
  const requestPermission = notificationAvailable
114
145
  ? async () => {
115
- if (permissionPromise) return permissionPromise
116
- permissionPromise = Notification.requestPermission()
117
- const permission = await permissionPromise
118
- permissionPromise = undefined
146
+ if (requestPromise) return requestPromise
147
+ requestPromise = Notification.requestPermission()
148
+ permission = await requestPromise
149
+ requestPromise = undefined
119
150
  return permission
120
151
  }
121
- : () => Promise.resolve("denied")
152
+ : () => Promise.resolve("default")
@@ -5,7 +5,12 @@
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1" />
6
6
  <meta charset="utf-8" />
7
7
  <link rel="icon" href="data:," />
8
- <link rel="stylesheet" type="text/css" href="./toolbar.main.css" />
8
+ <link
9
+ rel="stylesheet"
10
+ type="text/css"
11
+ href="./toolbar.main.css"
12
+ data-jsenv-force-inline
13
+ />
9
14
  </head>
10
15
  <body>
11
16
  <div id="toolbar-overlay"></div>
@@ -13,7 +18,7 @@
13
18
  <div id="toolbar">
14
19
  <div id="toolbar-wrapper">
15
20
  <section id="file-list-link" data-responsive-toolbar-element>
16
- <a class="toolbar-icon-wrapper" href="">
21
+ <a class="toolbar-icon-wrapper" href="/">
17
22
  <svg
18
23
  id="fileIconSvg"
19
24
  class="iconToolbar"
@@ -251,7 +256,7 @@
251
256
  </div>
252
257
  <div id="settings-box-body">
253
258
  <div class="settings-box-items-wrapper">
254
- <div class="settings-box-item">
259
+ <div class="settings-box-item settings-notification">
255
260
  <div class="category-title">
256
261
  <svg
257
262
  xmlns="http://www.w3.org/2000/svg"
@@ -274,6 +279,14 @@
274
279
  </label>
275
280
  <div class="category-subtitle">
276
281
  Send system notification when execution fails or is fixed.
282
+ <div class="notification-text">
283
+ <a
284
+ data-when="notif_permission:no"
285
+ class="request_notification_permission"
286
+ href="javascript:void(0);"
287
+ >Enable notification</a
288
+ >
289
+ </div>
277
290
  </div>
278
291
  </div>
279
292
  <div class="settings-box-item settings-livereload">
@@ -526,7 +539,7 @@
526
539
  <!--
527
540
  Reusable svg(s)
528
541
  -->
529
- <div style="display: none">
542
+ <div style="display: none; position: absolute">
530
543
  <svg
531
544
  id="loading_svg"
532
545
  xmlns="http://www.w3.org/2000/svg"
@@ -551,6 +564,19 @@
551
564
  module approach wil be faster because
552
565
  no compilation will be necessary
553
566
  -->
554
- <script src="/.jsenv/toolbar.main.js"></script>
567
+ <script
568
+ type="importmap"
569
+ src="../../../../node_resolution.importmap"
570
+ ></script>
571
+ <script>
572
+ // here we should create something like window.toolbar = {}
573
+ // and a promise the toolbar injector can listen to act on the toolbar
574
+ // or we could just consider all communication should pass by postmessage
575
+ </script>
576
+ <script
577
+ type="module"
578
+ src="./toolbar.main.js"
579
+ data-jsenv-force-inline
580
+ ></script>
555
581
  </body>
556
582
  </html>
@@ -1,6 +1,10 @@
1
1
  import { fetchExploringJson } from "@jsenv/core/src/internal/dev_server/exploring/fetchExploringJson.js"
2
2
  import { setAttributes, setStyles } from "./util/dom.js"
3
3
 
4
+ // eslint-disable-next-line no-undef
5
+ const TOOLBAR_BUILD_RELATIVE_URL = __TOOLBAR_BUILD_RELATIVE_URL_
6
+ const jsenvLogoSvgUrl = new URL("./jsenv-logo.svg", import.meta.url)
7
+
4
8
  const injectToolbar = async () => {
5
9
  await new Promise((resolve) => {
6
10
  if (window.requestIdleCallback) {
@@ -40,7 +44,7 @@ const injectToolbar = async () => {
40
44
  })
41
45
  const iframeLoadedPromise = iframeToLoadedPromise(iframe)
42
46
  const jsenvToolbarHtmlServerUrl = resolveUrl(
43
- "./src/internal/dev_server/toolbar/toolbar.html",
47
+ TOOLBAR_BUILD_RELATIVE_URL,
44
48
  jsenvDirectoryServerUrl,
45
49
  )
46
50
  // set iframe src BEFORE putting it into the DOM (prevent firefox adding an history entry)
@@ -50,40 +54,11 @@ const injectToolbar = async () => {
50
54
  await iframeLoadedPromise
51
55
  iframe.removeAttribute("tabindex")
52
56
 
53
- const listenToolbarIframeEvent = (event, fn) => {
54
- window.addEventListener(
55
- "message",
56
- (messageEvent) => {
57
- const { data } = messageEvent
58
- if (typeof data !== "object") return
59
- const { jsenv } = data
60
- if (!jsenv) return
61
- const { type } = data
62
- if (type !== event) return
63
- fn(data.value)
64
- },
65
- false,
66
- )
67
- }
68
-
69
- listenToolbarIframeEvent("toolbar-visibility-change", (visible) => {
70
- if (visible) {
71
- hideToolbarTrigger()
72
- } else {
73
- showToolbarTrigger()
74
- }
75
- })
76
-
77
57
  const div = document.createElement("div")
78
- const jsenvLogoUrl = resolveUrl(
79
- "./src/internal/dev_server/toolbar/jsenv-logo.svg",
80
- jsenvDirectoryServerUrl,
81
- )
82
- const jsenvLogoSvgSrc = jsenvLogoUrl
83
58
  div.innerHTML = `
84
59
  <div id="jsenv-toolbar-trigger">
85
60
  <svg id="jsenv-toolbar-trigger-icon">
86
- <use xlink:href="${jsenvLogoSvgSrc}#jsenv-logo"></use>
61
+ <use xlink:href="${jsenvLogoSvgUrl}#jsenv-logo"></use>
87
62
  </svg>
88
63
  <style>
89
64
  #jsenv-toolbar-trigger {
@@ -148,7 +123,7 @@ const injectToolbar = async () => {
148
123
  collapseToolbarTrigger()
149
124
  }
150
125
  toolbarTrigger.onclick = () => {
151
- window.__jsenv__.toolbar.show()
126
+ sendCommandToToolbar(iframe, "showToolbar")
152
127
  }
153
128
 
154
129
  const showToolbarTrigger = () => {
@@ -166,13 +141,56 @@ const injectToolbar = async () => {
166
141
  const collapseToolbarTrigger = () => {
167
142
  toolbarTrigger.removeAttribute("data-expanded", "")
168
143
  }
169
- hideToolbarTrigger()
170
144
 
171
- iframe.contentWindow.renderToolbar()
145
+ hideToolbarTrigger()
146
+ addToolbarEventCallback(iframe, "toolbar-visibility-change", (visible) => {
147
+ if (visible) {
148
+ hideToolbarTrigger()
149
+ } else {
150
+ showToolbarTrigger()
151
+ }
152
+ })
153
+ addToolbarEventCallback(iframe, "toolbar_ready", () => {
154
+ sendCommandToToolbar(iframe, "renderToolbar")
155
+ })
172
156
 
173
157
  return iframe
174
158
  }
175
159
 
160
+ const addToolbarEventCallback = (iframe, eventName, callback) => {
161
+ const messageEventCallback = (messageEvent) => {
162
+ const { data } = messageEvent
163
+ if (typeof data !== "object") {
164
+ return
165
+ }
166
+ const { __jsenv__ } = data
167
+ if (!__jsenv__) {
168
+ return
169
+ }
170
+ if (__jsenv__.event !== eventName) {
171
+ return
172
+ }
173
+ callback(__jsenv__.data)
174
+ }
175
+
176
+ window.addEventListener("message", messageEventCallback, false)
177
+ return () => {
178
+ window.removeEventListener("message", messageEventCallback, false)
179
+ }
180
+ }
181
+
182
+ const sendCommandToToolbar = (iframe, command, ...args) => {
183
+ iframe.contentWindow.postMessage(
184
+ {
185
+ __jsenv__: {
186
+ command,
187
+ args,
188
+ },
189
+ },
190
+ window.origin,
191
+ )
192
+ }
193
+
176
194
  const getToolbarPlaceholder = () => {
177
195
  const placeholder = queryPlaceholder()
178
196
  if (placeholder) {
@@ -188,8 +206,9 @@ const getToolbarPlaceholder = () => {
188
206
  return createTooolbarPlaceholder()
189
207
  }
190
208
 
191
- const queryPlaceholder = () =>
192
- document.querySelector("[data-jsenv-toolbar-placeholder]")
209
+ const queryPlaceholder = () => {
210
+ return document.querySelector("[data-jsenv-toolbar-placeholder]")
211
+ }
193
212
 
194
213
  const createTooolbarPlaceholder = () => {
195
214
  const placeholder = document.createElement("span")
@@ -4,7 +4,6 @@ import { urlToRelativeUrl } from "@jsenv/filesystem/src/urlToRelativeUrl.js"
4
4
  import { fetchExploringJson } from "../exploring/fetchExploringJson.js"
5
5
  import { startJavaScriptAnimation } from "../toolbar/util/animation.js"
6
6
  import "./focus/toolbar.focus.js"
7
- import { renderBackToListInToolbar } from "./backtolist/toolbar.backtolist.js"
8
7
  import {
9
8
  getToolbarIframe,
10
9
  deactivateToolbarSection,
@@ -45,16 +44,6 @@ const renderToolbar = async () => {
45
44
  hideSettings()
46
45
  }
47
46
 
48
- const toolbarElement = document.querySelector("#toolbar")
49
- exposeOnParentWindow({
50
- toolbar: {
51
- element: toolbarElement,
52
- show: showToolbar,
53
- hide: () => hideToolbar(),
54
- toggle: toogleToolbar,
55
- },
56
- })
57
-
58
47
  const toolbarVisible = toolbarVisibilityPreference.has()
59
48
  ? toolbarVisibilityPreference.get()
60
49
  : true
@@ -65,11 +54,6 @@ const renderToolbar = async () => {
65
54
  hideToolbar({ animate: false })
66
55
  }
67
56
 
68
- renderBackToListInToolbar({
69
- outDirectoryRelativeUrl,
70
- exploringHtmlFileRelativeUrl: exploringConfig.exploringHtmlFileRelativeUrl,
71
- })
72
-
73
57
  renderToolbarNotification()
74
58
  makeToolbarResponsive()
75
59
  renderToolbarSettings()
@@ -91,16 +75,6 @@ const renderToolbar = async () => {
91
75
  toogleToolbar()
92
76
  }
93
77
 
94
- const exposeOnParentWindow = (object) => {
95
- let { __jsenv__ } = window.parent
96
- if (!__jsenv__) {
97
- __jsenv__ = {}
98
- window.parent.__jsenv__ = {}
99
- }
100
-
101
- Object.assign(__jsenv__, object)
102
- }
103
-
104
78
  const toogleToolbar = () => {
105
79
  if (toolbarIsVisible()) {
106
80
  hideToolbar()
@@ -213,15 +187,55 @@ const getCompileGroup = ({
213
187
  }
214
188
  }
215
189
 
216
- const sendEventToParent = (type, value) => {
190
+ const addExternalCommandCallback = (command, callback) => {
191
+ const messageEventCallback = (messageEvent) => {
192
+ const { data } = messageEvent
193
+ if (typeof data !== "object") {
194
+ return
195
+ }
196
+ const { __jsenv__ } = data
197
+ if (!__jsenv__) {
198
+ return
199
+ }
200
+
201
+ if (__jsenv__.command !== command) {
202
+ return
203
+ }
204
+
205
+ callback(...__jsenv__.args)
206
+ }
207
+
208
+ window.addEventListener("message", messageEventCallback)
209
+ return () => {
210
+ window.removeEventListener("message", messageEventCallback)
211
+ }
212
+ }
213
+
214
+ const sendEventToParent = (name, data) => {
217
215
  window.parent.postMessage(
218
216
  {
219
- jsenv: true,
220
- type,
221
- value,
217
+ __jsenv__: {
218
+ event: name,
219
+ data,
220
+ },
222
221
  },
223
222
  "*",
224
223
  )
225
224
  }
226
225
 
227
- window.renderToolbar = renderToolbar
226
+ window.toolbar = {
227
+ render: renderToolbar,
228
+ show: showToolbar,
229
+ hide: () => hideToolbar(),
230
+ }
231
+
232
+ addExternalCommandCallback("renderToolbar", () => {
233
+ renderToolbar()
234
+ })
235
+ addExternalCommandCallback("showToolbar", () => {
236
+ showToolbar()
237
+ })
238
+ addExternalCommandCallback("hideToolbar", () => {
239
+ hideToolbar()
240
+ })
241
+ sendEventToParent("toolbar_ready")
@@ -6,7 +6,7 @@ const fetchPolyfill = async (...args) => {
6
6
  }
7
7
 
8
8
  const loadPolyfill = memoize(() =>
9
- import("../../../browser-utils/fetchUsingXHR.js"),
9
+ import("../../../browser_utils/fetchUsingXHR.js"),
10
10
  )
11
11
 
12
12
  export const fetchUrl =
@@ -11,7 +11,7 @@ import {
11
11
  normalizeStructuredMetaMap,
12
12
  urlToMeta,
13
13
  } from "@jsenv/filesystem"
14
- import { Abort } from "@jsenv/abort"
14
+ import { Abort, createCallbackListNotifiedOnce } from "@jsenv/abort"
15
15
 
16
16
  import { launchAndExecute } from "../executing/launchAndExecute.js"
17
17
  import { reportToCoverage } from "./coverage/reportToCoverage.js"
@@ -27,14 +27,14 @@ export const executeConcurrently = async (
27
27
  launchAndExecuteLogLevel,
28
28
 
29
29
  projectDirectoryUrl,
30
- compileServerOrigin,
31
- outDirectoryRelativeUrl,
30
+ compileServer,
32
31
 
33
32
  babelPluginMap,
34
33
 
35
34
  defaultMsAllocatedPerExecution = 30000,
36
35
  cooldownBetweenExecutions = 0,
37
36
  maxExecutionsInParallel = 1,
37
+ stopAfterExecute,
38
38
  completedExecutionLogMerging,
39
39
  completedExecutionLogAbbreviation,
40
40
 
@@ -138,6 +138,8 @@ export const executeConcurrently = async (
138
138
  let timedoutCount = 0
139
139
  let erroredCount = 0
140
140
  let completedCount = 0
141
+ const stopAfterAllExecutionCallbackList = createCallbackListNotifiedOnce()
142
+
141
143
  const executionsDone = await executeInParallel({
142
144
  multipleExecutionsOperation,
143
145
  maxExecutionsInParallel,
@@ -154,12 +156,7 @@ export const executeConcurrently = async (
154
156
  measurePerformance: false,
155
157
  collectPerformance: false,
156
158
  captureConsole: true,
157
- // stopAfterExecute: true to ensure runtime is stopped once executed
158
- // because we have what we wants: execution is completed and
159
- // we have associated coverage and capturedConsole
160
- // passsing false means all node process and browsers launched stays opened
161
- // (can eventually be used for debug)
162
- stopAfterExecute: true,
159
+ stopAfterExecute,
163
160
  stopAfterExecuteReason: "execution-done",
164
161
  allocatedMs: defaultMsAllocatedPerExecution,
165
162
  ...paramsFromStep,
@@ -206,11 +203,14 @@ export const executeConcurrently = async (
206
203
  coverageTempDirectoryUrl,
207
204
  runtimeParams: {
208
205
  projectDirectoryUrl,
209
- compileServerOrigin,
210
- outDirectoryRelativeUrl,
206
+ compileServerOrigin: compileServer.origin,
207
+ compileServerId: compileServer.id,
208
+ outDirectoryRelativeUrl: compileServer.outDirectoryRelativeUrl,
209
+
211
210
  collectCoverage: coverage,
212
211
  coverageIgnorePredicate,
213
212
  coverageForceIstanbul,
213
+ stopAfterAllExecutionCallbackList,
214
214
  ...executionParams.runtimeParams,
215
215
  },
216
216
  executeParams: {
@@ -282,6 +282,10 @@ export const executeConcurrently = async (
282
282
  },
283
283
  })
284
284
 
285
+ if (stopAfterExecute) {
286
+ stopAfterAllExecutionCallbackList.notify()
287
+ }
288
+
285
289
  const summaryCounts = reportToSummary(report)
286
290
 
287
291
  const summary = {
@@ -26,6 +26,7 @@ export const executePlan = async (
26
26
 
27
27
  defaultMsAllocatedPerExecution,
28
28
  maxExecutionsInParallel,
29
+ stopAfterExecute,
29
30
  cooldownBetweenExecutions,
30
31
  completedExecutionLogMerging,
31
32
  completedExecutionLogAbbreviation,
@@ -146,8 +147,7 @@ export const executePlan = async (
146
147
  launchAndExecuteLogLevel,
147
148
 
148
149
  projectDirectoryUrl,
149
- compileServerOrigin: compileServer.origin,
150
- outDirectoryRelativeUrl: compileServer.outDirectoryRelativeUrl,
150
+ compileServer,
151
151
 
152
152
  // not sure we actually have to pass import params to executeConcurrently
153
153
  importResolutionMethod,
@@ -157,6 +157,7 @@ export const executePlan = async (
157
157
 
158
158
  defaultMsAllocatedPerExecution,
159
159
  maxExecutionsInParallel,
160
+ stopAfterExecute,
160
161
  cooldownBetweenExecutions,
161
162
  completedExecutionLogMerging,
162
163
  completedExecutionLogAbbreviation,
@@ -1,4 +1,4 @@
1
- import { findHighestVersion } from "../semantic-versioning/index.js"
1
+ import { findHighestVersion } from "../semantic_versioning/index.js"
2
2
 
3
3
  export const createOneRuntimeCompat = ({
4
4
  runtimeName,
@@ -1,4 +1,4 @@
1
- import { findHighestVersion } from "../semantic-versioning/index.js"
1
+ import { findHighestVersion } from "../semantic_versioning/index.js"
2
2
 
3
3
  export const composeMinRuntimeVersions = (
4
4
  firstMinRuntimeVersions,
@@ -1,4 +1,4 @@
1
- import { findLowestVersion } from "../semantic-versioning/findLowestVersion.js"
1
+ import { findLowestVersion } from "../semantic_versioning/findLowestVersion.js"
2
2
 
3
3
  export const isNodePartOfSupportedRuntimes = (runtimeSupport) => {
4
4
  return Boolean(runtimeSupport.node)
@@ -14,32 +14,6 @@ export const jsenvNodeSystemFileInfo = {
14
14
  ),
15
15
  }
16
16
 
17
- export const jsenvBrowserSystemFileInfo = {
18
- jsenvRelativeUrl: "./src/internal/browser-launcher/jsenv-browser-system.js",
19
- jsenvBuildRelativeUrl: "./jsenv_browser_system.js",
20
- jsenvBuildUrl: resolveUrl(
21
- "./dist/jsenv_browser_system.js",
22
- jsenvCoreDirectoryUrl,
23
- ),
24
- }
25
-
26
- export const jsenvCompileProxyHtmlFileInfo = {
27
- jsenvRelativeUrl: "./src/internal/browser-launcher/jsenv_compile_proxy.html",
28
- url: resolveUrl(
29
- "./src/internal/browser-launcher/jsenv_compile_proxy.html",
30
- jsenvCoreDirectoryUrl,
31
- ),
32
- }
33
-
34
- export const jsenvCompileProxyFileInfo = {
35
- jsenvRelativeUrl: "./src/internal/browser-launcher/jsenv_compile_proxy.js",
36
- jsenvBuildRelativeUrl: "./jsenv_compile_proxy.js",
37
- jsenvBuildUrl: resolveUrl(
38
- "./dist/jsenv_compile_proxy.js",
39
- jsenvCoreDirectoryUrl,
40
- ),
41
- }
42
-
43
17
  export const sourcemapMainFileInfo = {
44
18
  url: fileSystemPathToUrl(require.resolve("source-map/dist/source-map.js")),
45
19
  }
@@ -0,0 +1,19 @@
1
+ import { readFile } from "@jsenv/filesystem"
2
+
3
+ import { jsenvCoreDirectoryUrl } from "./jsenvCoreDirectoryUrl.js"
4
+
5
+ export const getJsenvBuildUrl = async (buildRelativeUrlWithoutHash) => {
6
+ try {
7
+ const manifest = await readFile(
8
+ new URL("./dist/manifest.json", jsenvCoreDirectoryUrl),
9
+ { as: "json" },
10
+ )
11
+ const buildRelativeUrl = manifest[buildRelativeUrlWithoutHash]
12
+ return new URL(buildRelativeUrl, jsenvCoreDirectoryUrl).href
13
+ } catch (e) {
14
+ if (e.code === "ENOENT") {
15
+ return null
16
+ }
17
+ throw e
18
+ }
19
+ }