@jsenv/core 24.1.0-alpha.0 → 24.2.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 (68) hide show
  1. package/dist/jsenv_event_source_client.js +338 -0
  2. package/dist/jsenv_event_source_client.js.map +126 -0
  3. package/dist/jsenv_exploring_index.js.map +7 -7
  4. package/dist/jsenv_redirector.js +1386 -0
  5. package/dist/jsenv_redirector.js.map +384 -0
  6. package/dist/jsenv_toolbar.js +37 -504
  7. package/dist/jsenv_toolbar.js.map +37 -112
  8. package/dist/jsenv_toolbar_injector.js +31 -126
  9. package/dist/jsenv_toolbar_injector.js.map +11 -30
  10. package/package.json +1 -1
  11. package/src/buildProject.js +2 -0
  12. package/src/dev_server.js +104 -57
  13. package/src/internal/compiling/compile-directory/validateCache.js +0 -5
  14. package/src/internal/compiling/compileFile.js +17 -54
  15. package/src/internal/compiling/createCompiledFileService.js +2 -0
  16. package/src/internal/compiling/html_source_file_service.js +43 -9
  17. package/src/internal/compiling/jsenvCompilerForHtml.js +33 -9
  18. package/src/internal/compiling/startCompileServer.js +5 -1
  19. package/src/internal/dev_server/event_source_client/event_source_client.js +63 -0
  20. package/src/internal/dev_server/event_source_client/event_source_client_file_info.js +17 -0
  21. package/src/internal/{toolbar/eventsource/connectEventSource.js → dev_server/event_source_client/event_source_connection.js} +47 -78
  22. package/src/internal/dev_server/event_source_client/file_changes.js +82 -0
  23. package/src/internal/dev_server/event_source_client/livereload_preference.js +13 -0
  24. package/src/internal/{exploring → dev_server/exploring}/exploring.css +0 -0
  25. package/src/internal/{exploring → dev_server/exploring}/exploring.html +1 -1
  26. package/src/internal/{exploring → dev_server/exploring}/exploring.js +0 -0
  27. package/src/internal/dev_server/exploring/exploring_file_info.js +21 -0
  28. package/src/internal/{exploring → dev_server/exploring}/fetchExploringJson.js +1 -1
  29. package/src/internal/{exploring/exploring.redirector.html → dev_server/redirector/redirector.html} +1 -1
  30. package/src/internal/{exploring/exploring.redirector.js → dev_server/redirector/redirector.js} +1 -1
  31. package/src/internal/dev_server/redirector/redirector_file_info.js +24 -0
  32. package/src/internal/{toolbar → dev_server/toolbar}/animation/toolbar.animation.js +0 -0
  33. package/src/internal/{toolbar → dev_server/toolbar}/backtolist/toolbar.backtolist.js +0 -0
  34. package/src/internal/{toolbar → dev_server/toolbar}/compilation/compilation.css +0 -0
  35. package/src/internal/{toolbar → dev_server/toolbar}/compilation/toolbar.compilation.js +1 -1
  36. package/src/internal/{toolbar → dev_server/toolbar}/eventsource/eventsource.css +0 -0
  37. package/src/internal/dev_server/toolbar/eventsource/toolbar.eventsource.js +83 -0
  38. package/src/internal/{toolbar → dev_server/toolbar}/execution/execution.css +0 -0
  39. package/src/internal/{toolbar → dev_server/toolbar}/execution/toolbar.execution.js +0 -0
  40. package/src/internal/{toolbar → dev_server/toolbar}/focus/focus.css +0 -0
  41. package/src/internal/{toolbar → dev_server/toolbar}/focus/toolbar.focus.js +0 -0
  42. package/src/internal/{toolbar → dev_server/toolbar}/jsenv-logo.svg +0 -0
  43. package/src/internal/{toolbar → dev_server/toolbar}/notification/toolbar.notification.js +0 -0
  44. package/src/internal/{toolbar → dev_server/toolbar}/responsive/overflow-menu.css +0 -0
  45. package/src/internal/{toolbar → dev_server/toolbar}/responsive/toolbar.responsive.js +0 -0
  46. package/src/internal/{toolbar → dev_server/toolbar}/settings/settings.css +0 -0
  47. package/src/internal/{toolbar → dev_server/toolbar}/settings/toolbar.settings.js +0 -0
  48. package/src/internal/{toolbar → dev_server/toolbar}/theme/jsenv-theme.css +0 -0
  49. package/src/internal/{toolbar → dev_server/toolbar}/theme/light-theme.css +0 -0
  50. package/src/internal/{toolbar → dev_server/toolbar}/theme/toolbar.theme.js +0 -0
  51. package/src/internal/{toolbar → dev_server/toolbar}/toolbar.html +4 -37
  52. package/src/internal/{toolbar → dev_server/toolbar}/toolbar.injector.js +3 -92
  53. package/src/internal/{toolbar → dev_server/toolbar}/toolbar.main.css +0 -0
  54. package/src/internal/{toolbar → dev_server/toolbar}/toolbar.main.js +0 -0
  55. package/src/internal/dev_server/toolbar/toolbar_file_info.js +37 -0
  56. package/src/internal/{toolbar → dev_server/toolbar}/tooltip/tooltip.css +0 -0
  57. package/src/internal/{toolbar → dev_server/toolbar}/tooltip/tooltip.js +0 -0
  58. package/src/internal/{toolbar → dev_server/toolbar}/util/animation.js +0 -0
  59. package/src/internal/{toolbar → dev_server/toolbar}/util/dom.js +0 -0
  60. package/src/internal/{toolbar → dev_server/toolbar}/util/fetching.js +2 -2
  61. package/src/internal/{toolbar → dev_server/toolbar}/util/jsenvLogger.js +0 -0
  62. package/src/internal/{toolbar → dev_server/toolbar}/util/preferences.js +0 -0
  63. package/src/internal/{toolbar → dev_server/toolbar}/util/responsive.js +0 -0
  64. package/src/internal/{toolbar → dev_server/toolbar}/util/util.js +0 -0
  65. package/src/internal/{toolbar → dev_server/toolbar}/variant/variant.js +0 -0
  66. package/src/internal/jsenvInternalFiles.js +0 -58
  67. package/src/internal/toolbar/eventsource/connectCompileServerEventSource.js +0 -74
  68. package/src/internal/toolbar/eventsource/toolbar.eventsource.js +0 -239
