@jsenv/core 25.3.0 → 25.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.
- 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_2334a374.js.map +342 -0
- package/dist/compile_proxy/{compile_proxy_8dfaee51.html → compile_proxy_9f737eaf.html} +357 -398
- package/dist/redirector/asset-manifest.json +2 -2
- package/dist/redirector/redirector.html__inline__12_009c47c7.js.map +348 -0
- package/dist/redirector/{redirector_3e9a97b9.html → redirector_96f74871.html} +378 -421
- package/dist/toolbar/asset-manifest.json +2 -2
- package/dist/toolbar/{toolbar.main_6c1b3d82.js.map → toolbar.main_86335f90.js.map} +82 -115
- package/dist/toolbar/{toolbar_361afb84.html → toolbar_d3a918a4.html} +487 -508
- package/dist/toolbar_injector/asset-manifest.json +2 -2
- package/dist/toolbar_injector/toolbar_injector_978bbd14.js +267 -0
- package/dist/toolbar_injector/toolbar_injector_978bbd14.js.map +119 -0
- package/package.json +12 -11
- package/src/buildProject.js +31 -26
- package/src/dev_server.js +76 -87
- 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/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 +156 -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 +85 -78
- package/src/internal/dev_server/toolbar/settings/toolbar.settings.js +13 -0
- package/src/internal/dev_server/toolbar/toolbar.html +40 -16
- package/src/internal/dev_server/toolbar/toolbar.injector.js +11 -17
- package/src/internal/dev_server/toolbar/toolbar.main.js +6 -6
- 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 +85 -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/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/{dev_server/redirector → redirector}/redirector.html +8 -18
- 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_injector/toolbar_injector_fac1e995.js +0 -973
- package/dist/toolbar_injector/toolbar_injector_fac1e995.js.map +0 -294
- 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/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/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
|
@@ -1,59 +1,40 @@
|
|
|
1
|
-
import { readFileSync } from "node:fs"
|
|
2
1
|
import {
|
|
3
2
|
jsenvAccessControlAllowedHeaders,
|
|
4
3
|
startServer,
|
|
5
4
|
fetchFileSystem,
|
|
6
|
-
createSSERoom,
|
|
7
5
|
composeServices,
|
|
8
|
-
urlToContentType,
|
|
9
6
|
pluginServerTiming,
|
|
10
7
|
pluginRequestWaitingCheck,
|
|
11
8
|
pluginCORS,
|
|
9
|
+
readRequestBody,
|
|
12
10
|
} from "@jsenv/server"
|
|
13
|
-
import { createLogger, createDetailedMessage } from "@jsenv/logger"
|
|
14
11
|
import {
|
|
15
12
|
resolveUrl,
|
|
16
|
-
urlToFileSystemPath,
|
|
17
13
|
urlToRelativeUrl,
|
|
18
14
|
resolveDirectoryUrl,
|
|
19
|
-
readFile,
|
|
20
|
-
writeFile,
|
|
21
|
-
ensureEmptyDirectory,
|
|
22
|
-
registerDirectoryLifecycle,
|
|
23
15
|
urlIsInsideOf,
|
|
24
|
-
urlToBasename,
|
|
25
|
-
urlToExtension,
|
|
26
16
|
} from "@jsenv/filesystem"
|
|
27
|
-
import {
|
|
28
|
-
|
|
29
|
-
createCallbackListNotifiedOnce,
|
|
30
|
-
} from "@jsenv/abort"
|
|
31
|
-
|
|
32
|
-
import {
|
|
33
|
-
TOOLBAR_INJECTOR_BUILD_URL,
|
|
34
|
-
EVENT_SOURCE_CLIENT_BUILD_URL,
|
|
35
|
-
BROWSER_RUNTIME_BUILD_URL,
|
|
36
|
-
} from "@jsenv/core/dist/build_manifest.js"
|
|
37
|
-
import { generateGroupMap } from "@jsenv/core/src/internal/generateGroupMap/generateGroupMap.js"
|
|
38
|
-
import { isBrowserPartOfSupportedRuntimes } from "@jsenv/core/src/internal/generateGroupMap/runtime_support.js"
|
|
17
|
+
import { createLogger, createDetailedMessage } from "@jsenv/logger"
|
|
18
|
+
import { createCallbackListNotifiedOnce } from "@jsenv/abort"
|
|
39
19
|
|
|
40
|
-
import { createJsenvRemoteDirectory } from "../jsenv_remote_directory.js"
|
|
41
20
|
import {
|
|
42
21
|
sourcemapMainFileInfo,
|
|
43
22
|
sourcemapMappingFileInfo,
|
|
44
|
-
} from "
|
|
23
|
+
} from "@jsenv/core/src/internal/jsenvInternalFiles.js"
|
|
24
|
+
import { createJsenvRemoteDirectory } from "../jsenv_remote_directory.js"
|
|
45
25
|
import { babelPluginReplaceExpressions } from "../babel_plugin_replace_expressions.js"
|
|
46
|
-
import {
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
} from "
|
|
26
|
+
import { jsenvDistDirectoryUrl } from "../jsenvCoreDirectoryUrl.js"
|
|
27
|
+
import { createCompileContext } from "./jsenv_directory/compile_context.js"
|
|
28
|
+
import { createCompileProfile } from "./jsenv_directory/compile_profile.js"
|
|
29
|
+
import { setupJsenvDirectory } from "./jsenv_directory/jsenv_directory.js"
|
|
30
|
+
import { urlIsCompilationAsset } from "./jsenv_directory/compile_asset.js"
|
|
31
|
+
import { createSSEService } from "./sse_service/sse_service.js"
|
|
50
32
|
import { loadBabelPluginMapFromFile } from "./load_babel_plugin_map_from_file.js"
|
|
51
33
|
import { extractSyntaxBabelPluginMap } from "./babel_plugins.js"
|
|
52
34
|
import { babelPluginGlobalThisAsJsenvImport } from "./babel_plugin_global_this_as_jsenv_import.js"
|
|
53
35
|
import { babelPluginNewStylesheetAsJsenvImport } from "./babel_plugin_new_stylesheet_as_jsenv_import.js"
|
|
54
36
|
import { babelPluginImportAssertions } from "./babel_plugin_import_assertions.js"
|
|
55
37
|
import { createCompiledFileService } from "./createCompiledFileService.js"
|
|
56
|
-
import { urlIsCompilationAsset } from "./compile-directory/compile-asset.js"
|
|
57
38
|
import { createTransformHtmlSourceFileService } from "./html_source_file_service.js"
|
|
58
39
|
|
|
59
40
|
let compileServerId = 0
|
|
@@ -77,7 +58,6 @@ export const startCompileServer = async ({
|
|
|
77
58
|
|
|
78
59
|
jsenvDirectoryRelativeUrl = ".jsenv",
|
|
79
60
|
jsenvDirectoryClean = false,
|
|
80
|
-
outDirectoryName = "out",
|
|
81
61
|
|
|
82
62
|
sourcemapMethod = "comment", // "inline" is also possible
|
|
83
63
|
sourcemapExcludeSources = false, // this should increase perf (no need to download source for browser)
|
|
@@ -88,9 +68,7 @@ export const startCompileServer = async ({
|
|
|
88
68
|
|
|
89
69
|
// js compile options
|
|
90
70
|
moduleOutFormat,
|
|
91
|
-
importMetaFormat,
|
|
92
71
|
topLevelAwait,
|
|
93
|
-
env = {},
|
|
94
72
|
processEnvNodeEnv = process.env.NODE_ENV,
|
|
95
73
|
replaceProcessEnvNodeEnv = true,
|
|
96
74
|
replaceGlobalObject = false,
|
|
@@ -105,7 +83,6 @@ export const startCompileServer = async ({
|
|
|
105
83
|
serviceWorkers = [],
|
|
106
84
|
importMapInWebWorkers = false,
|
|
107
85
|
prependSystemJs,
|
|
108
|
-
runtimeSupport,
|
|
109
86
|
|
|
110
87
|
// remaining options
|
|
111
88
|
livereloadWatchConfig = {
|
|
@@ -123,32 +100,14 @@ export const startCompileServer = async ({
|
|
|
123
100
|
jsenvEventSourceClientInjection = false,
|
|
124
101
|
jsenvToolbarInjection = false,
|
|
125
102
|
inlineImportMapIntoHTML = true,
|
|
103
|
+
errorStackRemapping = true,
|
|
126
104
|
}) => {
|
|
127
|
-
assertArguments({
|
|
128
|
-
projectDirectoryUrl,
|
|
129
|
-
jsenvDirectoryRelativeUrl,
|
|
130
|
-
outDirectoryName,
|
|
131
|
-
})
|
|
132
|
-
|
|
133
|
-
const jsenvDirectoryUrl = resolveDirectoryUrl(
|
|
134
|
-
jsenvDirectoryRelativeUrl,
|
|
135
|
-
projectDirectoryUrl,
|
|
136
|
-
)
|
|
137
|
-
const outDirectoryUrl = resolveDirectoryUrl(
|
|
138
|
-
outDirectoryName,
|
|
139
|
-
jsenvDirectoryUrl,
|
|
140
|
-
)
|
|
141
|
-
const outDirectoryRelativeUrl = urlToRelativeUrl(
|
|
142
|
-
outDirectoryUrl,
|
|
143
|
-
projectDirectoryUrl,
|
|
144
|
-
)
|
|
145
|
-
// normalization
|
|
146
|
-
jsenvDirectoryRelativeUrl = urlToRelativeUrl(
|
|
147
|
-
jsenvDirectoryUrl,
|
|
148
|
-
projectDirectoryUrl,
|
|
149
|
-
)
|
|
150
105
|
const logger = createLogger({ logLevel })
|
|
151
|
-
|
|
106
|
+
if (typeof projectDirectoryUrl !== "string") {
|
|
107
|
+
throw new TypeError(
|
|
108
|
+
`projectDirectoryUrl must be a string. got ${projectDirectoryUrl}`,
|
|
109
|
+
)
|
|
110
|
+
}
|
|
152
111
|
preservedUrls = {
|
|
153
112
|
// Authorize jsenv to modify any file url
|
|
154
113
|
// because the goal is to build the files into chunks
|
|
@@ -168,18 +127,12 @@ export const startCompileServer = async ({
|
|
|
168
127
|
*/
|
|
169
128
|
...preservedUrls,
|
|
170
129
|
}
|
|
171
|
-
const jsenvRemoteDirectory = createJsenvRemoteDirectory({
|
|
172
|
-
projectDirectoryUrl,
|
|
173
|
-
jsenvDirectoryRelativeUrl,
|
|
174
|
-
preservedUrls,
|
|
175
|
-
})
|
|
176
130
|
const workerUrls = workers.map((worker) =>
|
|
177
131
|
resolveUrl(worker, projectDirectoryUrl),
|
|
178
132
|
)
|
|
179
133
|
const serviceWorkerUrls = serviceWorkers.map((serviceWorker) =>
|
|
180
134
|
resolveUrl(serviceWorker, projectDirectoryUrl),
|
|
181
135
|
)
|
|
182
|
-
const browser = isBrowserPartOfSupportedRuntimes(runtimeSupport)
|
|
183
136
|
const babelPluginMapFromFile = await loadBabelPluginMapFromFile({
|
|
184
137
|
projectDirectoryUrl,
|
|
185
138
|
babelConfigFileUrl,
|
|
@@ -211,33 +164,15 @@ export const startCompileServer = async ({
|
|
|
211
164
|
delete babelPluginMap[key]
|
|
212
165
|
}
|
|
213
166
|
})
|
|
214
|
-
|
|
215
167
|
const { babelSyntaxPluginMap, babelPluginMapWithoutSyntax } =
|
|
216
168
|
extractSyntaxBabelPluginMap(babelPluginMap)
|
|
217
|
-
const compileServerGroupMap = generateGroupMap({
|
|
218
|
-
featureNames: [
|
|
219
|
-
...(browser
|
|
220
|
-
? [
|
|
221
|
-
"module",
|
|
222
|
-
"importmap",
|
|
223
|
-
"import_assertion_type_json",
|
|
224
|
-
"import_assertion_type_css",
|
|
225
|
-
]
|
|
226
|
-
: []),
|
|
227
|
-
...(browser && workerUrls.length > 0 ? ["worker_type_module"] : []),
|
|
228
|
-
...(browser && importMapInWebWorkers ? ["worker_importmap"] : []),
|
|
229
|
-
...Object.keys(babelPluginMapWithoutSyntax),
|
|
230
|
-
],
|
|
231
|
-
runtimeSupport,
|
|
232
|
-
})
|
|
233
|
-
|
|
234
169
|
babelPluginMap = {
|
|
235
170
|
// When code should be compatible with browsers, ensure
|
|
236
171
|
// process.env.NODE_ENV is replaced to be executable in a browser by forcing
|
|
237
172
|
// "transform-replace-expressions" babel plugin.
|
|
238
173
|
// It happens for module written in ESM but also using process.env.NODE_ENV
|
|
239
174
|
// for example "react-redux"
|
|
240
|
-
// This babel plugin won't force compilation because it's added after "
|
|
175
|
+
// This babel plugin won't force compilation because it's added after "featureNames"
|
|
241
176
|
// however it will be used even if not part of "missingFeatureNames"
|
|
242
177
|
// as visible in "babelPluginMapFromCompileId"
|
|
243
178
|
// This is a quick workaround to get things working because:
|
|
@@ -248,137 +183,168 @@ export const startCompileServer = async ({
|
|
|
248
183
|
// Ideally this should be a custom compiler dedicated for this use case. It's not the case
|
|
249
184
|
// for now because it was faster to do it this way and the use case is a bit blurry:
|
|
250
185
|
// What should this custom compiler do? Just replace some node globals? How would it be named and documented?
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
},
|
|
269
|
-
allowConflictingReplacements: true,
|
|
270
|
-
},
|
|
271
|
-
],
|
|
272
|
-
}
|
|
273
|
-
: {}),
|
|
186
|
+
"transform-replace-expressions": [
|
|
187
|
+
babelPluginReplaceExpressions,
|
|
188
|
+
{
|
|
189
|
+
replaceMap: {
|
|
190
|
+
...(replaceProcessEnvNodeEnv
|
|
191
|
+
? { "process.env.NODE_ENV": `("${processEnvNodeEnv}")` }
|
|
192
|
+
: {}),
|
|
193
|
+
...(replaceGlobalObject ? { global: "globalThis" } : {}),
|
|
194
|
+
...(replaceGlobalFilename
|
|
195
|
+
? { __filename: __filenameReplacement }
|
|
196
|
+
: {}),
|
|
197
|
+
...(replaceGlobalDirname ? { __dirname: __dirnameReplacement } : {}),
|
|
198
|
+
...replaceMap,
|
|
199
|
+
},
|
|
200
|
+
allowConflictingReplacements: true,
|
|
201
|
+
},
|
|
202
|
+
],
|
|
274
203
|
...babelSyntaxPluginMap,
|
|
275
204
|
...babelPluginMap,
|
|
276
205
|
}
|
|
206
|
+
jsenvDirectoryRelativeUrl = assertAndNormalizeJsenvDirectoryRelativeUrl({
|
|
207
|
+
projectDirectoryUrl,
|
|
208
|
+
jsenvDirectoryRelativeUrl,
|
|
209
|
+
})
|
|
210
|
+
const compileContext = await createCompileContext({
|
|
211
|
+
preservedUrls,
|
|
212
|
+
workers,
|
|
213
|
+
serviceWorkers,
|
|
214
|
+
replaceProcessEnvNodeEnv,
|
|
215
|
+
inlineImportMapIntoHTML,
|
|
216
|
+
})
|
|
217
|
+
const jsenvDirectory = await setupJsenvDirectory({
|
|
218
|
+
logger,
|
|
219
|
+
projectDirectoryUrl,
|
|
220
|
+
jsenvDirectoryRelativeUrl,
|
|
221
|
+
jsenvDirectoryClean,
|
|
222
|
+
compileServerCanWriteOnFilesystem,
|
|
223
|
+
compileContext,
|
|
224
|
+
})
|
|
225
|
+
const jsenvRemoteDirectory = createJsenvRemoteDirectory({
|
|
226
|
+
projectDirectoryUrl,
|
|
227
|
+
jsenvDirectoryRelativeUrl,
|
|
228
|
+
preservedUrls,
|
|
229
|
+
})
|
|
277
230
|
|
|
278
231
|
const serverStopCallbackList = createCallbackListNotifiedOnce()
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
serverStopCallbackList,
|
|
232
|
+
const projectFileRequestedSignal = { onrequested: () => {} }
|
|
233
|
+
customServices = {
|
|
234
|
+
...customServices,
|
|
235
|
+
"jsenv:sse": createSSEService({
|
|
284
236
|
projectDirectoryUrl,
|
|
285
237
|
jsenvDirectoryRelativeUrl,
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
livereloadWatchConfig,
|
|
289
|
-
})
|
|
238
|
+
livereloadSSE,
|
|
239
|
+
projectFileRequestedSignal,
|
|
290
240
|
|
|
291
|
-
projectFileRequestedCallback = sseSetup.projectFileRequestedCallback
|
|
292
|
-
const serveSSEForLivereload = createSSEForLivereloadService({
|
|
293
241
|
serverStopCallbackList,
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
})
|
|
297
|
-
customServices = {
|
|
298
|
-
...customServices,
|
|
299
|
-
"jsenv:sse": serveSSEForLivereload,
|
|
300
|
-
}
|
|
301
|
-
} else {
|
|
302
|
-
const roomWhenLivereloadIsDisabled = createSSERoom()
|
|
303
|
-
roomWhenLivereloadIsDisabled.open()
|
|
304
|
-
customServices = {
|
|
305
|
-
...customServices,
|
|
306
|
-
"jsenv:sse": (request) => {
|
|
307
|
-
const { accept } = request.headers
|
|
308
|
-
if (!accept || !accept.includes("text/event-stream")) {
|
|
309
|
-
return null
|
|
310
|
-
}
|
|
311
|
-
return roomWhenLivereloadIsDisabled.join(request)
|
|
312
|
-
},
|
|
313
|
-
}
|
|
242
|
+
livereloadLogLevel,
|
|
243
|
+
livereloadWatchConfig,
|
|
244
|
+
}),
|
|
314
245
|
}
|
|
246
|
+
const projectFileRequestedCallback = (...args) =>
|
|
247
|
+
projectFileRequestedSignal.onrequested(...args)
|
|
315
248
|
|
|
316
|
-
const
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
249
|
+
const createCompileIdFromRuntimeReport = async (runtimeReport) => {
|
|
250
|
+
const compileProfile = createCompileProfile({
|
|
251
|
+
importDefaultExtension,
|
|
252
|
+
customCompilers,
|
|
253
|
+
babelPluginMapWithoutSyntax,
|
|
254
|
+
preservedUrls,
|
|
255
|
+
workerUrls,
|
|
256
|
+
importMapInWebWorkers,
|
|
257
|
+
moduleOutFormat,
|
|
258
|
+
sourcemapMethod,
|
|
259
|
+
sourcemapExcludeSources,
|
|
260
|
+
jsenvEventSourceClientInjection,
|
|
261
|
+
jsenvToolbarInjection,
|
|
322
262
|
|
|
323
|
-
|
|
324
|
-
workers,
|
|
325
|
-
serviceWorkers,
|
|
326
|
-
compileServerGroupMap,
|
|
327
|
-
babelPluginMap,
|
|
328
|
-
replaceProcessEnvNodeEnv,
|
|
329
|
-
processEnvNodeEnv,
|
|
330
|
-
env,
|
|
331
|
-
inlineImportMapIntoHTML,
|
|
332
|
-
customCompilers,
|
|
333
|
-
jsenvToolbarInjection,
|
|
334
|
-
sourcemapMethod,
|
|
335
|
-
sourcemapExcludeSources,
|
|
336
|
-
})
|
|
337
|
-
if (compileServerCanWriteOnFilesystem) {
|
|
338
|
-
await cleanOutDirectoryIfNeeded({
|
|
339
|
-
logger,
|
|
340
|
-
outDirectoryUrl,
|
|
341
|
-
jsenvDirectoryUrl,
|
|
342
|
-
jsenvDirectoryClean,
|
|
343
|
-
compileServerMetaFileInfo,
|
|
263
|
+
runtimeReport,
|
|
344
264
|
})
|
|
345
|
-
await
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
265
|
+
const compileId = await jsenvDirectory.getOrCreateCompileId({
|
|
266
|
+
runtimeName: runtimeReport.name,
|
|
267
|
+
runtimeVersion: runtimeReport.version,
|
|
268
|
+
compileProfile,
|
|
269
|
+
})
|
|
270
|
+
return { compileProfile, compileId }
|
|
350
271
|
}
|
|
351
272
|
|
|
352
273
|
const jsenvServices = {
|
|
274
|
+
"service:compile profile": async (request) => {
|
|
275
|
+
if (request.ressource !== `/__jsenv_compile_profile__`) {
|
|
276
|
+
return null
|
|
277
|
+
}
|
|
278
|
+
if (request.method === "GET") {
|
|
279
|
+
const body = JSON.stringify(
|
|
280
|
+
{
|
|
281
|
+
jsenvDirectoryRelativeUrl,
|
|
282
|
+
inlineImportMapIntoHTML,
|
|
283
|
+
errorStackRemapping,
|
|
284
|
+
sourcemapMainFileRelativeUrl: urlToRelativeUrl(
|
|
285
|
+
sourcemapMainFileInfo.url,
|
|
286
|
+
projectDirectoryUrl,
|
|
287
|
+
),
|
|
288
|
+
sourcemapMappingFileRelativeUrl: urlToRelativeUrl(
|
|
289
|
+
sourcemapMappingFileInfo.url,
|
|
290
|
+
projectDirectoryUrl,
|
|
291
|
+
),
|
|
292
|
+
},
|
|
293
|
+
null,
|
|
294
|
+
" ",
|
|
295
|
+
)
|
|
296
|
+
return {
|
|
297
|
+
status: 200,
|
|
298
|
+
headers: {
|
|
299
|
+
"content-type": "application/json",
|
|
300
|
+
"content-length": Buffer.byteLength(body),
|
|
301
|
+
},
|
|
302
|
+
body,
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
if (request.method === "POST") {
|
|
306
|
+
const runtimeReport = await readRequestBody(request, {
|
|
307
|
+
as: "json",
|
|
308
|
+
})
|
|
309
|
+
const { compileProfile, compileId } =
|
|
310
|
+
await createCompileIdFromRuntimeReport(runtimeReport)
|
|
311
|
+
const responseBodyAsObject = {
|
|
312
|
+
compileProfile,
|
|
313
|
+
compileId,
|
|
314
|
+
}
|
|
315
|
+
const responseBodyAsString = JSON.stringify(
|
|
316
|
+
responseBodyAsObject,
|
|
317
|
+
null,
|
|
318
|
+
" ",
|
|
319
|
+
)
|
|
320
|
+
return {
|
|
321
|
+
status: 200,
|
|
322
|
+
headers: {
|
|
323
|
+
"content-type": "application/json",
|
|
324
|
+
"content-length": Buffer.byteLength(responseBodyAsString),
|
|
325
|
+
},
|
|
326
|
+
body: responseBodyAsString,
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
return null
|
|
330
|
+
},
|
|
353
331
|
"service:compilation asset": createCompilationAssetFileService({
|
|
354
332
|
projectDirectoryUrl,
|
|
355
333
|
}),
|
|
356
|
-
"service:compile server meta": createCompileServerMetaService({
|
|
357
|
-
projectDirectoryUrl,
|
|
358
|
-
outDirectoryUrl,
|
|
359
|
-
compileServerMetaFileInfo,
|
|
360
|
-
}),
|
|
361
334
|
"service:compiled file": createCompiledFileService({
|
|
362
335
|
logger,
|
|
363
336
|
|
|
364
337
|
projectDirectoryUrl,
|
|
365
338
|
jsenvDirectoryRelativeUrl,
|
|
366
|
-
|
|
339
|
+
jsenvDirectory,
|
|
367
340
|
jsenvRemoteDirectory,
|
|
368
341
|
|
|
369
|
-
importDefaultExtension,
|
|
370
|
-
|
|
371
|
-
runtimeSupport,
|
|
372
342
|
topLevelAwait,
|
|
373
|
-
groupMap: compileServerGroupMap,
|
|
374
343
|
babelPluginMap,
|
|
375
344
|
customCompilers,
|
|
376
345
|
workerUrls,
|
|
377
346
|
serviceWorkerUrls,
|
|
378
|
-
importMapInWebWorkers,
|
|
379
347
|
prependSystemJs,
|
|
380
|
-
moduleOutFormat,
|
|
381
|
-
importMetaFormat,
|
|
382
348
|
jsenvEventSourceClientInjection,
|
|
383
349
|
jsenvToolbarInjection,
|
|
384
350
|
|
|
@@ -457,47 +423,19 @@ export const startCompileServer = async ({
|
|
|
457
423
|
return {
|
|
458
424
|
id: compileServerId++,
|
|
459
425
|
jsenvDirectoryRelativeUrl,
|
|
460
|
-
|
|
426
|
+
createCompileIdFromRuntimeReport,
|
|
461
427
|
...compileServer,
|
|
462
|
-
compileServerGroupMap,
|
|
463
428
|
babelPluginMap,
|
|
464
429
|
preservedUrls,
|
|
465
430
|
projectFileRequestedCallback,
|
|
466
431
|
}
|
|
467
432
|
}
|
|
468
433
|
|
|
469
|
-
|
|
434
|
+
// updating "jsenvDirectoryRelativeUrl" normalizes it (ensure it has trailing "/")
|
|
435
|
+
export const assertAndNormalizeJsenvDirectoryRelativeUrl = ({
|
|
470
436
|
projectDirectoryUrl,
|
|
471
437
|
jsenvDirectoryRelativeUrl = ".jsenv",
|
|
472
|
-
outDirectoryName = "out",
|
|
473
|
-
}) => {
|
|
474
|
-
const jsenvDirectoryUrl = resolveDirectoryUrl(
|
|
475
|
-
jsenvDirectoryRelativeUrl,
|
|
476
|
-
projectDirectoryUrl,
|
|
477
|
-
)
|
|
478
|
-
const outDirectoryUrl = resolveDirectoryUrl(
|
|
479
|
-
outDirectoryName,
|
|
480
|
-
jsenvDirectoryUrl,
|
|
481
|
-
)
|
|
482
|
-
const outDirectoryRelativeUrl = urlToRelativeUrl(
|
|
483
|
-
outDirectoryUrl,
|
|
484
|
-
projectDirectoryUrl,
|
|
485
|
-
)
|
|
486
|
-
|
|
487
|
-
return outDirectoryRelativeUrl
|
|
488
|
-
}
|
|
489
|
-
|
|
490
|
-
const assertArguments = ({
|
|
491
|
-
projectDirectoryUrl,
|
|
492
|
-
jsenvDirectoryRelativeUrl,
|
|
493
|
-
outDirectoryName,
|
|
494
438
|
}) => {
|
|
495
|
-
if (typeof projectDirectoryUrl !== "string") {
|
|
496
|
-
throw new TypeError(
|
|
497
|
-
`projectDirectoryUrl must be a string. got ${projectDirectoryUrl}`,
|
|
498
|
-
)
|
|
499
|
-
}
|
|
500
|
-
|
|
501
439
|
if (typeof jsenvDirectoryRelativeUrl !== "string") {
|
|
502
440
|
throw new TypeError(
|
|
503
441
|
`jsenvDirectoryRelativeUrl must be a string. got ${jsenvDirectoryRelativeUrl}`,
|
|
@@ -507,7 +445,6 @@ const assertArguments = ({
|
|
|
507
445
|
jsenvDirectoryRelativeUrl,
|
|
508
446
|
projectDirectoryUrl,
|
|
509
447
|
)
|
|
510
|
-
|
|
511
448
|
if (!jsenvDirectoryUrl.startsWith(projectDirectoryUrl)) {
|
|
512
449
|
throw new TypeError(
|
|
513
450
|
createDetailedMessage(
|
|
@@ -519,441 +456,11 @@ const assertArguments = ({
|
|
|
519
456
|
),
|
|
520
457
|
)
|
|
521
458
|
}
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
}
|
|
528
|
-
}
|
|
529
|
-
|
|
530
|
-
const cleanOutDirectoryIfNeeded = async ({
|
|
531
|
-
logger,
|
|
532
|
-
outDirectoryUrl,
|
|
533
|
-
jsenvDirectoryClean,
|
|
534
|
-
jsenvDirectoryUrl,
|
|
535
|
-
compileServerMetaFileInfo,
|
|
536
|
-
}) => {
|
|
537
|
-
if (jsenvDirectoryClean) {
|
|
538
|
-
logger.debug(
|
|
539
|
-
`Cleaning jsenv directory because jsenvDirectoryClean parameter enabled`,
|
|
540
|
-
)
|
|
541
|
-
await ensureEmptyDirectory(jsenvDirectoryUrl)
|
|
542
|
-
}
|
|
543
|
-
|
|
544
|
-
let previousCompileServerMeta
|
|
545
|
-
try {
|
|
546
|
-
const source = await readFile(compileServerMetaFileInfo.url)
|
|
547
|
-
if (source === "") {
|
|
548
|
-
previousCompileServerMeta = null
|
|
549
|
-
logger.debug(
|
|
550
|
-
`compiler server meta file is empty ${compileServerMetaFileInfo.url}`,
|
|
551
|
-
)
|
|
552
|
-
} else {
|
|
553
|
-
previousCompileServerMeta = JSON.parse(source)
|
|
554
|
-
}
|
|
555
|
-
} catch (e) {
|
|
556
|
-
if (e.code === "ENOENT") {
|
|
557
|
-
previousCompileServerMeta = null
|
|
558
|
-
} else if (e.name === "SyntaxError") {
|
|
559
|
-
previousCompileServerMeta = null
|
|
560
|
-
logger.warn(`Syntax error while parsing ${compileServerMetaFileInfo.url}`)
|
|
561
|
-
} else {
|
|
562
|
-
throw e
|
|
563
|
-
}
|
|
564
|
-
}
|
|
565
|
-
|
|
566
|
-
if (previousCompileServerMeta !== null) {
|
|
567
|
-
const outDirectoryChanges = getOutDirectoryChanges(
|
|
568
|
-
previousCompileServerMeta,
|
|
569
|
-
compileServerMetaFileInfo.data,
|
|
570
|
-
)
|
|
571
|
-
|
|
572
|
-
if (outDirectoryChanges) {
|
|
573
|
-
if (!jsenvDirectoryClean) {
|
|
574
|
-
logger.debug(
|
|
575
|
-
createDetailedMessage(
|
|
576
|
-
`Cleaning jsenv ${urlToBasename(
|
|
577
|
-
outDirectoryUrl.slice(0, -1),
|
|
578
|
-
)} directory because configuration has changed.`,
|
|
579
|
-
{
|
|
580
|
-
"changes": outDirectoryChanges.namedChanges
|
|
581
|
-
? outDirectoryChanges.namedChanges
|
|
582
|
-
: `something`,
|
|
583
|
-
"out directory": urlToFileSystemPath(outDirectoryUrl),
|
|
584
|
-
},
|
|
585
|
-
),
|
|
586
|
-
)
|
|
587
|
-
}
|
|
588
|
-
await ensureEmptyDirectory(outDirectoryUrl)
|
|
589
|
-
}
|
|
590
|
-
}
|
|
591
|
-
}
|
|
592
|
-
|
|
593
|
-
const getOutDirectoryChanges = (
|
|
594
|
-
previousCompileServerMeta,
|
|
595
|
-
compileServerMeta,
|
|
596
|
-
) => {
|
|
597
|
-
const changes = []
|
|
598
|
-
|
|
599
|
-
Object.keys(compileServerMeta).forEach((key) => {
|
|
600
|
-
const now = compileServerMeta[key]
|
|
601
|
-
const previous = previousCompileServerMeta[key]
|
|
602
|
-
if (!compareValueJson(now, previous)) {
|
|
603
|
-
changes.push(key)
|
|
604
|
-
}
|
|
605
|
-
})
|
|
606
|
-
|
|
607
|
-
if (changes.length > 0) {
|
|
608
|
-
return { namedChanges: changes }
|
|
609
|
-
}
|
|
610
|
-
|
|
611
|
-
// in case basic comparison from above is not enough
|
|
612
|
-
if (!compareValueJson(previousCompileServerMeta, compileServerMeta)) {
|
|
613
|
-
return { somethingChanged: true }
|
|
614
|
-
}
|
|
615
|
-
|
|
616
|
-
return null
|
|
617
|
-
}
|
|
618
|
-
|
|
619
|
-
const compareValueJson = (left, right) => {
|
|
620
|
-
return JSON.stringify(left) === JSON.stringify(right)
|
|
621
|
-
}
|
|
622
|
-
|
|
623
|
-
/**
|
|
624
|
-
* We need to get two things:
|
|
625
|
-
* { projectFileRequestedCallback, trackMainAndDependencies }
|
|
626
|
-
*
|
|
627
|
-
* projectFileRequestedCallback
|
|
628
|
-
* This function will be called by the compile server every time a file inside projectDirectory
|
|
629
|
-
* is requested so that we can build up the dependency tree of any file
|
|
630
|
-
*
|
|
631
|
-
* trackMainAndDependencies
|
|
632
|
-
* This function is meant to be used to implement server sent events in order for a client to know
|
|
633
|
-
* when a given file or any of its dependencies changes in order to implement livereloading.
|
|
634
|
-
* At any time this function can be called with (mainRelativeUrl, { modified, removed, lastEventId })
|
|
635
|
-
* modified is called
|
|
636
|
-
* - immediatly if lastEventId is passed and mainRelativeUrl or any of its dependencies have
|
|
637
|
-
* changed since that event (last change is passed to modified if their is more than one change)
|
|
638
|
-
* - when mainRelativeUrl or any of its dependencies is modified
|
|
639
|
-
* removed is called
|
|
640
|
-
* - with same spec as modified but when a file is deleted from the filesystem instead of modified
|
|
641
|
-
*
|
|
642
|
-
*/
|
|
643
|
-
const setupServerSentEventsForLivereload = ({
|
|
644
|
-
serverStopCallbackList,
|
|
645
|
-
projectDirectoryUrl,
|
|
646
|
-
jsenvDirectoryRelativeUrl,
|
|
647
|
-
outDirectoryRelativeUrl,
|
|
648
|
-
livereloadLogLevel,
|
|
649
|
-
livereloadWatchConfig,
|
|
650
|
-
}) => {
|
|
651
|
-
const livereloadLogger = createLogger({ logLevel: livereloadLogLevel })
|
|
652
|
-
const trackerMap = new Map()
|
|
653
|
-
const projectFileRequested = createCallbackList()
|
|
654
|
-
const projectFileModified = createCallbackList()
|
|
655
|
-
const projectFileRemoved = createCallbackList()
|
|
656
|
-
const projectFileAdded = createCallbackList()
|
|
657
|
-
|
|
658
|
-
const projectFileRequestedCallback = (relativeUrl, request) => {
|
|
659
|
-
if (relativeUrl[0] === "/") {
|
|
660
|
-
relativeUrl = relativeUrl.slice(1)
|
|
661
|
-
}
|
|
662
|
-
const url = `${projectDirectoryUrl}${relativeUrl}`
|
|
663
|
-
|
|
664
|
-
if (
|
|
665
|
-
// Do not watch sourcemap files
|
|
666
|
-
urlToExtension(url) === ".map" ||
|
|
667
|
-
// Do not watch compilation asset, watching source file is enough
|
|
668
|
-
urlIsCompilationAsset(url)
|
|
669
|
-
) {
|
|
670
|
-
return
|
|
671
|
-
}
|
|
672
|
-
|
|
673
|
-
projectFileRequested.notify({ relativeUrl, request })
|
|
674
|
-
}
|
|
675
|
-
const watchDescription = {
|
|
676
|
-
...livereloadWatchConfig,
|
|
677
|
-
[jsenvDirectoryRelativeUrl]: false,
|
|
678
|
-
}
|
|
679
|
-
|
|
680
|
-
// wait 100ms to actually start watching
|
|
681
|
-
// otherwise server starting is delayed by the filesystem scan done in
|
|
682
|
-
// registerDirectoryLifecycle
|
|
683
|
-
const timeout = setTimeout(() => {
|
|
684
|
-
const unregisterDirectoryLifecyle = registerDirectoryLifecycle(
|
|
685
|
-
projectDirectoryUrl,
|
|
686
|
-
{
|
|
687
|
-
watchDescription,
|
|
688
|
-
updated: ({ relativeUrl }) => {
|
|
689
|
-
projectFileModified.notify(relativeUrl)
|
|
690
|
-
},
|
|
691
|
-
removed: ({ relativeUrl }) => {
|
|
692
|
-
projectFileRemoved.notify(relativeUrl)
|
|
693
|
-
},
|
|
694
|
-
added: ({ relativeUrl }) => {
|
|
695
|
-
projectFileAdded.notify(relativeUrl)
|
|
696
|
-
},
|
|
697
|
-
keepProcessAlive: false,
|
|
698
|
-
recursive: true,
|
|
699
|
-
},
|
|
700
|
-
)
|
|
701
|
-
serverStopCallbackList.add(unregisterDirectoryLifecyle)
|
|
702
|
-
}, 100)
|
|
703
|
-
serverStopCallbackList.add(() => {
|
|
704
|
-
clearTimeout(timeout)
|
|
705
|
-
})
|
|
706
|
-
|
|
707
|
-
const startTrackingRoot = (rootFile) => {
|
|
708
|
-
stopTrackingRoot(rootFile)
|
|
709
|
-
const set = new Set()
|
|
710
|
-
set.add(rootFile)
|
|
711
|
-
const depInfo = {
|
|
712
|
-
set,
|
|
713
|
-
cleanup: [],
|
|
714
|
-
}
|
|
715
|
-
trackerMap.set(rootFile, depInfo)
|
|
716
|
-
return depInfo
|
|
717
|
-
}
|
|
718
|
-
const addStopTrackingCalback = (rootFile, callback) => {
|
|
719
|
-
trackerMap.get(rootFile).cleanup.push(callback)
|
|
720
|
-
}
|
|
721
|
-
const stopTrackingRoot = (rootFile) => {
|
|
722
|
-
const depInfo = trackerMap.get(rootFile)
|
|
723
|
-
if (depInfo) {
|
|
724
|
-
depInfo.cleanup.forEach((cb) => {
|
|
725
|
-
cb()
|
|
726
|
-
})
|
|
727
|
-
trackerMap.delete(rootFile)
|
|
728
|
-
}
|
|
729
|
-
}
|
|
730
|
-
const isDependencyOf = (file, rootFile) => {
|
|
731
|
-
const depInfo = trackerMap.get(rootFile)
|
|
732
|
-
return depInfo && depInfo.set.has(file)
|
|
733
|
-
}
|
|
734
|
-
const markAsDependencyOf = (file, rootFile) => {
|
|
735
|
-
trackerMap.get(rootFile).set.add(file)
|
|
736
|
-
}
|
|
737
|
-
|
|
738
|
-
// each time a file is requested for the first time its dependencySet is computed
|
|
739
|
-
projectFileRequested.add((requestInfo) => {
|
|
740
|
-
const rootRelativeUrl = requestInfo.relativeUrl
|
|
741
|
-
// for now no use case of livereloading on node.js
|
|
742
|
-
// and for browsers only html file can be main files
|
|
743
|
-
// this avoid collecting dependencies of non html files that will never be used
|
|
744
|
-
if (!rootRelativeUrl.endsWith(".html")) {
|
|
745
|
-
return
|
|
746
|
-
}
|
|
747
|
-
|
|
748
|
-
livereloadLogger.debug(`${rootRelativeUrl} requested -> start tracking it`)
|
|
749
|
-
// when a file is requested, always rebuild its dependency in case it has changed
|
|
750
|
-
// since the last time it was requested
|
|
751
|
-
startTrackingRoot(rootRelativeUrl)
|
|
752
|
-
|
|
753
|
-
const removeDependencyRequestedCallback = projectFileRequested.add(
|
|
754
|
-
({ relativeUrl, request }) => {
|
|
755
|
-
if (isDependencyOf(relativeUrl, rootRelativeUrl)) {
|
|
756
|
-
return
|
|
757
|
-
}
|
|
758
|
-
const dependencyReport = reportDependency(
|
|
759
|
-
relativeUrl,
|
|
760
|
-
rootRelativeUrl,
|
|
761
|
-
request,
|
|
762
|
-
)
|
|
763
|
-
if (dependencyReport.dependency === false) {
|
|
764
|
-
livereloadLogger.debug(
|
|
765
|
-
`${relativeUrl} not a dependency of ${rootRelativeUrl} because ${dependencyReport.reason}`,
|
|
766
|
-
)
|
|
767
|
-
return
|
|
768
|
-
}
|
|
769
|
-
livereloadLogger.debug(
|
|
770
|
-
`${relativeUrl} is a dependency of ${rootRelativeUrl} because ${dependencyReport.reason}`,
|
|
771
|
-
)
|
|
772
|
-
markAsDependencyOf(relativeUrl, rootRelativeUrl)
|
|
773
|
-
},
|
|
774
|
-
)
|
|
775
|
-
addStopTrackingCalback(rootRelativeUrl, removeDependencyRequestedCallback)
|
|
776
|
-
const removeRootRemovedCallback = projectFileRemoved.add((relativeUrl) => {
|
|
777
|
-
if (relativeUrl === rootRelativeUrl) {
|
|
778
|
-
stopTrackingRoot(rootRelativeUrl)
|
|
779
|
-
livereloadLogger.debug(`${rootRelativeUrl} removed -> stop tracking it`)
|
|
780
|
-
}
|
|
781
|
-
})
|
|
782
|
-
addStopTrackingCalback(rootRelativeUrl, removeRootRemovedCallback)
|
|
783
|
-
})
|
|
784
|
-
|
|
785
|
-
const trackMainAndDependencies = (
|
|
786
|
-
mainRelativeUrl,
|
|
787
|
-
{ modified, removed, added },
|
|
788
|
-
) => {
|
|
789
|
-
livereloadLogger.debug(`track ${mainRelativeUrl} and its dependencies`)
|
|
790
|
-
|
|
791
|
-
const removeModifiedCallback = projectFileModified.add((relativeUrl) => {
|
|
792
|
-
if (isDependencyOf(relativeUrl, mainRelativeUrl)) {
|
|
793
|
-
modified(relativeUrl)
|
|
794
|
-
}
|
|
795
|
-
})
|
|
796
|
-
const removeRemovedCallback = projectFileRemoved.add((relativeUrl) => {
|
|
797
|
-
if (isDependencyOf(relativeUrl, mainRelativeUrl)) {
|
|
798
|
-
removed(relativeUrl)
|
|
799
|
-
}
|
|
800
|
-
})
|
|
801
|
-
const removeAddedCallback = projectFileAdded.add((relativeUrl) => {
|
|
802
|
-
if (isDependencyOf(relativeUrl, mainRelativeUrl)) {
|
|
803
|
-
added(relativeUrl)
|
|
804
|
-
}
|
|
805
|
-
})
|
|
806
|
-
|
|
807
|
-
return () => {
|
|
808
|
-
livereloadLogger.debug(
|
|
809
|
-
`stop tracking ${mainRelativeUrl} and its dependencies.`,
|
|
810
|
-
)
|
|
811
|
-
removeModifiedCallback()
|
|
812
|
-
removeRemovedCallback()
|
|
813
|
-
removeAddedCallback()
|
|
814
|
-
}
|
|
815
|
-
}
|
|
816
|
-
|
|
817
|
-
const reportDependency = (relativeUrl, mainRelativeUrl, request) => {
|
|
818
|
-
if (relativeUrl === mainRelativeUrl) {
|
|
819
|
-
return {
|
|
820
|
-
dependency: true,
|
|
821
|
-
reason: "it's main",
|
|
822
|
-
}
|
|
823
|
-
}
|
|
824
|
-
|
|
825
|
-
if ("x-jsenv-execution-id" in request.headers) {
|
|
826
|
-
const executionId = request.headers["x-jsenv-execution-id"]
|
|
827
|
-
if (executionId === mainRelativeUrl) {
|
|
828
|
-
return {
|
|
829
|
-
dependency: true,
|
|
830
|
-
reason: "x-jsenv-execution-id request header",
|
|
831
|
-
}
|
|
832
|
-
}
|
|
833
|
-
return {
|
|
834
|
-
dependency: false,
|
|
835
|
-
reason: "x-jsenv-execution-id request header",
|
|
836
|
-
}
|
|
837
|
-
}
|
|
838
|
-
|
|
839
|
-
const { referer } = request.headers
|
|
840
|
-
if (referer) {
|
|
841
|
-
// here we know the referer is inside compileServer
|
|
842
|
-
const refererRelativeUrl = urlToOriginalRelativeUrl(
|
|
843
|
-
referer,
|
|
844
|
-
resolveUrl(outDirectoryRelativeUrl, request.origin),
|
|
845
|
-
)
|
|
846
|
-
if (refererRelativeUrl) {
|
|
847
|
-
// search if referer (file requesting this one) is tracked as being a dependency of main file
|
|
848
|
-
// in that case because the importer is a dependency the importee is also a dependency
|
|
849
|
-
// eslint-disable-next-line no-unused-vars
|
|
850
|
-
for (const tracker of trackerMap) {
|
|
851
|
-
if (
|
|
852
|
-
tracker[0] === mainRelativeUrl &&
|
|
853
|
-
tracker[1].set.has(refererRelativeUrl)
|
|
854
|
-
) {
|
|
855
|
-
return {
|
|
856
|
-
dependency: true,
|
|
857
|
-
reason: "referer is a dependency",
|
|
858
|
-
}
|
|
859
|
-
}
|
|
860
|
-
}
|
|
861
|
-
}
|
|
862
|
-
}
|
|
863
|
-
|
|
864
|
-
return {
|
|
865
|
-
dependency: true,
|
|
866
|
-
reason: "it was requested",
|
|
867
|
-
}
|
|
868
|
-
}
|
|
869
|
-
|
|
870
|
-
return {
|
|
871
|
-
projectFileRequestedCallback,
|
|
872
|
-
trackMainAndDependencies,
|
|
873
|
-
}
|
|
874
|
-
}
|
|
875
|
-
|
|
876
|
-
const createSSEForLivereloadService = ({
|
|
877
|
-
serverStopCallbackList,
|
|
878
|
-
outDirectoryRelativeUrl,
|
|
879
|
-
trackMainAndDependencies,
|
|
880
|
-
}) => {
|
|
881
|
-
const cache = []
|
|
882
|
-
const sseRoomLimit = 100
|
|
883
|
-
const getOrCreateSSERoom = (mainFileRelativeUrl) => {
|
|
884
|
-
const cacheEntry = cache.find(
|
|
885
|
-
(cacheEntryCandidate) =>
|
|
886
|
-
cacheEntryCandidate.mainFileRelativeUrl === mainFileRelativeUrl,
|
|
887
|
-
)
|
|
888
|
-
if (cacheEntry) {
|
|
889
|
-
return cacheEntry.sseRoom
|
|
890
|
-
}
|
|
891
|
-
|
|
892
|
-
const sseRoom = createSSERoom({
|
|
893
|
-
retryDuration: 2000,
|
|
894
|
-
historyLength: 100,
|
|
895
|
-
welcomeEventEnabled: true,
|
|
896
|
-
})
|
|
897
|
-
|
|
898
|
-
// each time something is modified or removed we send event to the room
|
|
899
|
-
const stopTracking = trackMainAndDependencies(mainFileRelativeUrl, {
|
|
900
|
-
modified: (relativeUrl) => {
|
|
901
|
-
sseRoom.sendEvent({ type: "file-modified", data: relativeUrl })
|
|
902
|
-
},
|
|
903
|
-
removed: (relativeUrl) => {
|
|
904
|
-
sseRoom.sendEvent({ type: "file-removed", data: relativeUrl })
|
|
905
|
-
},
|
|
906
|
-
added: (relativeUrl) => {
|
|
907
|
-
sseRoom.sendEvent({ type: "file-added", data: relativeUrl })
|
|
908
|
-
},
|
|
909
|
-
})
|
|
910
|
-
|
|
911
|
-
const removeSSECleanupCallback = serverStopCallbackList.add(() => {
|
|
912
|
-
removeSSECleanupCallback()
|
|
913
|
-
sseRoom.close()
|
|
914
|
-
stopTracking()
|
|
915
|
-
})
|
|
916
|
-
cache.push({
|
|
917
|
-
mainFileRelativeUrl,
|
|
918
|
-
sseRoom,
|
|
919
|
-
cleanup: () => {
|
|
920
|
-
removeSSECleanupCallback()
|
|
921
|
-
sseRoom.close()
|
|
922
|
-
stopTracking()
|
|
923
|
-
},
|
|
924
|
-
})
|
|
925
|
-
if (cache.length >= sseRoomLimit) {
|
|
926
|
-
const firstCacheEntry = cache.shift()
|
|
927
|
-
firstCacheEntry.cleanup()
|
|
928
|
-
}
|
|
929
|
-
return sseRoom
|
|
930
|
-
}
|
|
931
|
-
|
|
932
|
-
return (request) => {
|
|
933
|
-
const { accept } = request.headers
|
|
934
|
-
if (!accept || !accept.includes("text/event-stream")) {
|
|
935
|
-
return null
|
|
936
|
-
}
|
|
937
|
-
|
|
938
|
-
const fileRelativeUrl = urlToOriginalRelativeUrl(
|
|
939
|
-
resolveUrl(request.ressource, request.origin),
|
|
940
|
-
resolveUrl(outDirectoryRelativeUrl, request.origin),
|
|
941
|
-
)
|
|
942
|
-
|
|
943
|
-
const room = getOrCreateSSERoom(fileRelativeUrl)
|
|
944
|
-
return room.join(request)
|
|
945
|
-
}
|
|
946
|
-
}
|
|
947
|
-
|
|
948
|
-
const urlToOriginalRelativeUrl = (url, outDirectoryRemoteUrl) => {
|
|
949
|
-
if (urlIsInsideOf(url, outDirectoryRemoteUrl)) {
|
|
950
|
-
const afterCompileDirectory = urlToRelativeUrl(url, outDirectoryRemoteUrl)
|
|
951
|
-
const fileRelativeUrl = afterCompileDirectory.slice(
|
|
952
|
-
afterCompileDirectory.indexOf("/") + 1,
|
|
953
|
-
)
|
|
954
|
-
return fileRelativeUrl
|
|
955
|
-
}
|
|
956
|
-
return new URL(url).pathname.slice(1)
|
|
459
|
+
jsenvDirectoryRelativeUrl = urlToRelativeUrl(
|
|
460
|
+
jsenvDirectoryUrl,
|
|
461
|
+
projectDirectoryUrl,
|
|
462
|
+
)
|
|
463
|
+
return jsenvDirectoryRelativeUrl
|
|
957
464
|
}
|
|
958
465
|
|
|
959
466
|
const createCompilationAssetFileService = ({ projectDirectoryUrl }) => {
|
|
@@ -1019,161 +526,6 @@ const createSourceFileService = ({
|
|
|
1019
526
|
}
|
|
1020
527
|
}
|
|
1021
528
|
|
|
1022
|
-
const createCompileServerMetaFileInfo = ({
|
|
1023
|
-
projectDirectoryUrl,
|
|
1024
|
-
jsenvDirectoryRelativeUrl,
|
|
1025
|
-
outDirectoryRelativeUrl,
|
|
1026
|
-
importDefaultExtension,
|
|
1027
|
-
|
|
1028
|
-
preservedUrls,
|
|
1029
|
-
workers,
|
|
1030
|
-
serviceWorkers,
|
|
1031
|
-
compileServerGroupMap,
|
|
1032
|
-
babelPluginMap,
|
|
1033
|
-
replaceProcessEnvNodeEnv,
|
|
1034
|
-
processEnvNodeEnv,
|
|
1035
|
-
env,
|
|
1036
|
-
inlineImportMapIntoHTML,
|
|
1037
|
-
customCompilers,
|
|
1038
|
-
jsenvToolbarInjection,
|
|
1039
|
-
sourcemapMethod,
|
|
1040
|
-
sourcemapExcludeSources,
|
|
1041
|
-
}) => {
|
|
1042
|
-
const outDirectoryUrl = resolveUrl(
|
|
1043
|
-
outDirectoryRelativeUrl,
|
|
1044
|
-
projectDirectoryUrl,
|
|
1045
|
-
)
|
|
1046
|
-
const compileServerMetaFileUrl = resolveUrl(
|
|
1047
|
-
"./__compile_server_meta__.json",
|
|
1048
|
-
outDirectoryUrl,
|
|
1049
|
-
)
|
|
1050
|
-
const jsenvCorePackageFileUrl = resolveUrl(
|
|
1051
|
-
"./package.json",
|
|
1052
|
-
jsenvCoreDirectoryUrl,
|
|
1053
|
-
)
|
|
1054
|
-
const jsenvCorePackageFilePath = urlToFileSystemPath(jsenvCorePackageFileUrl)
|
|
1055
|
-
const jsenvCorePackageVersion = readPackage(jsenvCorePackageFilePath).version
|
|
1056
|
-
const customCompilerPatterns = Object.keys(customCompilers)
|
|
1057
|
-
const sourcemapMainFileRelativeUrl = urlToRelativeUrl(
|
|
1058
|
-
sourcemapMainFileInfo.url,
|
|
1059
|
-
projectDirectoryUrl,
|
|
1060
|
-
)
|
|
1061
|
-
const sourcemapMappingFileRelativeUrl = urlToRelativeUrl(
|
|
1062
|
-
sourcemapMappingFileInfo.url,
|
|
1063
|
-
projectDirectoryUrl,
|
|
1064
|
-
)
|
|
1065
|
-
// The object below must list everything that can influence how the
|
|
1066
|
-
// compiled files are generated. So that the cahce for those generated files is
|
|
1067
|
-
// not reused when it should not
|
|
1068
|
-
// In some cases the parameters influences only a subset of files and ideally
|
|
1069
|
-
// this parameter should somehow invalidate a subset of the cache
|
|
1070
|
-
// To keep things simple these parameters currently invalidates the whole cache
|
|
1071
|
-
const compileServerMeta = {
|
|
1072
|
-
jsenvDirectoryRelativeUrl,
|
|
1073
|
-
outDirectoryRelativeUrl,
|
|
1074
|
-
importDefaultExtension,
|
|
1075
|
-
|
|
1076
|
-
preservedUrls,
|
|
1077
|
-
workers,
|
|
1078
|
-
serviceWorkers,
|
|
1079
|
-
babelPluginMap: babelPluginMapAsData(babelPluginMap),
|
|
1080
|
-
compileServerGroupMap,
|
|
1081
|
-
customCompilerPatterns,
|
|
1082
|
-
replaceProcessEnvNodeEnv,
|
|
1083
|
-
processEnvNodeEnv,
|
|
1084
|
-
inlineImportMapIntoHTML,
|
|
1085
|
-
|
|
1086
|
-
sourcemapMethod,
|
|
1087
|
-
sourcemapExcludeSources,
|
|
1088
|
-
sourcemapMainFileRelativeUrl,
|
|
1089
|
-
sourcemapMappingFileRelativeUrl,
|
|
1090
|
-
errorStackRemapping: true,
|
|
1091
|
-
|
|
1092
|
-
// used to consider logic generating files may have changed
|
|
1093
|
-
jsenvCorePackageVersion,
|
|
1094
|
-
|
|
1095
|
-
// impact only HTML files
|
|
1096
|
-
jsenvToolbarInjection,
|
|
1097
|
-
TOOLBAR_INJECTOR_BUILD_URL,
|
|
1098
|
-
EVENT_SOURCE_CLIENT_BUILD_URL,
|
|
1099
|
-
BROWSER_RUNTIME_BUILD_URL,
|
|
1100
|
-
|
|
1101
|
-
env,
|
|
1102
|
-
}
|
|
1103
|
-
return {
|
|
1104
|
-
url: compileServerMetaFileUrl,
|
|
1105
|
-
data: compileServerMeta,
|
|
1106
|
-
}
|
|
1107
|
-
}
|
|
1108
|
-
|
|
1109
|
-
const babelPluginMapAsData = (babelPluginMap) => {
|
|
1110
|
-
const data = {}
|
|
1111
|
-
Object.keys(babelPluginMap).forEach((key) => {
|
|
1112
|
-
const value = babelPluginMap[key]
|
|
1113
|
-
if (Array.isArray(value)) {
|
|
1114
|
-
data[key] = value
|
|
1115
|
-
return
|
|
1116
|
-
}
|
|
1117
|
-
if (typeof value === "object") {
|
|
1118
|
-
data[key] = {
|
|
1119
|
-
options: value.options,
|
|
1120
|
-
}
|
|
1121
|
-
return
|
|
1122
|
-
}
|
|
1123
|
-
data[key] = value
|
|
1124
|
-
})
|
|
1125
|
-
return data
|
|
1126
|
-
}
|
|
1127
|
-
|
|
1128
|
-
const createCompileServerMetaService = ({
|
|
1129
|
-
projectDirectoryUrl,
|
|
1130
|
-
outDirectoryUrl,
|
|
1131
|
-
compileServerMetaFileInfo,
|
|
1132
|
-
}) => {
|
|
1133
|
-
const isCompileServerMetaFile = (url) => {
|
|
1134
|
-
if (!urlIsInsideOf(url, outDirectoryUrl)) {
|
|
1135
|
-
return false
|
|
1136
|
-
}
|
|
1137
|
-
const afterOutDirectory = url.slice(outDirectoryUrl.length)
|
|
1138
|
-
if (afterOutDirectory.indexOf("/") > -1) {
|
|
1139
|
-
return false
|
|
1140
|
-
}
|
|
1141
|
-
return true
|
|
1142
|
-
}
|
|
1143
|
-
|
|
1144
|
-
// serve from memory
|
|
1145
|
-
return (request) => {
|
|
1146
|
-
const requestUrl = resolveUrl(
|
|
1147
|
-
request.ressource.slice(1),
|
|
1148
|
-
projectDirectoryUrl,
|
|
1149
|
-
)
|
|
1150
|
-
if (
|
|
1151
|
-
isCompileServerMetaFile(requestUrl) ||
|
|
1152
|
-
// allow to request it directly from .jsenv
|
|
1153
|
-
request.ressource === "/.jsenv/__compile_server_meta__.json"
|
|
1154
|
-
) {
|
|
1155
|
-
const body = JSON.stringify(compileServerMetaFileInfo.data, null, " ")
|
|
1156
|
-
return {
|
|
1157
|
-
status: 200,
|
|
1158
|
-
headers: {
|
|
1159
|
-
"content-type": urlToContentType(requestUrl),
|
|
1160
|
-
"content-length": Buffer.byteLength(body),
|
|
1161
|
-
},
|
|
1162
|
-
body,
|
|
1163
|
-
}
|
|
1164
|
-
}
|
|
1165
|
-
|
|
1166
|
-
return null
|
|
1167
|
-
}
|
|
1168
|
-
}
|
|
1169
|
-
|
|
1170
|
-
const readPackage = (packagePath) => {
|
|
1171
|
-
const buffer = readFileSync(packagePath)
|
|
1172
|
-
const string = String(buffer)
|
|
1173
|
-
const packageObject = JSON.parse(string)
|
|
1174
|
-
return packageObject
|
|
1175
|
-
}
|
|
1176
|
-
|
|
1177
529
|
const __filenameReplacement = `import.meta.url.slice('file:///'.length)`
|
|
1178
530
|
|
|
1179
531
|
const __dirnameReplacement = `import.meta.url.slice('file:///'.length).replace(/[\\\/\\\\][^\\\/\\\\]*$/, '')`
|