@jsenv/core 22.5.1 → 23.0.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/jsenv_browser_system.js +203 -49
- package/dist/jsenv_browser_system.js.map +39 -8
- package/dist/jsenv_compile_proxy.js +186 -108
- package/dist/jsenv_compile_proxy.js.map +48 -42
- package/dist/jsenv_exploring_redirector.js +148 -71
- package/dist/jsenv_exploring_redirector.js.map +26 -20
- package/dist/jsenv_toolbar.js +215 -104
- package/dist/jsenv_toolbar.js.map +39 -26
- package/helpers/new_stylesheet/new_stylesheet.js +411 -0
- package/{LICENSE → license} +0 -0
- package/main.js +7 -7
- package/package.json +23 -19
- package/readme.md +5 -4
- package/src/execute.js +23 -10
- package/src/executeTestPlan.js +0 -4
- package/src/importUsingChildProcess.js +36 -32
- package/src/internal/{babel-plugin-replace-expressions.js → babel_plugin_replace_expressions.js} +0 -0
- package/src/internal/{babel-plugin-transform-import-meta.js → babel_plugin_transform_import_meta.js} +0 -0
- package/src/internal/browser-launcher/executeHtmlFile.js +6 -8
- package/src/internal/browser-launcher/jsenv-browser-system.js +3 -0
- package/src/internal/building/asset_url_versioning.js +5 -9
- package/src/internal/building/buildServiceWorker.js +6 -13
- package/src/internal/building/buildUsingRollup.js +34 -0
- package/src/internal/building/build_logs.js +11 -0
- package/src/internal/building/build_stats.js +7 -1
- package/src/internal/building/createJsenvRollupPlugin.js +380 -297
- package/src/internal/building/css/parseCssRessource.js +67 -71
- package/src/internal/building/css/parseCssUrls.js +2 -2
- package/src/internal/building/css/{postcss-urlhash-plugin.js → postcss_plugin_url_visitor.js} +43 -21
- package/src/internal/building/css/replaceCssUrls.js +17 -14
- package/src/internal/building/css_module.js +47 -0
- package/src/internal/building/html/parseHtmlRessource.js +44 -43
- package/src/internal/building/import_references.js +81 -0
- package/src/internal/building/importmap/parseImportmapRessource.js +5 -2
- package/src/internal/building/js/minifyJs.js +30 -3
- package/src/internal/building/js/parseJsRessource.js +70 -77
- package/src/internal/building/json/parseJsonRessource.js +3 -2
- package/src/internal/building/parseRessource.js +11 -8
- package/src/internal/building/parsing.utils.js +4 -15
- package/src/internal/building/ressource_builder.js +142 -114
- package/src/internal/building/ressource_builder_util.js +31 -18
- package/src/internal/building/{fetchSourcemap.js → sourcemap_loader.js} +29 -27
- package/src/internal/building/svg/parseSvgRessource.js +7 -3
- package/src/internal/building/url-versioning.js +2 -1
- package/src/internal/building/url_fetcher.js +79 -0
- package/src/internal/building/url_loader.js +267 -0
- package/src/internal/building/webmanifest/parseWebmanifestRessource.js +9 -4
- package/src/internal/compiling/{js-compilation-service/ensureGlobalThisImportBabelPlugin.js → babel_plugin_global_this_as_jsenv_import.js} +4 -2
- package/src/internal/compiling/babel_plugin_import_assertions.js +100 -0
- package/src/internal/compiling/babel_plugin_new_stylesheet_as_jsenv_import.js +109 -0
- package/src/internal/compiling/babel_plugin_transform_import_specifier.js +86 -0
- package/src/internal/compiling/babel_plugins.js +2 -0
- package/src/internal/compiling/createCompiledFileService.js +6 -8
- package/src/internal/compiling/html_source_file_service.js +2 -2
- package/src/internal/compiling/js-compilation-service/{transformBabelHelperToImportBabelPlugin.js → babel_plugin_babel_helpers_as_jsenv_imports.js} +1 -1
- package/src/internal/compiling/js-compilation-service/{ensureRegeneratorRuntimeImportBabelPlugin.js → babel_plugin_regenerator_runtime_as_jsenv_import.js} +1 -1
- package/src/internal/compiling/js-compilation-service/jsenvTransform.js +7 -16
- package/src/internal/compiling/js-compilation-service/transformJs.js +0 -2
- package/src/internal/compiling/rollup_plugin_commonjs_named_exports.js +2 -2
- package/src/internal/compiling/startCompileServer.js +11 -4
- package/src/internal/escapeTemplateStringSpecialCharacters.js +20 -0
- package/src/internal/executing/coverage/{babel-plugin-instrument.js → babel_plugin_instrument.js} +17 -6
- package/src/internal/executing/coverage/relativeUrlToEmptyCoverage.js +1 -1
- package/src/internal/executing/executeConcurrently.js +2 -2
- package/src/internal/executing/executePlan.js +16 -2
- package/src/internal/executing/generateFileExecutionSteps.js +2 -1
- package/src/internal/executing/launchAndExecute.js +43 -69
- package/src/internal/exploring/exploring.css +2 -1
- package/src/internal/exploring/exploring.redirector.js +0 -1
- package/src/internal/generateGroupMap/generateGroupMap.js +14 -10
- package/src/internal/generateGroupMap/jsenvBabelPluginCompatMap.js +30 -0
- package/src/internal/generateGroupMap/jsenvPluginCompatMap.js +0 -6
- package/src/internal/generateGroupMap/one_runtime_compat.js +9 -38
- package/src/internal/generateGroupMap/runtime_compat.js +9 -24
- package/src/internal/generateGroupMap/runtime_compat_composition.js +2 -12
- package/src/internal/generateGroupMap/runtime_support.js +53 -0
- package/src/internal/jsenvInternalFiles.js +0 -1
- package/src/internal/node-launcher/createControllableNodeProcess.js +2 -3
- package/src/internal/response_validation.js +143 -0
- package/src/internal/runtime/createBrowserRuntime/createBrowserRuntime.js +8 -3
- package/src/internal/runtime/createBrowserRuntime/createBrowserSystem.js +117 -0
- package/src/internal/runtime/createBrowserRuntime/displayErrorInDocument.js +1 -1
- package/src/internal/runtime/createBrowserRuntime/scanBrowserRuntimeFeatures.js +124 -68
- package/src/internal/runtime/createNodeRuntime/createNodeRuntime.js +8 -86
- package/src/internal/runtime/createNodeRuntime/scanNodeRuntimeFeatures.js +115 -0
- package/src/internal/runtime/module-registration.js +1 -2
- package/src/internal/runtime/resolveGroup.js +2 -3
- package/src/internal/toolbar/compilation/toolbar.compilation.js +15 -17
- package/src/internal/toolbar/eventsource/toolbar.eventsource.js +35 -8
- package/src/internal/toolbar/toolbar.main.js +7 -4
- package/src/internal/url_utils.js +20 -0
- package/src/launchBrowser.js +47 -34
- package/src/launchNode.js +6 -3
- package/src/requireUsingChildProcess.js +36 -32
- package/src/startExploring.js +23 -11
- package/src/internal/building/transformImportMetaUrlReferences.js +0 -71
- package/src/internal/runtime/resolveBrowserGroup.js +0 -5
- package/src/internal/runtime/resolveNodeGroup.js +0 -5
- package/src/internal/validateResponseStatusIsOk.js +0 -91
|
@@ -1,8 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { nodeSupportsTopLevelAwait } from "../node-feature-detect/nodeSupportsTopLevelAwait.js"
|
|
3
|
-
import { computeCompileIdFromGroupId } from "../computeCompileIdFromGroupId.js"
|
|
4
|
-
import { resolveNodeGroup } from "../resolveNodeGroup.js"
|
|
5
|
-
import { fetchSource } from "./fetchSource.js"
|
|
1
|
+
import { scanNodeRuntimeFeatures } from "./scanNodeRuntimeFeatures.js"
|
|
6
2
|
import { createNodeExecutionWithSystemJs } from "./createNodeExecutionWithSystemJs.js"
|
|
7
3
|
import { createNodeExecutionWithDynamicImport } from "./createNodeExecutionWithDynamicImport.js"
|
|
8
4
|
|
|
@@ -10,33 +6,16 @@ export const createNodeRuntime = async ({
|
|
|
10
6
|
projectDirectoryUrl,
|
|
11
7
|
compileServerOrigin,
|
|
12
8
|
outDirectoryRelativeUrl,
|
|
13
|
-
canUseNativeModuleSystem,
|
|
9
|
+
canUseNativeModuleSystem = true,
|
|
14
10
|
}) => {
|
|
15
|
-
const
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
)
|
|
19
|
-
const envFileServerUrl = String(new URL("env.json", outDirectoryServerUrl))
|
|
20
|
-
const [groupMap, envJson] = await Promise.all([
|
|
21
|
-
importJson(groupMapServerUrl),
|
|
22
|
-
importJson(envFileServerUrl),
|
|
23
|
-
])
|
|
24
|
-
|
|
25
|
-
const { importDefaultExtension } = envJson
|
|
26
|
-
|
|
27
|
-
const compileId = computeCompileIdFromGroupId({
|
|
28
|
-
groupId: resolveNodeGroup(groupMap),
|
|
29
|
-
groupMap,
|
|
11
|
+
const nodeFeatures = await scanNodeRuntimeFeatures({
|
|
12
|
+
compileServerOrigin,
|
|
13
|
+
outDirectoryRelativeUrl,
|
|
30
14
|
})
|
|
31
|
-
const
|
|
32
|
-
|
|
33
|
-
canUseNativeModuleSystem = await nodeRuntimeSupportsAllFeatures({
|
|
34
|
-
groupInfo,
|
|
35
|
-
importDefaultExtension,
|
|
36
|
-
})
|
|
37
|
-
}
|
|
15
|
+
const { canAvoidCompilation, compileId, importDefaultExtension } =
|
|
16
|
+
nodeFeatures
|
|
38
17
|
|
|
39
|
-
if (canUseNativeModuleSystem) {
|
|
18
|
+
if (canAvoidCompilation && canUseNativeModuleSystem) {
|
|
40
19
|
return createNodeExecutionWithDynamicImport({
|
|
41
20
|
projectDirectoryUrl,
|
|
42
21
|
compileServerOrigin,
|
|
@@ -51,60 +30,3 @@ export const createNodeRuntime = async ({
|
|
|
51
30
|
importDefaultExtension,
|
|
52
31
|
})
|
|
53
32
|
}
|
|
54
|
-
|
|
55
|
-
const importJson = async (url) => {
|
|
56
|
-
const response = await fetchSource(url)
|
|
57
|
-
const status = response.status
|
|
58
|
-
if (status !== 200) {
|
|
59
|
-
throw new Error(`unexpected response status for ${url}, got ${status}`)
|
|
60
|
-
}
|
|
61
|
-
const object = await response.json()
|
|
62
|
-
return object
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
const nodeRuntimeSupportsAllFeatures = async ({
|
|
66
|
-
groupInfo,
|
|
67
|
-
importDefaultExtension,
|
|
68
|
-
}) => {
|
|
69
|
-
// node native resolution will not auto add extension
|
|
70
|
-
if (importDefaultExtension) {
|
|
71
|
-
return false
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
const requiredBabelPluginCount = countRequiredBabelPlugins(groupInfo)
|
|
75
|
-
if (requiredBabelPluginCount > 0) {
|
|
76
|
-
return false
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
if (groupInfo.jsenvPluginRequiredNameArray.length > 0) {
|
|
80
|
-
return false
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
const hasDynamicImport = await nodeSupportsDynamicImport()
|
|
84
|
-
if (!hasDynamicImport) {
|
|
85
|
-
return false
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
const hasTopLevelAwait = await nodeSupportsTopLevelAwait()
|
|
89
|
-
if (!hasTopLevelAwait) {
|
|
90
|
-
return false
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
return true
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
const countRequiredBabelPlugins = (groupInfo) => {
|
|
97
|
-
const { babelPluginRequiredNameArray } = groupInfo
|
|
98
|
-
let count = babelPluginRequiredNameArray.length
|
|
99
|
-
|
|
100
|
-
// https://nodejs.org/docs/latest-v15.x/api/cli.html#cli_node_v8_coverage_dir
|
|
101
|
-
// instrumentation CAN be handed by process.env.NODE_V8_COVERAGE
|
|
102
|
-
// "transform-instrument" becomes non mandatory
|
|
103
|
-
const transformInstrumentIndex = babelPluginRequiredNameArray.indexOf(
|
|
104
|
-
"transform-instrument",
|
|
105
|
-
)
|
|
106
|
-
if (transformInstrumentIndex > -1 && process.env.NODE_V8_COVERAGE) {
|
|
107
|
-
count--
|
|
108
|
-
}
|
|
109
|
-
return count
|
|
110
|
-
}
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import { detectNode } from "../detectNode/detectNode.js"
|
|
2
|
+
import { resolveGroup } from "../resolveGroup.js"
|
|
3
|
+
import { computeCompileIdFromGroupId } from "../computeCompileIdFromGroupId.js"
|
|
4
|
+
import { nodeSupportsDynamicImport } from "../node-feature-detect/nodeSupportsDynamicImport.js"
|
|
5
|
+
import { nodeSupportsTopLevelAwait } from "../node-feature-detect/nodeSupportsTopLevelAwait.js"
|
|
6
|
+
import { fetchSource } from "./fetchSource.js"
|
|
7
|
+
|
|
8
|
+
export const scanNodeRuntimeFeatures = async ({
|
|
9
|
+
compileServerOrigin,
|
|
10
|
+
outDirectoryRelativeUrl,
|
|
11
|
+
}) => {
|
|
12
|
+
const outDirectoryServerUrl = `${compileServerOrigin}/${outDirectoryRelativeUrl}`
|
|
13
|
+
const groupMapServerUrl = String(
|
|
14
|
+
new URL("groupMap.json", outDirectoryServerUrl),
|
|
15
|
+
)
|
|
16
|
+
const envFileServerUrl = String(new URL("env.json", outDirectoryServerUrl))
|
|
17
|
+
const [groupMap, envJson] = await Promise.all([
|
|
18
|
+
importJson(groupMapServerUrl),
|
|
19
|
+
importJson(envFileServerUrl),
|
|
20
|
+
])
|
|
21
|
+
|
|
22
|
+
const { importDefaultExtension, customCompilerPatterns } = envJson
|
|
23
|
+
|
|
24
|
+
const node = detectNode()
|
|
25
|
+
const compileId = computeCompileIdFromGroupId({
|
|
26
|
+
groupId: resolveGroup(node, groupMap),
|
|
27
|
+
groupMap,
|
|
28
|
+
})
|
|
29
|
+
const groupInfo = groupMap[compileId]
|
|
30
|
+
|
|
31
|
+
const featuresReport = {
|
|
32
|
+
dynamicImport: undefined,
|
|
33
|
+
topLevelAwait: undefined,
|
|
34
|
+
}
|
|
35
|
+
await detectSupportedFeatures({
|
|
36
|
+
featuresReport,
|
|
37
|
+
failFastOnFeatureDetection: true,
|
|
38
|
+
})
|
|
39
|
+
const pluginRequiredNameArray = pluginRequiredNamesFromGroupInfo(groupInfo, {
|
|
40
|
+
featuresReport,
|
|
41
|
+
// https://nodejs.org/docs/latest-v15.x/api/cli.html#cli_node_v8_coverage_dir
|
|
42
|
+
// instrumentation CAN be handed by process.env.NODE_V8_COVERAGE
|
|
43
|
+
// "transform-instrument" becomes non mandatory
|
|
44
|
+
coverageHandledFromOutside: process.env.NODE_V8_COVERAGE,
|
|
45
|
+
})
|
|
46
|
+
|
|
47
|
+
const canAvoidCompilation =
|
|
48
|
+
// node native resolution will not auto add extension
|
|
49
|
+
!importDefaultExtension &&
|
|
50
|
+
customCompilerPatterns.length === 0 &&
|
|
51
|
+
pluginRequiredNameArray.length === 0 &&
|
|
52
|
+
featuresReport.dynamicImport &&
|
|
53
|
+
featuresReport.topLevelAwait
|
|
54
|
+
|
|
55
|
+
return {
|
|
56
|
+
canAvoidCompilation,
|
|
57
|
+
featuresReport,
|
|
58
|
+
pluginRequiredNameArray,
|
|
59
|
+
compileId,
|
|
60
|
+
importDefaultExtension,
|
|
61
|
+
node,
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
const detectSupportedFeatures = async ({
|
|
66
|
+
featuresReport,
|
|
67
|
+
failFastOnFeatureDetection,
|
|
68
|
+
}) => {
|
|
69
|
+
const dynamicImport = await nodeSupportsDynamicImport()
|
|
70
|
+
featuresReport.dynamicImport = dynamicImport
|
|
71
|
+
if (failFastOnFeatureDetection && !dynamicImport) {
|
|
72
|
+
return
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
const topLevelAwait = await nodeSupportsTopLevelAwait()
|
|
76
|
+
featuresReport.topLevelAwait = topLevelAwait
|
|
77
|
+
if (failFastOnFeatureDetection && !topLevelAwait) {
|
|
78
|
+
return
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
const importJson = async (url) => {
|
|
83
|
+
const response = await fetchSource(url)
|
|
84
|
+
const status = response.status
|
|
85
|
+
if (status !== 200) {
|
|
86
|
+
throw new Error(`unexpected response status for ${url}, got ${status}`)
|
|
87
|
+
}
|
|
88
|
+
const object = await response.json()
|
|
89
|
+
return object
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
const pluginRequiredNamesFromGroupInfo = (
|
|
93
|
+
groupInfo,
|
|
94
|
+
{ coverageHandledFromOutside },
|
|
95
|
+
) => {
|
|
96
|
+
const { pluginRequiredNameArray } = groupInfo
|
|
97
|
+
const requiredPluginNames = pluginRequiredNameArray.slice()
|
|
98
|
+
const markPluginAsSupported = (name) => {
|
|
99
|
+
const index = requiredPluginNames.indexOf(name)
|
|
100
|
+
if (index > -1) {
|
|
101
|
+
requiredPluginNames.splice(index, 1)
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
if (coverageHandledFromOutside) {
|
|
106
|
+
markPluginAsSupported("transform-instrument")
|
|
107
|
+
}
|
|
108
|
+
// We assume import assertions and constructable stylesheet won't be used
|
|
109
|
+
// in code executed in Node.js
|
|
110
|
+
// so event they are conceptually required, they are ignored
|
|
111
|
+
markPluginAsSupported("transform-import-assertions")
|
|
112
|
+
markPluginAsSupported("new-stylesheet-as-jsenv-import")
|
|
113
|
+
|
|
114
|
+
return requiredPluginNames
|
|
115
|
+
}
|
|
@@ -108,8 +108,7 @@ export const getJavaScriptModuleResponseError = async (
|
|
|
108
108
|
compileServerOrigin,
|
|
109
109
|
compileDirectoryRelativeUrl,
|
|
110
110
|
}),
|
|
111
|
-
|
|
112
|
-
"suggestion 2": `Use customCompilers to convert non-js to js`,
|
|
111
|
+
suggestion: `Use import.meta.url or import assertions as documented in https://github.com/jsenv/jsenv-core/blob/master/docs/building/readme.md#How-to-reference-assets`,
|
|
113
112
|
},
|
|
114
113
|
),
|
|
115
114
|
)
|
|
@@ -3,11 +3,10 @@ import { findHighestVersion } from "../semantic-versioning/index.js"
|
|
|
3
3
|
export const resolveGroup = ({ name, version }, groupMap) => {
|
|
4
4
|
return Object.keys(groupMap).find((compileIdCandidate) => {
|
|
5
5
|
const { minRuntimeVersions } = groupMap[compileIdCandidate]
|
|
6
|
-
|
|
6
|
+
const versionForGroup = minRuntimeVersions[name]
|
|
7
|
+
if (!versionForGroup) {
|
|
7
8
|
return false
|
|
8
9
|
}
|
|
9
|
-
const versionForGroup = minRuntimeVersions[name]
|
|
10
|
-
|
|
11
10
|
const highestVersion = findHighestVersion(version, versionForGroup)
|
|
12
11
|
return highestVersion === version
|
|
13
12
|
})
|
|
@@ -11,8 +11,10 @@ export const renderCompilationInToolbar = ({ compileGroup }) => {
|
|
|
11
11
|
|
|
12
12
|
scanBrowserRuntimeFeatures().then(
|
|
13
13
|
({
|
|
14
|
-
featuresReport,
|
|
15
14
|
canAvoidCompilation,
|
|
15
|
+
featuresReport,
|
|
16
|
+
customCompilerPatterns,
|
|
17
|
+
pluginRequiredNameArray,
|
|
16
18
|
inlineImportMapIntoHTML,
|
|
17
19
|
outDirectoryRelativeUrl,
|
|
18
20
|
compileId,
|
|
@@ -35,6 +37,8 @@ export const renderCompilationInToolbar = ({ compileGroup }) => {
|
|
|
35
37
|
{
|
|
36
38
|
missingOnly: true,
|
|
37
39
|
featuresReport,
|
|
40
|
+
customCompilerPatterns,
|
|
41
|
+
pluginRequiredNameArray,
|
|
38
42
|
inlineImportMapIntoHTML,
|
|
39
43
|
},
|
|
40
44
|
)}`,
|
|
@@ -49,6 +53,8 @@ export const renderCompilationInToolbar = ({ compileGroup }) => {
|
|
|
49
53
|
`Source files (except html) can be executed directly in this browser because: ${getBrowserSupportMessage(
|
|
50
54
|
{
|
|
51
55
|
featuresReport,
|
|
56
|
+
customCompilerPatterns,
|
|
57
|
+
pluginRequiredNameArray,
|
|
52
58
|
inlineImportMapIntoHTML,
|
|
53
59
|
},
|
|
54
60
|
)}`,
|
|
@@ -63,6 +69,8 @@ export const renderCompilationInToolbar = ({ compileGroup }) => {
|
|
|
63
69
|
`Source files can be executed directly in this browser because: ${getBrowserSupportMessage(
|
|
64
70
|
{
|
|
65
71
|
featuresReport,
|
|
72
|
+
customCompilerPatterns,
|
|
73
|
+
pluginRequiredNameArray,
|
|
66
74
|
inlineImportMapIntoHTML,
|
|
67
75
|
},
|
|
68
76
|
)}`,
|
|
@@ -119,6 +127,8 @@ export const renderCompilationInToolbar = ({ compileGroup }) => {
|
|
|
119
127
|
const getBrowserSupportMessage = ({
|
|
120
128
|
missingOnly,
|
|
121
129
|
featuresReport,
|
|
130
|
+
customCompilerPatterns,
|
|
131
|
+
pluginRequiredNameArray,
|
|
122
132
|
inlineImportMapIntoHTML,
|
|
123
133
|
}) => {
|
|
124
134
|
const parts = []
|
|
@@ -154,19 +164,17 @@ const getBrowserSupportMessage = ({
|
|
|
154
164
|
parts.push(`top level await is not supported`)
|
|
155
165
|
}
|
|
156
166
|
|
|
157
|
-
const
|
|
158
|
-
|
|
159
|
-
if (babelPluginRequiredCount === 0) {
|
|
167
|
+
const pluginRequiredCount = pluginRequiredNameArray.length
|
|
168
|
+
if (pluginRequiredCount === 0) {
|
|
160
169
|
if (!missingOnly) {
|
|
161
|
-
parts.push(`all
|
|
170
|
+
parts.push(`all plugins are natively supported`)
|
|
162
171
|
}
|
|
163
172
|
} else {
|
|
164
173
|
parts.push(
|
|
165
|
-
`${
|
|
174
|
+
`${pluginRequiredCount} plugins are mandatory: ${pluginRequiredNameArray}`,
|
|
166
175
|
)
|
|
167
176
|
}
|
|
168
177
|
|
|
169
|
-
const { customCompilerPatterns } = featuresReport
|
|
170
178
|
const customCompilerCount = customCompilerPatterns.length
|
|
171
179
|
if (customCompilerCount === 0) {
|
|
172
180
|
// no need to talk about something unused
|
|
@@ -176,16 +184,6 @@ const getBrowserSupportMessage = ({
|
|
|
176
184
|
)
|
|
177
185
|
}
|
|
178
186
|
|
|
179
|
-
const { jsenvPluginRequiredNames } = featuresReport
|
|
180
|
-
const jsenvPluginRequiredCount = jsenvPluginRequiredNames.length
|
|
181
|
-
if (jsenvPluginRequiredCount === 0) {
|
|
182
|
-
// no need to talk about something unused
|
|
183
|
-
} else {
|
|
184
|
-
parts.push(
|
|
185
|
-
`${jsenvPluginRequiredCount} jsenv plugins are mandatory: ${jsenvPluginRequiredNames}`,
|
|
186
|
-
)
|
|
187
|
-
}
|
|
188
|
-
|
|
189
187
|
return `
|
|
190
188
|
- ${parts.join(`
|
|
191
189
|
- `)}`
|
|
@@ -18,8 +18,13 @@ export const initToolbarEventSource = ({
|
|
|
18
18
|
executedFileRelativeUrl,
|
|
19
19
|
livereloading,
|
|
20
20
|
}) => {
|
|
21
|
+
const getLivereloadCallback = (originalFileProjectRelativeUrl) => {
|
|
22
|
+
const callbacks = window.parent.__jsenv__.livereloadingCallbacks
|
|
23
|
+
return callbacks[originalFileProjectRelativeUrl]
|
|
24
|
+
}
|
|
25
|
+
|
|
21
26
|
removeForceHideElement(document.querySelector("#eventsource-indicator"))
|
|
22
|
-
connectEventSource(executedFileRelativeUrl)
|
|
27
|
+
connectEventSource({ executedFileRelativeUrl, getLivereloadCallback })
|
|
23
28
|
livereloadingAvailableOnServer = livereloading
|
|
24
29
|
if (!livereloadingAvailableOnServer) {
|
|
25
30
|
disableLivereloadSetting()
|
|
@@ -54,11 +59,18 @@ let eventSourceHooks = {}
|
|
|
54
59
|
let eventSourceConnection
|
|
55
60
|
let connectionReadyPromise
|
|
56
61
|
|
|
57
|
-
const handleFileChange = (file,
|
|
58
|
-
latestChangeMap[file] =
|
|
62
|
+
const handleFileChange = ({ file, eventType, livereloadCallback }) => {
|
|
63
|
+
latestChangeMap[file] = eventType
|
|
59
64
|
updateEventSourceIndicator()
|
|
65
|
+
|
|
60
66
|
if (shouldLivereload()) {
|
|
61
|
-
if (
|
|
67
|
+
if (livereloadCallback) {
|
|
68
|
+
livereloadCallback({
|
|
69
|
+
file,
|
|
70
|
+
latestChangeMap,
|
|
71
|
+
reloadPage,
|
|
72
|
+
})
|
|
73
|
+
} else if (
|
|
62
74
|
file.endsWith(".css") ||
|
|
63
75
|
file.endsWith(".scss") ||
|
|
64
76
|
file.endsWith(".sass")
|
|
@@ -109,7 +121,10 @@ const reloadChanges = () => {
|
|
|
109
121
|
}
|
|
110
122
|
}
|
|
111
123
|
|
|
112
|
-
const connectEventSource = (
|
|
124
|
+
const connectEventSource = ({
|
|
125
|
+
executedFileRelativeUrl,
|
|
126
|
+
getLivereloadCallback,
|
|
127
|
+
}) => {
|
|
113
128
|
updateEventSourceIndicator()
|
|
114
129
|
connectionReadyPromise = createPromiseAndHooks()
|
|
115
130
|
|
|
@@ -117,13 +132,25 @@ const connectEventSource = (executedFileRelativeUrl) => {
|
|
|
117
132
|
executedFileRelativeUrl,
|
|
118
133
|
{
|
|
119
134
|
onFileModified: (file) => {
|
|
120
|
-
handleFileChange(
|
|
135
|
+
handleFileChange({
|
|
136
|
+
file,
|
|
137
|
+
eventType: "modified",
|
|
138
|
+
livereloadCallback: getLivereloadCallback(file),
|
|
139
|
+
})
|
|
121
140
|
},
|
|
122
141
|
onFileRemoved: (file) => {
|
|
123
|
-
handleFileChange(
|
|
142
|
+
handleFileChange({
|
|
143
|
+
file,
|
|
144
|
+
eventType: "removed",
|
|
145
|
+
livereloadCallback: getLivereloadCallback(file),
|
|
146
|
+
})
|
|
124
147
|
},
|
|
125
148
|
onFileAdded: (file) => {
|
|
126
|
-
handleFileChange(
|
|
149
|
+
handleFileChange({
|
|
150
|
+
file,
|
|
151
|
+
eventType: "added",
|
|
152
|
+
livereloadCallback: getLivereloadCallback(file),
|
|
153
|
+
})
|
|
127
154
|
},
|
|
128
155
|
onConnecting: ({ cancel }) => {
|
|
129
156
|
eventSourceState = "connecting"
|
|
@@ -80,7 +80,10 @@ const renderToolbar = async () => {
|
|
|
80
80
|
renderCompilationInToolbar({ compileGroup })
|
|
81
81
|
// this might become active but we need to detect this somehow
|
|
82
82
|
deactivateToolbarSection(document.querySelector("#file-list-link"))
|
|
83
|
-
initToolbarEventSource({
|
|
83
|
+
initToolbarEventSource({
|
|
84
|
+
executedFileRelativeUrl,
|
|
85
|
+
livereloading,
|
|
86
|
+
})
|
|
84
87
|
|
|
85
88
|
// if user click enter or space quickly while closing toolbar
|
|
86
89
|
// it will cancel the closing
|
|
@@ -188,13 +191,13 @@ const getCompileGroup = ({
|
|
|
188
191
|
outDirectoryRelativeUrl,
|
|
189
192
|
compileServerOrigin,
|
|
190
193
|
}) => {
|
|
191
|
-
const
|
|
194
|
+
const outDirectoryServerUrl = String(
|
|
192
195
|
new URL(outDirectoryRelativeUrl, compileServerOrigin),
|
|
193
196
|
)
|
|
194
|
-
if (urlIsInsideOf(executedFileCompiledUrl,
|
|
197
|
+
if (urlIsInsideOf(executedFileCompiledUrl, outDirectoryServerUrl)) {
|
|
195
198
|
const afterCompileDirectory = urlToRelativeUrl(
|
|
196
199
|
executedFileCompiledUrl,
|
|
197
|
-
|
|
200
|
+
outDirectoryServerUrl,
|
|
198
201
|
)
|
|
199
202
|
const slashIndex = afterCompileDirectory.indexOf("/")
|
|
200
203
|
const fileRelativeUrl = afterCompileDirectory.slice(slashIndex + 1)
|
|
@@ -11,3 +11,23 @@ export const setUrlExtension = (url, extension) => {
|
|
|
11
11
|
const newPathname = `${pathnameWithoutExtension}${extension}`
|
|
12
12
|
return `${origin}${newPathname}${search ? `?${search}` : ""}`
|
|
13
13
|
}
|
|
14
|
+
|
|
15
|
+
export const getUrlSearchParamsDescriptor = (url) => {
|
|
16
|
+
const urlObject = new URL(url)
|
|
17
|
+
const { searchParams } = urlObject
|
|
18
|
+
const searchParamsDescriptor = {}
|
|
19
|
+
Array.from(searchParams.keys()).forEach((key) => {
|
|
20
|
+
const value = searchParams.getAll(key)
|
|
21
|
+
searchParamsDescriptor[key] = value.length === 1 ? value[0] : value
|
|
22
|
+
})
|
|
23
|
+
return searchParamsDescriptor
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export const setUrlSearchParamsDescriptor = (url, searchParamsDescriptor) => {
|
|
27
|
+
const urlObject = new URL(url)
|
|
28
|
+
const { searchParams } = urlObject
|
|
29
|
+
Object.keys(searchParamsDescriptor).forEach((key) => {
|
|
30
|
+
searchParams.set(key, searchParamsDescriptor[key])
|
|
31
|
+
})
|
|
32
|
+
return String(urlObject)
|
|
33
|
+
}
|
package/src/launchBrowser.js
CHANGED
|
@@ -5,11 +5,12 @@ import {
|
|
|
5
5
|
createCancellationToken,
|
|
6
6
|
createStoppableOperation,
|
|
7
7
|
} from "@jsenv/cancellation"
|
|
8
|
+
import { createDetailedMessage } from "@jsenv/logger"
|
|
8
9
|
import { teardownSignal } from "@jsenv/node-signals"
|
|
9
10
|
|
|
10
11
|
import { trackRessources } from "./internal/trackRessources.js"
|
|
11
12
|
import { fetchUrl } from "./internal/fetchUrl.js"
|
|
12
|
-
import {
|
|
13
|
+
import { validateResponse } from "./internal/response_validation.js"
|
|
13
14
|
import { trackPageToNotify } from "./internal/browser-launcher/trackPageToNotify.js"
|
|
14
15
|
import { createSharing } from "./internal/browser-launcher/createSharing.js"
|
|
15
16
|
import { executeHtmlFile } from "./internal/browser-launcher/executeHtmlFile.js"
|
|
@@ -20,8 +21,11 @@ import {
|
|
|
20
21
|
} from "./playwright_browser_versions.js"
|
|
21
22
|
|
|
22
23
|
const chromiumSharing = createSharing()
|
|
23
|
-
|
|
24
|
-
|
|
24
|
+
export const chromiumRuntime = {
|
|
25
|
+
name: "chromium",
|
|
26
|
+
version: PLAYWRIGHT_CHROMIUM_VERSION,
|
|
27
|
+
}
|
|
28
|
+
chromiumRuntime.launch = async ({
|
|
25
29
|
browserServerLogLevel,
|
|
26
30
|
cancellationToken = createCancellationToken(),
|
|
27
31
|
chromiumExecutablePath,
|
|
@@ -91,9 +95,11 @@ export const launchChromium = async ({
|
|
|
91
95
|
cancellationToken,
|
|
92
96
|
ignoreHttpsError: true,
|
|
93
97
|
})
|
|
94
|
-
const {
|
|
95
|
-
|
|
96
|
-
|
|
98
|
+
const { isValid, message, details } = await validateResponse(
|
|
99
|
+
browserResponse,
|
|
100
|
+
)
|
|
101
|
+
if (!isValid) {
|
|
102
|
+
throw new Error(createDetailedMessage(message, details))
|
|
97
103
|
}
|
|
98
104
|
|
|
99
105
|
const browserResponseObject = JSON.parse(browserResponse.body)
|
|
@@ -103,8 +109,6 @@ export const launchChromium = async ({
|
|
|
103
109
|
|
|
104
110
|
return {
|
|
105
111
|
browser,
|
|
106
|
-
runtimeName: "chromium",
|
|
107
|
-
runtimeVersion: PLAYWRIGHT_CHROMIUM_VERSION,
|
|
108
112
|
stop: ressourceTracker.cleanup,
|
|
109
113
|
...browserToRuntimeHooks(browser, {
|
|
110
114
|
browserServerLogLevel,
|
|
@@ -124,16 +128,21 @@ export const launchChromium = async ({
|
|
|
124
128
|
}),
|
|
125
129
|
}
|
|
126
130
|
}
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
131
|
+
export const chromiumTabRuntime = {
|
|
132
|
+
...chromiumRuntime,
|
|
133
|
+
launch: (params) =>
|
|
134
|
+
chromiumRuntime.launch({
|
|
135
|
+
shared: true,
|
|
136
|
+
...params,
|
|
137
|
+
}),
|
|
138
|
+
}
|
|
133
139
|
|
|
134
140
|
const firefoxSharing = createSharing()
|
|
135
|
-
|
|
136
|
-
|
|
141
|
+
export const firefoxRuntime = {
|
|
142
|
+
name: "firefox",
|
|
143
|
+
version: PLAYWRIGHT_FIREFOX_VERSION,
|
|
144
|
+
}
|
|
145
|
+
firefoxRuntime.launch = async ({
|
|
137
146
|
cancellationToken = createCancellationToken(),
|
|
138
147
|
firefoxExecutablePath,
|
|
139
148
|
browserServerLogLevel,
|
|
@@ -179,8 +188,6 @@ export const launchFirefox = async ({
|
|
|
179
188
|
|
|
180
189
|
return {
|
|
181
190
|
browser,
|
|
182
|
-
runtimeName: "firefox",
|
|
183
|
-
runtimeVersion: PLAYWRIGHT_FIREFOX_VERSION,
|
|
184
191
|
stop: ressourceTracker.cleanup,
|
|
185
192
|
...browserToRuntimeHooks(browser, {
|
|
186
193
|
browserServerLogLevel,
|
|
@@ -199,16 +206,21 @@ export const launchFirefox = async ({
|
|
|
199
206
|
}),
|
|
200
207
|
}
|
|
201
208
|
}
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
209
|
+
export const firefoxTabRuntime = {
|
|
210
|
+
...firefoxRuntime,
|
|
211
|
+
launch: (params) =>
|
|
212
|
+
firefoxRuntime.launch({
|
|
213
|
+
shared: true,
|
|
214
|
+
...params,
|
|
215
|
+
}),
|
|
216
|
+
}
|
|
208
217
|
|
|
209
218
|
const webkitSharing = createSharing()
|
|
210
|
-
|
|
211
|
-
|
|
219
|
+
export const webkitRuntime = {
|
|
220
|
+
name: "webkit",
|
|
221
|
+
version: PLAYWRIGHT_WEBKIT_VERSION,
|
|
222
|
+
}
|
|
223
|
+
webkitRuntime.launch = async ({
|
|
212
224
|
browserServerLogLevel,
|
|
213
225
|
cancellationToken = createCancellationToken(),
|
|
214
226
|
webkitExecutablePath,
|
|
@@ -254,8 +266,7 @@ export const launchWebkit = async ({
|
|
|
254
266
|
|
|
255
267
|
return {
|
|
256
268
|
browser,
|
|
257
|
-
|
|
258
|
-
runtimeVersion: PLAYWRIGHT_WEBKIT_VERSION,
|
|
269
|
+
|
|
259
270
|
stop: ressourceTracker.cleanup,
|
|
260
271
|
...browserToRuntimeHooks(browser, {
|
|
261
272
|
browserServerLogLevel,
|
|
@@ -274,12 +285,14 @@ export const launchWebkit = async ({
|
|
|
274
285
|
}),
|
|
275
286
|
}
|
|
276
287
|
}
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
288
|
+
export const webkitTabRuntime = {
|
|
289
|
+
...webkitRuntime,
|
|
290
|
+
launch: (params) =>
|
|
291
|
+
webkitRuntime.launch({
|
|
292
|
+
shared: true,
|
|
293
|
+
...params,
|
|
294
|
+
}),
|
|
295
|
+
}
|
|
283
296
|
|
|
284
297
|
const launchBrowser = async (
|
|
285
298
|
browserName,
|
package/src/launchNode.js
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
/* eslint-disable import/max-dependencies */
|
|
2
|
-
import { Script } from "vm"
|
|
3
|
-
|
|
2
|
+
import { Script } from "node:vm"
|
|
4
3
|
import cuid from "cuid"
|
|
5
4
|
import { loggerToLogLevel } from "@jsenv/logger"
|
|
6
5
|
import { createCancellationToken } from "@jsenv/cancellation"
|
|
@@ -17,7 +16,11 @@ import { escapeRegexpSpecialCharacters } from "./internal/escapeRegexpSpecialCha
|
|
|
17
16
|
import { createControllableNodeProcess } from "./internal/node-launcher/createControllableNodeProcess.js"
|
|
18
17
|
import { v8CoverageFromNodeV8Directory } from "./internal/executing/coverage/v8CoverageFromNodeV8Directory.js"
|
|
19
18
|
|
|
20
|
-
export const
|
|
19
|
+
export const nodeRuntime = {
|
|
20
|
+
name: "node",
|
|
21
|
+
version: process.version.slice(1),
|
|
22
|
+
}
|
|
23
|
+
nodeRuntime.launch = async ({
|
|
21
24
|
logger,
|
|
22
25
|
logProcessCommand,
|
|
23
26
|
cancellationToken = createCancellationToken(),
|