package/src/dev_server.js CHANGED
@@ -15,16 +15,21 @@ import {
15
15
  computeOutDirectoryRelativeUrl,
16
16
  } from "./internal/compiling/startCompileServer.js"
17
17
  import { jsenvExplorableConfig } from "./jsenvExplorableConfig.js"
18
+ import {
19
+ redirectorHtmlFileInfo,
20
+ redirectorJsFileInfo,
21
+ } from "./internal/dev_server/redirector/redirector_file_info.js"
22
+ import {
23
+ exploringIndexHtmlFileInfo,
24
+ exploringIndexJsFileInfo,
25
+ } from "@jsenv/core/src/internal/dev_server/exploring/exploring_file_info.js"
26
+ import { toolbarJsFileInfo } from "@jsenv/core/src/internal/dev_server/toolbar/toolbar_file_info.js"
18
27
  import {
19
28
  sourcemapMainFileInfo,
20
29
  sourcemapMappingFileInfo,
21
- jsenvExploringRedirectorHtmlFileInfo,
22
- jsenvExploringRedirectorJsFileInfo,
23
- jsenvExploringIndexHtmlFileInfo,
24
- jsenvExploringIndexJsFileInfo,
25
- jsenvToolbarJsFileInfo,
26
30
  } from "./internal/jsenvInternalFiles.js"
27
31
  import { jsenvRuntimeSupportDuringDev } from "./jsenvRuntimeSupportDuringDev.js"
32
+ import { eventSourceClientFileInfo } from "./internal/dev_server/event_source_client/event_source_client_file_info.js"
28
33
 
