@jsenv/core 25.2.1 → 25.4.1
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.
- package/dist/browser_runtime/asset-manifest.json +2 -2
- package/dist/browser_runtime/{browser_runtime_91c5a3b8.js → browser_runtime_0e3396a1.js} +15 -16
- package/dist/browser_runtime/{browser_runtime_91c5a3b8.js.map → browser_runtime_0e3396a1.js.map} +13 -13
- package/dist/build_manifest.js +5 -5
- package/dist/compile_proxy/asset-manifest.json +2 -2
- package/dist/compile_proxy/compile_proxy.html__inline__20_f4285042.js.map +343 -0
- package/dist/compile_proxy/{compile_proxy_8dfaee51.html → compile_proxy_ab528227.html} +358 -397
- package/dist/redirector/asset-manifest.json +2 -2
- package/dist/redirector/redirector.html__inline__12_404b8295.js.map +349 -0
- package/dist/redirector/{redirector_3e9a97b9.html → redirector_6df2620a.html} +369 -407
- package/dist/toolbar/asset-manifest.json +2 -2
- package/dist/toolbar/toolbar.main_279b3a68.js.map +764 -0
- package/dist/toolbar/{toolbar_361afb84.html → toolbar_0a91ca3b.html} +1509 -1583
- package/dist/toolbar_injector/asset-manifest.json +2 -2
- package/dist/toolbar_injector/{toolbar_injector_fac1e995.js → toolbar_injector_34f6ad8e.js} +18 -15
- package/dist/toolbar_injector/{toolbar_injector_fac1e995.js.map → toolbar_injector_34f6ad8e.js.map} +15 -15
- package/package.json +16 -12
- package/readme.md +54 -54
- package/src/buildProject.js +31 -26
- package/src/dev_server.js +111 -92
- package/src/execute.js +3 -8
- package/src/internal/browser_launcher/{browser_runtime_report.js → browser_runtime_profile.js} +21 -15
- package/src/internal/browser_launcher/executeHtmlFile.js +22 -14
- package/src/internal/browser_launcher/from_playwright.js +6 -4
- package/src/internal/browser_runtime/browser_runtime.js +12 -14
- package/src/internal/browser_runtime/createBrowserRuntime.js +7 -6
- package/src/internal/browser_utils/fetchAndEvalUsingFetch.js +1 -1
- package/src/internal/browser_utils/fetchJson.js +1 -1
- package/src/internal/browser_utils/{fetch-browser.js → fetch_browser.js} +0 -2
- package/src/internal/building/buildUsingRollup.js +41 -57
- package/src/internal/building/html/parseHtmlRessource.js +2 -1
- package/src/internal/building/rollup_plugin_jsenv.js +28 -8
- package/src/internal/compiling/babel_parse_error.js +9 -0
- package/src/internal/{babel_plugin_transform_import_meta.js → compiling/babel_plugin_transform_import_meta.js} +58 -9
- package/src/internal/compiling/compileFile.js +2 -2
- package/src/internal/compiling/compileHtml.js +1 -1
- package/src/internal/compiling/createCompiledFileService.js +25 -74
- package/src/internal/compiling/js-compilation-service/transformJs.js +153 -23
- package/src/internal/compiling/jsenvCompilerForHtml.js +29 -32
- package/src/internal/compiling/jsenvCompilerForImportmap.js +2 -2
- package/src/internal/compiling/jsenvCompilerForJavaScript.js +2 -4
- package/src/internal/compiling/jsenv_directory/comparison_utils.js +24 -0
- package/src/internal/compiling/{compile-directory/compile-asset.js → jsenv_directory/compile_asset.js} +0 -0
- package/src/internal/compiling/jsenv_directory/compile_context.js +68 -0
- package/src/internal/compiling/jsenv_directory/compile_profile.js +218 -0
- package/src/internal/compiling/{compile-directory/createLockRegistry.js → jsenv_directory/file_lock_registry.js} +0 -0
- package/src/internal/compiling/{compile-directory/createLockRegistry.test.js → jsenv_directory/file_lock_registry.test.js} +2 -1
- package/src/internal/compiling/{compile-directory → jsenv_directory}/fs-optimized-for-cache.js +0 -0
- package/src/internal/compiling/{compile-directory → jsenv_directory}/getOrGenerateCompiledFile.js +2 -2
- package/src/internal/compiling/jsenv_directory/jsenv_directory.js +174 -0
- package/src/internal/compiling/{compile-directory → jsenv_directory}/updateMeta.js +1 -1
- package/src/internal/compiling/{compile-directory → jsenv_directory}/validateCache.js +0 -0
- package/src/internal/compiling/sse_service/sse_service.js +369 -0
- package/src/internal/compiling/startCompileServer.js +157 -804
- package/src/internal/compiling/transformResultToCompilationResult.js +2 -2
- package/src/internal/dev_server/exploring/exploring.js +10 -8
- package/src/internal/dev_server/toolbar/compilation/toolbar.compilation.js +92 -78
- package/src/internal/dev_server/toolbar/settings/toolbar.settings.js +13 -0
- package/src/internal/dev_server/toolbar/toolbar.html +46 -16
- package/src/internal/dev_server/toolbar/toolbar.injector.js +17 -15
- package/src/internal/dev_server/toolbar/toolbar.main.js +12 -16
- package/src/internal/executing/executeConcurrently.js +1 -1
- package/src/internal/executing/executePlan.js +2 -3
- package/src/internal/{generateGroupMap → features}/babel_plugins_compatibility.js +8 -8
- package/src/internal/features/browser_feature_detection/browser_feature_detect_dynamic_import.js +20 -0
- package/src/internal/features/browser_feature_detection/browser_feature_detect_import_assertions_css.js +23 -0
- package/src/internal/features/browser_feature_detection/browser_feature_detect_import_assertions_json.js +25 -0
- package/src/internal/features/browser_feature_detection/browser_feature_detect_importmap.js +37 -0
- package/src/internal/features/browser_feature_detection/browser_feature_detect_new_stylesheet.js +9 -0
- package/src/internal/features/browser_feature_detection/browser_feature_detect_top_level_await.js +14 -0
- package/src/internal/features/browser_feature_detection/browser_feature_detection.js +89 -0
- package/src/internal/{browser_feature_detection → features/browser_feature_detection}/compile_proxy.html +1 -1
- package/src/internal/features/browser_feature_detection/execute_with_script_module.js +24 -0
- package/src/internal/features/features_compat_from_runtime.js +38 -0
- package/src/internal/features/features_compat_from_runtime_support.js +31 -0
- package/src/internal/{generateGroupMap → features}/features_compatibility.js +3 -3
- package/src/internal/{node_feature_detection → features/node_feature_detection}/feature_detect_dynamic_import.mjs +0 -0
- package/src/internal/{node_feature_detection → features/node_feature_detection}/feature_detect_top_level_await.mjs +0 -0
- package/src/internal/{node_feature_detection/nodeSupportsDynamicImport.js → features/node_feature_detection/node_feature_detect_dynamic_import.js} +0 -0
- package/src/internal/{node_feature_detection/nodeSupportsTopLevelAwait.js → features/node_feature_detection/node_feature_detect_top_level_await.js} +0 -0
- package/src/internal/features/node_feature_detection/node_feature_detection.js +66 -0
- package/src/internal/jsenv_remote_directory.js +1 -1
- package/src/internal/node_launcher/createControllableNodeProcess.js +4 -3
- package/src/internal/node_launcher/node_runtime_report.js +15 -9
- package/src/internal/node_runtime/fetchSource.js +2 -4
- package/src/internal/node_runtime/node_execution_systemjs.js +2 -5
- package/src/internal/redirector/redirector.html +40 -0
- package/src/internal/{generateGroupMap/jsenvRuntimeSupport.js → runtime_support/jsenv_runtime_support.js} +0 -0
- package/src/internal/{generateGroupMap → runtime_support}/runtime_support.js +0 -0
- package/src/internal/url_conversion.js +12 -17
- package/src/launchNode.js +29 -41
- package/dist/compile_proxy/compile_proxy.html__inline__20_809f35f7.js.map +0 -392
- package/dist/redirector/redirector.html__inline__15_e391410e.js.map +0 -397
- package/dist/toolbar/toolbar.main_6c1b3d82.js.map +0 -802
- package/src/internal/CONSTANTS.js +0 -11
- package/src/internal/browser_feature_detection/browser_feature_detection.js +0 -274
- package/src/internal/compiling/js-compilation-service/jsenvTransform.js +0 -242
- package/src/internal/dev_server/redirector/redirector.html +0 -48
- package/src/internal/generateGroupMap/generateGroupMap.js +0 -65
- package/src/internal/generateGroupMap/one_runtime_compat.js +0 -38
- package/src/internal/generateGroupMap/runtime_compat.js +0 -34
- package/src/internal/generateGroupMap/runtime_compat_composition.js +0 -76
- package/src/internal/generateGroupMap/shake_babel_plugin_map.js +0 -21
- package/src/internal/integrity/integrity_algorithms.js +0 -26
- package/src/internal/integrity/integrity_parsing.js +0 -50
- package/src/internal/integrity/integrity_update.js +0 -23
- package/src/internal/integrity/integrity_validation.js +0 -49
- package/src/internal/node_feature_detection/node_feature_detection.js +0 -117
- package/src/internal/node_runtime/detectNode.js +0 -3
- package/src/internal/runtime/computeCompileIdFromGroupId.js +0 -30
- package/src/internal/runtime/resolveGroup.js +0 -13
- package/src/internal/runtime/resolveRuntimeGroup.js +0 -11
|
@@ -0,0 +1,369 @@
|
|
|
1
|
+
import { createSSERoom } from "@jsenv/server"
|
|
2
|
+
import {
|
|
3
|
+
resolveUrl,
|
|
4
|
+
registerDirectoryLifecycle,
|
|
5
|
+
urlToExtension,
|
|
6
|
+
urlIsInsideOf,
|
|
7
|
+
urlToRelativeUrl,
|
|
8
|
+
} from "@jsenv/filesystem"
|
|
9
|
+
import { createLogger } from "@jsenv/logger"
|
|
10
|
+
import { createCallbackList } from "@jsenv/abort"
|
|
11
|
+
|
|
12
|
+
import { urlIsCompilationAsset } from "@jsenv/core/src/internal/compiling/jsenv_directory/compile_asset.js"
|
|
13
|
+
|
|
14
|
+
export const createSSEService = ({
|
|
15
|
+
projectDirectoryUrl,
|
|
16
|
+
jsenvDirectoryRelativeUrl,
|
|
17
|
+
livereloadSSE,
|
|
18
|
+
projectFileRequestedSignal,
|
|
19
|
+
|
|
20
|
+
serverStopCallbackList,
|
|
21
|
+
livereloadLogLevel,
|
|
22
|
+
livereloadWatchConfig,
|
|
23
|
+
}) => {
|
|
24
|
+
let handleSSEClientRequest
|
|
25
|
+
if (livereloadSSE) {
|
|
26
|
+
handleSSEClientRequest = createSSEServiceWithLivereload({
|
|
27
|
+
projectDirectoryUrl,
|
|
28
|
+
jsenvDirectoryRelativeUrl,
|
|
29
|
+
projectFileRequestedSignal,
|
|
30
|
+
|
|
31
|
+
serverStopCallbackList,
|
|
32
|
+
livereloadLogLevel,
|
|
33
|
+
livereloadWatchConfig,
|
|
34
|
+
})
|
|
35
|
+
} else {
|
|
36
|
+
const roomWhenLivereloadIsDisabled = createSSERoom()
|
|
37
|
+
roomWhenLivereloadIsDisabled.open()
|
|
38
|
+
handleSSEClientRequest = (request) => {
|
|
39
|
+
return roomWhenLivereloadIsDisabled.join(request)
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
return (request) => {
|
|
43
|
+
const { accept } = request.headers
|
|
44
|
+
if (!accept || !accept.includes("text/event-stream")) {
|
|
45
|
+
return null
|
|
46
|
+
}
|
|
47
|
+
return handleSSEClientRequest(request)
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
const createSSEServiceWithLivereload = ({
|
|
52
|
+
projectDirectoryUrl,
|
|
53
|
+
jsenvDirectoryRelativeUrl,
|
|
54
|
+
|
|
55
|
+
projectFileRequestedSignal,
|
|
56
|
+
serverStopCallbackList,
|
|
57
|
+
livereloadLogLevel,
|
|
58
|
+
livereloadWatchConfig,
|
|
59
|
+
}) => {
|
|
60
|
+
const livereloadLogger = createLogger({ logLevel: livereloadLogLevel })
|
|
61
|
+
const trackerMap = new Map()
|
|
62
|
+
const projectFileRequested = createCallbackList()
|
|
63
|
+
const projectFileModified = createCallbackList()
|
|
64
|
+
const projectFileRemoved = createCallbackList()
|
|
65
|
+
const projectFileAdded = createCallbackList()
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* projectFileRequestedCallback
|
|
69
|
+
* This function will be called by the compile server every time a file inside projectDirectory
|
|
70
|
+
* is requested so that we can build up the dependency tree of any file
|
|
71
|
+
*
|
|
72
|
+
*/
|
|
73
|
+
projectFileRequestedSignal.onrequested = (relativeUrl, request) => {
|
|
74
|
+
if (relativeUrl[0] === "/") {
|
|
75
|
+
relativeUrl = relativeUrl.slice(1)
|
|
76
|
+
}
|
|
77
|
+
const url = `${projectDirectoryUrl}${relativeUrl}`
|
|
78
|
+
if (
|
|
79
|
+
// Do not watch sourcemap files
|
|
80
|
+
urlToExtension(url) === ".map" ||
|
|
81
|
+
// Do not watch compilation asset, watching source file is enough
|
|
82
|
+
urlIsCompilationAsset(url)
|
|
83
|
+
) {
|
|
84
|
+
return
|
|
85
|
+
}
|
|
86
|
+
projectFileRequested.notify({ relativeUrl, request })
|
|
87
|
+
}
|
|
88
|
+
const watchDescription = {
|
|
89
|
+
...livereloadWatchConfig,
|
|
90
|
+
[jsenvDirectoryRelativeUrl]: false,
|
|
91
|
+
}
|
|
92
|
+
// wait 100ms to actually start watching
|
|
93
|
+
// otherwise server starting is delayed by the filesystem scan done in
|
|
94
|
+
// registerDirectoryLifecycle
|
|
95
|
+
const timeout = setTimeout(() => {
|
|
96
|
+
const unregisterDirectoryLifecyle = registerDirectoryLifecycle(
|
|
97
|
+
projectDirectoryUrl,
|
|
98
|
+
{
|
|
99
|
+
watchDescription,
|
|
100
|
+
updated: ({ relativeUrl }) => {
|
|
101
|
+
projectFileModified.notify(relativeUrl)
|
|
102
|
+
},
|
|
103
|
+
removed: ({ relativeUrl }) => {
|
|
104
|
+
projectFileRemoved.notify(relativeUrl)
|
|
105
|
+
},
|
|
106
|
+
added: ({ relativeUrl }) => {
|
|
107
|
+
projectFileAdded.notify(relativeUrl)
|
|
108
|
+
},
|
|
109
|
+
keepProcessAlive: false,
|
|
110
|
+
recursive: true,
|
|
111
|
+
},
|
|
112
|
+
)
|
|
113
|
+
serverStopCallbackList.add(unregisterDirectoryLifecyle)
|
|
114
|
+
}, 100)
|
|
115
|
+
serverStopCallbackList.add(() => {
|
|
116
|
+
clearTimeout(timeout)
|
|
117
|
+
})
|
|
118
|
+
|
|
119
|
+
const startTrackingRoot = (rootFile) => {
|
|
120
|
+
stopTrackingRoot(rootFile)
|
|
121
|
+
const set = new Set()
|
|
122
|
+
set.add(rootFile)
|
|
123
|
+
const depInfo = {
|
|
124
|
+
set,
|
|
125
|
+
cleanup: [],
|
|
126
|
+
}
|
|
127
|
+
trackerMap.set(rootFile, depInfo)
|
|
128
|
+
return depInfo
|
|
129
|
+
}
|
|
130
|
+
const addStopTrackingCalback = (rootFile, callback) => {
|
|
131
|
+
trackerMap.get(rootFile).cleanup.push(callback)
|
|
132
|
+
}
|
|
133
|
+
const stopTrackingRoot = (rootFile) => {
|
|
134
|
+
const depInfo = trackerMap.get(rootFile)
|
|
135
|
+
if (depInfo) {
|
|
136
|
+
depInfo.cleanup.forEach((cb) => {
|
|
137
|
+
cb()
|
|
138
|
+
})
|
|
139
|
+
trackerMap.delete(rootFile)
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
const isDependencyOf = (file, rootFile) => {
|
|
143
|
+
const depInfo = trackerMap.get(rootFile)
|
|
144
|
+
return depInfo && depInfo.set.has(file)
|
|
145
|
+
}
|
|
146
|
+
const markAsDependencyOf = (file, rootFile) => {
|
|
147
|
+
trackerMap.get(rootFile).set.add(file)
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
// each time a file is requested for the first time its dependencySet is computed
|
|
151
|
+
projectFileRequested.add((requestInfo) => {
|
|
152
|
+
const rootRelativeUrl = requestInfo.relativeUrl
|
|
153
|
+
// for now no use case of livereloading on node.js
|
|
154
|
+
// and for browsers only html file can be main files
|
|
155
|
+
// this avoid collecting dependencies of non html files that will never be used
|
|
156
|
+
if (!rootRelativeUrl.endsWith(".html")) {
|
|
157
|
+
return
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
livereloadLogger.debug(`${rootRelativeUrl} requested -> start tracking it`)
|
|
161
|
+
// when a file is requested, always rebuild its dependency in case it has changed
|
|
162
|
+
// since the last time it was requested
|
|
163
|
+
startTrackingRoot(rootRelativeUrl)
|
|
164
|
+
|
|
165
|
+
const removeDependencyRequestedCallback = projectFileRequested.add(
|
|
166
|
+
({ relativeUrl, request }) => {
|
|
167
|
+
if (isDependencyOf(relativeUrl, rootRelativeUrl)) {
|
|
168
|
+
return
|
|
169
|
+
}
|
|
170
|
+
const dependencyReport = reportDependency(
|
|
171
|
+
relativeUrl,
|
|
172
|
+
rootRelativeUrl,
|
|
173
|
+
request,
|
|
174
|
+
)
|
|
175
|
+
if (dependencyReport.dependency === false) {
|
|
176
|
+
livereloadLogger.debug(
|
|
177
|
+
`${relativeUrl} not a dependency of ${rootRelativeUrl} because ${dependencyReport.reason}`,
|
|
178
|
+
)
|
|
179
|
+
return
|
|
180
|
+
}
|
|
181
|
+
livereloadLogger.debug(
|
|
182
|
+
`${relativeUrl} is a dependency of ${rootRelativeUrl} because ${dependencyReport.reason}`,
|
|
183
|
+
)
|
|
184
|
+
markAsDependencyOf(relativeUrl, rootRelativeUrl)
|
|
185
|
+
},
|
|
186
|
+
)
|
|
187
|
+
addStopTrackingCalback(rootRelativeUrl, removeDependencyRequestedCallback)
|
|
188
|
+
const removeRootRemovedCallback = projectFileRemoved.add((relativeUrl) => {
|
|
189
|
+
if (relativeUrl === rootRelativeUrl) {
|
|
190
|
+
stopTrackingRoot(rootRelativeUrl)
|
|
191
|
+
livereloadLogger.debug(`${rootRelativeUrl} removed -> stop tracking it`)
|
|
192
|
+
}
|
|
193
|
+
})
|
|
194
|
+
addStopTrackingCalback(rootRelativeUrl, removeRootRemovedCallback)
|
|
195
|
+
})
|
|
196
|
+
|
|
197
|
+
/**
|
|
198
|
+
* trackMainAndDependencies
|
|
199
|
+
* This function is meant to be used to implement server sent events in order for a client to know
|
|
200
|
+
* when a given file or any of its dependencies changes in order to implement livereloading.
|
|
201
|
+
* At any time this function can be called with (mainRelativeUrl, { modified, removed, lastEventId })
|
|
202
|
+
* modified is called
|
|
203
|
+
* - immediatly if lastEventId is passed and mainRelativeUrl or any of its dependencies have
|
|
204
|
+
* changed since that event (last change is passed to modified if their is more than one change)
|
|
205
|
+
* - when mainRelativeUrl or any of its dependencies is modified
|
|
206
|
+
* removed is called
|
|
207
|
+
* - with same spec as modified but when a file is deleted from the filesystem instead of modified
|
|
208
|
+
*/
|
|
209
|
+
const trackMainAndDependencies = (
|
|
210
|
+
mainRelativeUrl,
|
|
211
|
+
{ modified, removed, added },
|
|
212
|
+
) => {
|
|
213
|
+
livereloadLogger.debug(`track ${mainRelativeUrl} and its dependencies`)
|
|
214
|
+
|
|
215
|
+
const removeModifiedCallback = projectFileModified.add((relativeUrl) => {
|
|
216
|
+
if (isDependencyOf(relativeUrl, mainRelativeUrl)) {
|
|
217
|
+
modified(relativeUrl)
|
|
218
|
+
}
|
|
219
|
+
})
|
|
220
|
+
const removeRemovedCallback = projectFileRemoved.add((relativeUrl) => {
|
|
221
|
+
if (isDependencyOf(relativeUrl, mainRelativeUrl)) {
|
|
222
|
+
removed(relativeUrl)
|
|
223
|
+
}
|
|
224
|
+
})
|
|
225
|
+
const removeAddedCallback = projectFileAdded.add((relativeUrl) => {
|
|
226
|
+
if (isDependencyOf(relativeUrl, mainRelativeUrl)) {
|
|
227
|
+
added(relativeUrl)
|
|
228
|
+
}
|
|
229
|
+
})
|
|
230
|
+
|
|
231
|
+
return () => {
|
|
232
|
+
livereloadLogger.debug(
|
|
233
|
+
`stop tracking ${mainRelativeUrl} and its dependencies.`,
|
|
234
|
+
)
|
|
235
|
+
removeModifiedCallback()
|
|
236
|
+
removeRemovedCallback()
|
|
237
|
+
removeAddedCallback()
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
const reportDependency = (relativeUrl, mainRelativeUrl, request) => {
|
|
242
|
+
if (relativeUrl === mainRelativeUrl) {
|
|
243
|
+
return {
|
|
244
|
+
dependency: true,
|
|
245
|
+
reason: "it's main",
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
if ("x-jsenv-execution-id" in request.headers) {
|
|
250
|
+
const executionId = request.headers["x-jsenv-execution-id"]
|
|
251
|
+
if (executionId === mainRelativeUrl) {
|
|
252
|
+
return {
|
|
253
|
+
dependency: true,
|
|
254
|
+
reason: "x-jsenv-execution-id request header",
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
return {
|
|
258
|
+
dependency: false,
|
|
259
|
+
reason: "x-jsenv-execution-id request header",
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
const { referer } = request.headers
|
|
264
|
+
if (referer) {
|
|
265
|
+
// here we know the referer is inside compileServer
|
|
266
|
+
const refererRelativeUrl = urlToOriginalRelativeUrl(
|
|
267
|
+
referer,
|
|
268
|
+
resolveUrl(jsenvDirectoryRelativeUrl, request.origin),
|
|
269
|
+
)
|
|
270
|
+
if (refererRelativeUrl) {
|
|
271
|
+
// search if referer (file requesting this one) is tracked as being a dependency of main file
|
|
272
|
+
// in that case because the importer is a dependency the importee is also a dependency
|
|
273
|
+
// eslint-disable-next-line no-unused-vars
|
|
274
|
+
for (const tracker of trackerMap) {
|
|
275
|
+
if (
|
|
276
|
+
tracker[0] === mainRelativeUrl &&
|
|
277
|
+
tracker[1].set.has(refererRelativeUrl)
|
|
278
|
+
) {
|
|
279
|
+
return {
|
|
280
|
+
dependency: true,
|
|
281
|
+
reason: "referer is a dependency",
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
return {
|
|
289
|
+
dependency: true,
|
|
290
|
+
reason: "it was requested",
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
const cache = []
|
|
295
|
+
const sseRoomLimit = 100
|
|
296
|
+
const getOrCreateSSERoom = (mainFileRelativeUrl) => {
|
|
297
|
+
const cacheEntry = cache.find(
|
|
298
|
+
(cacheEntryCandidate) =>
|
|
299
|
+
cacheEntryCandidate.mainFileRelativeUrl === mainFileRelativeUrl,
|
|
300
|
+
)
|
|
301
|
+
if (cacheEntry) {
|
|
302
|
+
return cacheEntry.sseRoom
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
const sseRoom = createSSERoom({
|
|
306
|
+
retryDuration: 2000,
|
|
307
|
+
historyLength: 100,
|
|
308
|
+
welcomeEventEnabled: true,
|
|
309
|
+
})
|
|
310
|
+
|
|
311
|
+
// each time something is modified or removed we send event to the room
|
|
312
|
+
const stopTracking = trackMainAndDependencies(mainFileRelativeUrl, {
|
|
313
|
+
modified: (relativeUrl) => {
|
|
314
|
+
sseRoom.sendEvent({ type: "file-modified", data: relativeUrl })
|
|
315
|
+
},
|
|
316
|
+
removed: (relativeUrl) => {
|
|
317
|
+
sseRoom.sendEvent({ type: "file-removed", data: relativeUrl })
|
|
318
|
+
},
|
|
319
|
+
added: (relativeUrl) => {
|
|
320
|
+
sseRoom.sendEvent({ type: "file-added", data: relativeUrl })
|
|
321
|
+
},
|
|
322
|
+
})
|
|
323
|
+
|
|
324
|
+
const removeSSECleanupCallback = serverStopCallbackList.add(() => {
|
|
325
|
+
removeSSECleanupCallback()
|
|
326
|
+
sseRoom.close()
|
|
327
|
+
stopTracking()
|
|
328
|
+
})
|
|
329
|
+
cache.push({
|
|
330
|
+
mainFileRelativeUrl,
|
|
331
|
+
sseRoom,
|
|
332
|
+
cleanup: () => {
|
|
333
|
+
removeSSECleanupCallback()
|
|
334
|
+
sseRoom.close()
|
|
335
|
+
stopTracking()
|
|
336
|
+
},
|
|
337
|
+
})
|
|
338
|
+
if (cache.length >= sseRoomLimit) {
|
|
339
|
+
const firstCacheEntry = cache.shift()
|
|
340
|
+
firstCacheEntry.cleanup()
|
|
341
|
+
}
|
|
342
|
+
return sseRoom
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
return (request) => {
|
|
346
|
+
const requestUrl = resolveUrl(request.ressource, request.origin)
|
|
347
|
+
const outDirectoryServerUrl = resolveUrl(
|
|
348
|
+
jsenvDirectoryRelativeUrl,
|
|
349
|
+
request.origin,
|
|
350
|
+
)
|
|
351
|
+
const originalRelativeUrl = urlToOriginalRelativeUrl(
|
|
352
|
+
requestUrl,
|
|
353
|
+
outDirectoryServerUrl,
|
|
354
|
+
)
|
|
355
|
+
const room = getOrCreateSSERoom(originalRelativeUrl)
|
|
356
|
+
return room.join(request)
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
const urlToOriginalRelativeUrl = (url, outDirectoryRemoteUrl) => {
|
|
361
|
+
if (urlIsInsideOf(url, outDirectoryRemoteUrl)) {
|
|
362
|
+
const afterCompileDirectory = urlToRelativeUrl(url, outDirectoryRemoteUrl)
|
|
363
|
+
const fileRelativeUrl = afterCompileDirectory.slice(
|
|
364
|
+
afterCompileDirectory.indexOf("/") + 1,
|
|
365
|
+
)
|
|
366
|
+
return fileRelativeUrl
|
|
367
|
+
}
|
|
368
|
+
return new URL(url).pathname.slice(1)
|
|
369
|
+
}
|