29
34
  export const startDevServer = async ({
30
35
  signal = new AbortController().signal,
@@ -41,7 +46,7 @@ export const startDevServer = async ({
41
46
  projectDirectoryUrl,
42
47
  explorableConfig = jsenvExplorableConfig,
43
48
  mainFileRelativeUrl = urlToRelativeUrl(
44
- jsenvExploringIndexHtmlFileInfo.url,
49
+ exploringIndexHtmlFileInfo.sourceUrl,
45
50
  projectDirectoryUrl,
46
51
  ),
47
52
  jsenvDirectoryRelativeUrl,
@@ -59,6 +64,7 @@ export const startDevServer = async ({
59
64
  sourcemapMethod,
60
65
  customCompilers,
61
66
  livereloadWatchConfig,
67
+ livereloadLogLevel,
62
68
  jsenvDirectoryClean,
63
69
  }) => {
64
70
  projectDirectoryUrl = assertProjectDirectoryUrl({ projectDirectoryUrl })
@@ -70,23 +76,6 @@ export const startDevServer = async ({
70
76
  outDirectoryName,
71
77
  })
72
78
 
73
- const redirectFiles = createRedirectFilesService({
74
- projectDirectoryUrl,
75
- outDirectoryRelativeUrl,
76
- mainFileRelativeUrl,
77
- })
78
- const serveExploringData = createExploringDataService({
79
- projectDirectoryUrl,
80
- outDirectoryRelativeUrl,
81
- explorableConfig,
82
- livereloading,
83
- })
84
- const serveExplorableListAsJson = createExplorableListAsJsonService({
85
- projectDirectoryUrl,
86
- outDirectoryRelativeUrl,
87
- explorableConfig,
88
- })
89
-
90
79
  const compileServer = await startCompileServer({
91
80
  signal,
92
81
  handleSIGINT,
@@ -101,13 +90,35 @@ export const startDevServer = async ({
101
90
  plugins,
102
91
  customServices: {
103
92
  ...customServices,
104
- "jsenv:redirector": redirectFiles,
105
- "jsenv:exploring-data": serveExploringData,
106
- "jsenv:explorables": serveExplorableListAsJson,
93
+ "jsenv:redirector": createRedirectorService({
94
+ projectDirectoryUrl,
95
+ mainFileRelativeUrl,
96
+ }),
97
+ "jsenv:event_source_client": createEventSourceClientService({
98
+ projectDirectoryUrl,
99
+ }),
100
+ "jsenv:exploring_index": createExploringIndexService({
101
+ projectDirectoryUrl,
102
+ }),
103
+ "jsenv:exploring_json": createExploringJsonService({
104
+ projectDirectoryUrl,
105
+ outDirectoryRelativeUrl,
106
+ explorableConfig,
107
+ livereloading,
108
+ }),
109
+ "jsenv:explorables_json": createExplorableJsonService({
110
+ projectDirectoryUrl,
111
+ outDirectoryRelativeUrl,
112
+ explorableConfig,
113
+ }),
114
+ "jsenv:toolbar": createToolbarService({
115
+ projectDirectoryUrl,
116
+ }),
107
117
  },
108
118
 
109
119
  projectDirectoryUrl,
110
120
  livereloadSSE: livereloading,
121
+ jsenvEventSourceClientInjection: true,
111
122
  jsenvToolbarInjection: jsenvToolbar,
112
123
  jsenvDirectoryRelativeUrl,
113
124
  outDirectoryName,
@@ -120,78 +131,95 @@ export const startDevServer = async ({
120
131
  babelPluginMap,
121
132
  runtimeSupport: runtimeSupportDuringDev,
122
133
  livereloadWatchConfig,
134
+ livereloadLogLevel,
123
135
  jsenvDirectoryClean,
124
136
  })
125
137
 
126
138
  return compileServer
127
139
  }
128
140
 
129
- const createRedirectFilesService = ({
141
+ const createRedirectorService = ({
130
142
  projectDirectoryUrl,
131
143
  mainFileRelativeUrl,
132
144
  }) => {
133
- const jsenvExploringRedirectorHtmlRelativeUrlForProject = urlToRelativeUrl(
134
- jsenvExploringRedirectorHtmlFileInfo.url,
145
+ const jsenvRedirectorHtmlRelativeUrlForProject = urlToRelativeUrl(
146
+ redirectorHtmlFileInfo.sourceUrl,
135
147
  projectDirectoryUrl,
136
148
  )
137
- const jsenvExploringRedirectorJsBuildRelativeUrlForProject = urlToRelativeUrl(
138
- jsenvExploringRedirectorJsFileInfo.jsenvBuildUrl,
149
+ const jsenvRedirectorJsBuildRelativeUrlForProject = urlToRelativeUrl(
150
+ redirectorJsFileInfo.buildUrl,
139
151
  projectDirectoryUrl,
140
152
  )
141
- const jsenvExploringJsBuildRelativeUrlForProject = urlToRelativeUrl(
142
- jsenvExploringIndexJsFileInfo.jsenvBuildUrl,
143
- projectDirectoryUrl,
144
- )
145
- const jsenvToolbarJsBuildRelativeUrlForProject = urlToRelativeUrl(
146
- jsenvToolbarJsFileInfo.jsenvBuildUrl,
147
- projectDirectoryUrl,
148
- )
149
-
150
153
  return setupRoutes({
151
154
  "/": (request) => {
152
155
  const redirectTarget = mainFileRelativeUrl
153
- const jsenvExploringRedirectorHtmlServerUrl = `${request.origin}/${jsenvExploringRedirectorHtmlRelativeUrlForProject}?redirect=${redirectTarget}`
154
156
  return {
155
157
  status: 307,
156
158
  headers: {
157
- location: jsenvExploringRedirectorHtmlServerUrl,
159
+ location: `${request.origin}/${jsenvRedirectorHtmlRelativeUrlForProject}?redirect=${redirectTarget}`,
158
160
  },
159
161
  }
160
162
  },
161
163
  "/.jsenv/redirect/:rest*": (request) => {
162
164
  const redirectTarget = request.ressource.slice("/.jsenv/redirect/".length)
163
- const jsenvExploringRedirectorHtmlServerUrl = `${request.origin}/${jsenvExploringRedirectorHtmlRelativeUrlForProject}?redirect=${redirectTarget}`
164
165
  return {
165
166
  status: 307,
166
167
  headers: {
167
- location: jsenvExploringRedirectorHtmlServerUrl,
168
+ location: `${request.origin}/${jsenvRedirectorHtmlRelativeUrlForProject}?redirect=${redirectTarget}`,
168
169
  },
169
170
  }
170
171
  },
171
- "/.jsenv/exploring.redirector.js": (request) => {
172
- const jsenvExploringRedirectorBuildServerUrl = `${request.origin}/${jsenvExploringRedirectorJsBuildRelativeUrlForProject}`
172
+ "/.jsenv/redirector.js": (request) => {
173
173
  return {
174
174
  status: 307,
175
175
  headers: {
176
- location: jsenvExploringRedirectorBuildServerUrl,
176
+ location: `${request.origin}/${jsenvRedirectorJsBuildRelativeUrlForProject}`,
177
177
  },
178
178
  }
179
179
  },
180
- "/.jsenv/exploring.index.js": (request) => {
181
- const jsenvExploringJsBuildServerUrl = `${request.origin}/${jsenvExploringJsBuildRelativeUrlForProject}`
180
+ })
181
+ }
182
+
183
+ const createEventSourceClientService = ({ projectDirectoryUrl }) => {
184
+ const eventSourceClientBuildRelativeUrlForProject = urlToRelativeUrl(
185
+ eventSourceClientFileInfo.buildUrl,
186
+ projectDirectoryUrl,
187
+ )
188
+ return setupRoutes({
189
+ "/.jsenv/event_source_client.js": (request) => {
182
190
  return {
183
191
  status: 307,
184
192
  headers: {
185
- location: jsenvExploringJsBuildServerUrl,
193
+ location: `${request.origin}/${eventSourceClientBuildRelativeUrlForProject}`,
186
194
  },
187
195
  }
188
196
  },
189
- "/.jsenv/toolbar.main.js": (request) => {
190
- const jsenvToolbarJsBuildServerUrl = `${request.origin}/${jsenvToolbarJsBuildRelativeUrlForProject}`
197
+ // unfortunately browser resolves sourcemap to url before redirection (not after).
198
+ // It means browser tries to load source map from "/.jsenv/jsenv-toolbar.js.map"
199
+ // we could also inline sourcemap but it's not yet possible
200
+ // inside buildProject
201
+ "/.jsenv/event_source_client.js.map": (request) => {
191
202
  return {
192
203
  status: 307,
193
204
  headers: {
194
- location: jsenvToolbarJsBuildServerUrl,
205
+ location: `${request.origin}/${eventSourceClientBuildRelativeUrlForProject}.map`,
206
+ },
207
+ }
208
+ },
209
+ })
210
+ }
211
+
212
+ const createExploringIndexService = ({ projectDirectoryUrl }) => {
213
+ const jsenvExploringJsBuildRelativeUrlForProject = urlToRelativeUrl(
214
+ exploringIndexJsFileInfo.buildUrl,
215
+ projectDirectoryUrl,
216
+ )
217
+ return setupRoutes({
218
+ "/.jsenv/exploring.index.js": (request) => {
219
+ return {
220
+ status: 307,
221
+ headers: {
222
+ location: `${request.origin}/${jsenvExploringJsBuildRelativeUrlForProject}`,
195
223
  },
196
224
  }
197
225
  },
@@ -207,18 +235,37 @@ const createRedirectFilesService = ({
207
235
  },
208
236
  }
209
237
  },
238
+ })
239
+ }
240
+
241
+ const createToolbarService = ({ projectDirectoryUrl }) => {
242
+ const toolbarJsBuildRelativeUrlForProject = urlToRelativeUrl(
243
+ toolbarJsFileInfo.buildUrl,
244
+ projectDirectoryUrl,
245
+ )
246
+
247
+ return setupRoutes({
248
+ "/.jsenv/toolbar.main.js": (request) => {
249
+ const jsenvToolbarJsBuildServerUrl = `${request.origin}/${toolbarJsBuildRelativeUrlForProject}`
250
+ return {
251
+ status: 307,
252
+ headers: {
253
+ location: jsenvToolbarJsBuildServerUrl,
254
+ },
255
+ }
256
+ },
210
257
  "/.jsenv/jsenv_toolbar.js.map": (request) => {
211
258
  return {
212
259
  status: 307,
213
260
  headers: {
214
- location: `${request.origin}/${jsenvToolbarJsBuildRelativeUrlForProject}.map`,
261
+ location: `${request.origin}/${toolbarJsBuildRelativeUrlForProject}.map`,
215
262
  },
216
263
  }
217
264
  },
218
265
  })
219
266
  }
220
267
 
221
- const createExploringDataService = ({
268
+ const createExploringJsonService = ({
222
269
  projectDirectoryUrl,
223
270
  outDirectoryRelativeUrl,
224
271
  explorableConfig,
@@ -237,7 +284,7 @@ const createExploringDataService = ({
237
284
  projectDirectoryUrl,
238
285
  ),
239
286
  exploringHtmlFileRelativeUrl: urlToRelativeUrl(
240
- jsenvExploringIndexHtmlFileInfo.url,
287
+ exploringIndexHtmlFileInfo.sourceUrl,
241
288
  projectDirectoryUrl,
242
289
  ),
243
290
  sourcemapMainFileRelativeUrl: urlToRelativeUrl(
@@ -266,7 +313,7 @@ const createExploringDataService = ({
266
313
  }
267
314
  }
268
315
 
269
- const createExplorableListAsJsonService = ({
316
+ const createExplorableJsonService = ({
270
317
  projectDirectoryUrl,
271
318
  outDirectoryRelativeUrl,
272
319
  explorableConfig,
@@ -20,11 +20,6 @@ export const validateCache = async ({
20
20
  }) => {
21
21
  const validity = { isValid: true }
22
22
 
23
- // disable cahce for html files so that we always parse the importmap file
24
- if (compiledFileUrl.endsWith(".html")) {
25
- return { isValid: false }
26
- }
27
-
28
23
  const metaJsonFileUrl = `${compiledFileUrl}__asset__meta.json`
29
24
  const metaValidity = await validateMetaFile(metaJsonFileUrl)
30
25
  mergeValidity(validity, "meta", metaValidity)
@@ -5,7 +5,6 @@ import {
5
5
  bufferToEtag,
6
6
  urlIsInsideOf,
7
7
  } from "@jsenv/filesystem"
8
- import { normalizeImportMap, resolveImport } from "@jsenv/importmap"
9
8
  import { convertFileSystemErrorToResponseProperties } from "@jsenv/server/src/internal/convertFileSystemErrorToResponseProperties.js"
10
9
 
11
10
  import { getOrGenerateCompiledFile } from "./compile-directory/getOrGenerateCompiledFile.js"
@@ -109,15 +108,10 @@ export const compileFile = async ({
109
108
  })
110
109
 
111
110
  if (request.http2) {
112
- // js resolution is special, we cannot just do resolveUrl of the import specifier
113
- // because there can be importmap (bare specifier, import without extension, custom remapping, ...)
114
- // And we would push 404 to the browser
115
- // Until we implement import map resolution pushing ressource for js imports is disabled
116
111
  const dependencyResolver = getDependencyResolver({
117
112
  compileResult,
118
113
  importmapInfos,
119
114
  request,
120
- projectDirectoryUrl,
121
115
  })
122
116
  if (dependencyResolver) {
123
117
  compileResult.dependencies.forEach((dependency) => {
@@ -236,61 +230,30 @@ export const compileFile = async ({
236
230
  }
237
231
  }
238
232
 
239
- const getDependencyResolver = ({
240
- compileResult,
241
- importmapInfos,
242
- request,
243
- projectDirectoryUrl,
244
- }) => {
233
+ const getDependencyResolver = ({ compileResult, importmapInfos, request }) => {
245
234
  const importmapKeys = Object.keys(importmapInfos)
246
235
  const requestUrl = resolveUrl(request.ressource, request.origin)
247
236
 
248
237
  if (
249
- compileResult.contentType !== "application/javascript" ||
250
- importmapKeys.length === 0
238
+ compileResult.contentType === "application/javascript" &&
239
+ // we cannot trust importmapKeys because when html is restored from cache
240
+ // it would be empty
241
+ importmapKeys.length > 0
251
242
  ) {
252
- return {
253
- type: "url_resolution",
254
- resolve: (dependency) => {
255
- const dependencyUrl = resolveUrl(dependency, requestUrl)
256
- return dependencyUrl
257
- },
258
- }
259
- }
260
-
261
- const firstImportmapInfo = importmapInfos[importmapKeys[0]]
262
- if (!firstImportmapInfo.text) {
243
+ // js resolution is special, we cannot just do resolveUrl of the import specifier
244
+ // because there can be importmap (bare specifier, import without extension, custom remapping, ...)
245
+ // And we would push 404 to the browser
246
+ // BUT I tried to push everything to the browser and it was a big fail:
247
+ // server is trying to push streams but browser rejects most push streams
248
+ // either because main file is already fetched or an other file request the same ressource
263
249
  return null
264
250
  }
265
251
 
266
- if (
267
- // we are aware only of 1 importmap
268
- importmapKeys.length === 1 ||
269
- // all importmaps are the same
270
- importmapKeys.slice(1).every(({ url }) => url === firstImportmapInfo.url)
271
- ) {
272
- const importMapBaseUrl = resolveUrl(
273
- urlToRelativeUrl(firstImportmapInfo.url, projectDirectoryUrl),
274
- `${request.origin}/`,
275
- )
276
- const importMap = normalizeImportMap(
277
- JSON.parse(firstImportmapInfo.text),
278
- importMapBaseUrl,
279
- )
280
- return {
281
- type: "importmap_resolution",
282
- resolve: (dependency) => {
283
- const dependencyUrl = resolveImport({
284
- specifier: dependency,
285
- importer: requestUrl,
286
- importMap,
287
- })
288
- return dependencyUrl
289
- },
290
- }
252
+ return {
253
+ type: "url_resolution",
254
+ resolve: (dependency) => {
255
+ const dependencyUrl = resolveUrl(dependency, requestUrl)
256
+ return dependencyUrl
257
+ },
291
258
  }
292
-
293
- // there is more than 2 importmaps, we cannot know which one to pick
294
- // (not supposed ot happen because during dev you usually use a single importmap)
295
- return null
296
259
  }
@@ -48,6 +48,7 @@ export const createCompiledFileService = ({
48
48
  groupMap,
49
49
  customCompilers,
50
50
 
51
+ jsenvEventSourceClientInjection,
51
52
  jsenvToolbarInjection,
52
53
 
53
54
  projectFileRequestedCallback,
@@ -197,6 +198,7 @@ export const createCompiledFileService = ({
197
198
 
198
199
  sourcemapMethod,
199
200
  sourcemapExcludeSources,
201
+ jsenvEventSourceClientInjection,
200
202
  jsenvToolbarInjection,
201
203
  onHtmlImportmapInfo: ({ htmlUrl, importmapInfo }) => {
202
204
  importmapInfos[htmlUrl] = importmapInfo
@@ -22,11 +22,13 @@ import { moveImportMap } from "@jsenv/importmap"
22
22
  import { createDetailedMessage } from "@jsenv/logger"
23
23
 
24
24
  import { fetchUrl } from "@jsenv/core/src/internal/fetchUrl.js"
25
+ import { jsenvBrowserSystemFileInfo } from "@jsenv/core/src/internal/jsenvInternalFiles.js"
26
+ import { redirectorHtmlFileInfo } from "@jsenv/core/src/internal/dev_server/redirector/redirector_file_info.js"
27
+ import { eventSourceClientFileInfo } from "@jsenv/core/src/internal/dev_server/event_source_client/event_source_client_file_info.js"
25
28
  import {
26
- jsenvToolbarHtmlFileInfo,
27
- jsenvBrowserSystemFileInfo,
28
- jsenvToolbarInjectorFileInfo,
29
- } from "@jsenv/core/src/internal/jsenvInternalFiles.js"
29
+ toolbarInjectorFileInfo,
30
+ toolbarHtmlFileInfo,
31
+ } from "@jsenv/core/src/internal/dev_server/toolbar/toolbar_file_info.js"
30
32
  import { stringifyDataUrl } from "@jsenv/core/src/internal/dataUrl.utils.js"
31
33
  import {
32
34
  parseHtmlString,
@@ -45,8 +47,10 @@ import {
45
47
  export const createTransformHtmlSourceFileService = ({
46
48
  logger,
47
49
  projectDirectoryUrl,
50
+ projectFileRequestedCallback,
48
51
  inlineImportMapIntoHTML,
49
52
  jsenvScriptInjection,
53
+ jsenvEventSourceClientInjection,
50
54
  jsenvToolbarInjection,
51
55
  }) => {
52
56
  /**
@@ -93,6 +97,7 @@ export const createTransformHtmlSourceFileService = ({
93
97
  }
94
98
  throw e
95
99
  }
100
+ projectFileRequestedCallback(relativeUrl, request)
96
101
  htmlInlineScriptMap.forEach((inlineScript, inlineScriptUrl) => {
97
102
  if (inlineScript.htmlFileUrl === fileUrl) {
98
103
  htmlInlineScriptMap.delete(inlineScriptUrl)
@@ -107,6 +112,7 @@ export const createTransformHtmlSourceFileService = ({
107
112
  pushResponse,
108
113
  inlineImportMapIntoHTML,
109
114
  jsenvScriptInjection,
115
+ jsenvEventSourceClientInjection,
110
116
  jsenvToolbarInjection,
111
117
  onInlineModuleScript: ({ scriptContent, scriptIdentifier }) => {
112
118
  const inlineScriptUrl = resolveUrl(scriptIdentifier, fileUrl)
@@ -138,8 +144,11 @@ const transformHTMLSourceFile = async ({
138
144
  inlineImportMapIntoHTML,
139
145
  jsenvScriptInjection,
140
146
  jsenvToolbarInjection,
147
+ jsenvEventSourceClientInjection,
141
148
  onInlineModuleScript = () => {},
142
149
  }) => {
150
+ fileUrl = urlWithoutSearch(fileUrl)
151
+
143
152
  const htmlAst = parseHtmlString(fileContent)
144
153
  if (inlineImportMapIntoHTML) {
145
154
  await inlineImportmapScripts({
@@ -154,23 +163,42 @@ const transformHTMLSourceFile = async ({
154
163
  jsenvBrowserSystemFileInfo.jsenvBuildUrl,
155
164
  projectDirectoryUrl,
156
165
  )
157
- const jsenvToolbarInjectorBuildRelativeUrlForProject = urlToRelativeUrl(
158
- jsenvToolbarInjectorFileInfo.jsenvBuildUrl,
166
+ const eventSourceClientBuildRelativeUrlForProject = urlToRelativeUrl(
167
+ eventSourceClientFileInfo.buildUrl,
168
+ projectDirectoryUrl,
169
+ )
170
+ const toolbarInjectorBuildRelativeUrlForProject = urlToRelativeUrl(
171
+ toolbarInjectorFileInfo.buildUrl,
159
172
  projectDirectoryUrl,
160
173
  )
161
174
  manipulateHtmlAst(htmlAst, {
162
175
  scriptInjections: [
163
- ...(fileUrl !== jsenvToolbarHtmlFileInfo.url && jsenvScriptInjection
176
+ ...(fileUrl !== toolbarHtmlFileInfo.sourceUrl &&
177
+ fileUrl !== redirectorHtmlFileInfo.sourceUrl &&
178
+ jsenvScriptInjection
164
179
  ? [
165
180
  {
166
181
  src: `/${jsenvBrowserBuildUrlRelativeToProject}`,
167
182
  },
168
183
  ]
169
184
  : []),
170
- ...(fileUrl !== jsenvToolbarHtmlFileInfo.url && jsenvToolbarInjection
185
+ ...(fileUrl !== toolbarHtmlFileInfo.sourceUrl &&
186
+ fileUrl !== redirectorHtmlFileInfo.sourceUrl &&
187
+ jsenvEventSourceClientInjection
188
+ ? [
189
+ {
190
+ src: `/${eventSourceClientBuildRelativeUrlForProject}`,
191
+ },
192
+ ]
193
+ : []),
194
+ ...(fileUrl !== toolbarHtmlFileInfo.sourceUrl &&
195
+ fileUrl !== redirectorHtmlFileInfo.sourceUrl &&
196
+ jsenvToolbarInjection
171
197
  ? [
172
198
  {
173
- src: `/${jsenvToolbarInjectorBuildRelativeUrlForProject}`,
199
+ src: `/${toolbarInjectorBuildRelativeUrlForProject}`,
200
+ defer: "",
201
+ async: "",
174
202
  },
175
203
  ]
176
204
  : []),
@@ -401,3 +429,9 @@ const getJsenvForceInlineAttribute = (htmlNode) => {
401
429
  )
402
430
  return jsenvForceInlineAttribute
403
431
  }
432
+
433
+ const urlWithoutSearch = (url) => {
434
+ const urlObject = new URL(url)
435
+ urlObject.search = ""
436
+ return urlObject.href
437
+ }
@@ -2,11 +2,12 @@ import { resolveUrl, urlToRelativeUrl } from "@jsenv/filesystem"
2
2
  import { moveImportMap, composeTwoImportMaps } from "@jsenv/importmap"
3
3
  import { createDetailedMessage } from "@jsenv/logger"
4
4
 
5
+ import { jsenvBrowserSystemFileInfo } from "@jsenv/core/src/internal/jsenvInternalFiles.js"
6
+ import { eventSourceClientFileInfo } from "@jsenv/core/src/internal/dev_server/event_source_client/event_source_client_file_info.js"
5
7
  import {
6
- jsenvBrowserSystemFileInfo,
7
- jsenvToolbarHtmlFileInfo,
8
- jsenvToolbarInjectorFileInfo,
9
- } from "@jsenv/core/src/internal/jsenvInternalFiles.js"
8
+ toolbarInjectorFileInfo,
9
+ toolbarHtmlFileInfo,
10
+ } from "@jsenv/core/src/internal/dev_server/toolbar/toolbar_file_info.js"
10
11
  import { fetchUrl } from "@jsenv/core/src/internal/fetchUrl.js"
11
12
  import { getDefaultImportMap } from "@jsenv/core/src/internal/import-resolution/importmap-default.js"
12
13
  import {
@@ -49,6 +50,7 @@ export const compileHtml = async ({
49
50
  sourcemapMethod,
50
51
 
51
52
  jsenvScriptInjection = true,
53
+ jsenvEventSourceClientInjection,
52
54
  jsenvToolbarInjection,
53
55
  onHtmlImportmapInfo,
54
56
  }) => {
@@ -56,8 +58,12 @@ export const compileHtml = async ({
56
58
  jsenvBrowserSystemFileInfo.jsenvBuildUrl,
57
59
  projectDirectoryUrl,
58
60
  )
59
- const jsenvToolbarInjectorBuildRelativeUrlForProject = urlToRelativeUrl(
60
- jsenvToolbarInjectorFileInfo.jsenvBuildUrl,
61
+ const eventSourceClientBuildRelativeUrlForProject = urlToRelativeUrl(
62
+ eventSourceClientFileInfo.buildUrl,
63
+ projectDirectoryUrl,
64
+ )
65
+ const toolbarInjectorBuildRelativeUrlForProject = urlToRelativeUrl(
66
+ toolbarInjectorFileInfo.buildUrl,
61
67
  projectDirectoryUrl,
62
68
  )
63
69
 
@@ -68,19 +74,31 @@ export const compileHtml = async ({
68
74
  await mutateRessourceHints(htmlAst)
69
75
  }
70
76
 
77
+ const urlNoSearch = urlWithoutSearch(url)
78
+
71
79
  manipulateHtmlAst(htmlAst, {
72
80
  scriptInjections: [
73
- ...(url !== jsenvToolbarHtmlFileInfo.url && jsenvScriptInjection
81
+ ...(urlNoSearch !== toolbarHtmlFileInfo.sourceUrl && jsenvScriptInjection
74
82
  ? [
75
83
  {
76
84
  src: `/${jsenvBrowserBuildUrlRelativeToProject}`,
77
85
  },
78
86
  ]
79
87
  : []),
80
- ...(url !== jsenvToolbarHtmlFileInfo.url && jsenvToolbarInjection
88
+ ...(urlNoSearch !== toolbarHtmlFileInfo.sourceUrl &&
89
+ jsenvEventSourceClientInjection
90
+ ? [
91
+ {
92
+ src: `/${eventSourceClientBuildRelativeUrlForProject}`,
93
+ },
94
+ ]
95
+ : []),
96
+ ...(urlNoSearch !== toolbarHtmlFileInfo.sourceUrl && jsenvToolbarInjection
81
97
  ? [
82
98
  {
83
- src: `/${jsenvToolbarInjectorBuildRelativeUrlForProject}`,
99
+ src: `/${toolbarInjectorBuildRelativeUrlForProject}`,
100
+ defer: "",
101
+ async: "",
84
102
  },
85
103
  ]
86
104
  : []),
@@ -387,3 +405,9 @@ const mutateRessourceHints = async (htmlAst) => {
387
405
  )
388
406
  mutations.forEach((mutation) => mutation())
389
407
  }
408
+
409
+ const urlWithoutSearch = (url) => {
410
+ const urlObject = new URL(url)
411
+ urlObject.search = ""
412
+ return urlObject.href
413
+ }
@@ -104,8 +104,9 @@ export const startCompileServer = async ({
104
104
  plugins,
105
105
  livereloadSSE = false,
106
106
  transformHtmlSourceFiles = true,
107
- jsenvToolbarInjection = false,
108
107
  jsenvScriptInjection = true,
108
+ jsenvEventSourceClientInjection = false,
109
+ jsenvToolbarInjection = false,
109
110
  inlineImportMapIntoHTML = true,
110
111
  }) => {
111
112
  assertArguments({
@@ -312,6 +313,7 @@ export const startCompileServer = async ({
312
313
  customCompilers,
313
314
  moduleOutFormat,
314
315
  importMetaFormat,
316
+ jsenvEventSourceClientInjection,
315
317
  jsenvToolbarInjection,
316
318
 
317
319
  projectFileRequestedCallback,
@@ -327,8 +329,10 @@ export const startCompileServer = async ({
327
329
  createTransformHtmlSourceFileService({
328
330
  logger,
329
331
  projectDirectoryUrl,
332
+ projectFileRequestedCallback,
330
333
  inlineImportMapIntoHTML,
331
334
  jsenvScriptInjection,
335
+ jsenvEventSourceClientInjection,
332
336
  jsenvToolbarInjection,
333
337
  }),
334
338
  }