@jsenv/core 23.8.2 → 23.8.7
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 +46 -39
- package/dist/jsenv_browser_system.js.map +14 -14
- package/dist/jsenv_compile_proxy.js.map +6 -6
- package/dist/jsenv_exploring_index.js.map +5 -5
- package/dist/jsenv_exploring_redirector.js.map +12 -12
- package/dist/jsenv_toolbar.js.map +7 -7
- package/dist/jsenv_toolbar_injector.js.map +5 -5
- package/helpers/babel/.eslintrc.cjs +24 -24
- package/helpers/babel/AsyncGenerator/AsyncGenerator.js +81 -81
- package/helpers/babel/AwaitValue/AwaitValue.js +3 -3
- package/helpers/babel/applyDecoratorDescriptor/applyDecoratorDescriptor.js +33 -33
- package/helpers/babel/arrayLikeToArray/arrayLikeToArray.js +7 -7
- package/helpers/babel/arrayWithHoles/arrayWithHoles.js +4 -4
- package/helpers/babel/arrayWithoutHoles/arrayWithoutHoles.js +6 -6
- package/helpers/babel/assertThisInitialized/assertThisInitialized.js +7 -7
- package/helpers/babel/asyncGeneratorDelegate/asyncGeneratorDelegate.js +40 -40
- package/helpers/babel/asyncIterator/asyncIterator.js +12 -12
- package/helpers/babel/asyncToGenerator/asyncToGenerator.js +34 -34
- package/helpers/babel/awaitAsyncGenerator/awaitAsyncGenerator.js +5 -5
- package/helpers/babel/classApplyDescriptorDestructureSet/classApplyDescriptorDestructureSet.js +20 -20
- package/helpers/babel/classApplyDescriptorGet/classApplyDescriptorGet.js +6 -6
- package/helpers/babel/classApplyDescriptorSet/classApplyDescriptorSet.js +13 -13
- package/helpers/babel/classCallCheck/classCallCheck.js +5 -5
- package/helpers/babel/classCheckPrivateStaticAccess/classCheckPrivateStaticAccess.js +5 -5
- package/helpers/babel/classCheckPrivateStaticFieldDescriptor/classCheckPrivateStaticFieldDescriptor.js +6 -6
- package/helpers/babel/classExtractFieldDescriptor/classExtractFieldDescriptor.js +7 -7
- package/helpers/babel/classNameTDZError/classNameTDZError.js +4 -4
- package/helpers/babel/classPrivateFieldDestructureSet/classPrivateFieldDestructureSet.js +7 -7
- package/helpers/babel/classPrivateFieldGet/classPrivateFieldGet.js +7 -7
- package/helpers/babel/classPrivateFieldLooseBase/classPrivateFieldLooseBase.js +6 -6
- package/helpers/babel/classPrivateFieldLooseKey/classPrivateFieldLooseKey.js +5 -5
- package/helpers/babel/classPrivateFieldSet/classPrivateFieldSet.js +8 -8
- package/helpers/babel/classPrivateMethodGet/classPrivateMethodGet.js +6 -6
- package/helpers/babel/classPrivateMethodSet/classPrivateMethodSet.js +3 -3
- package/helpers/babel/classStaticPrivateFieldSpecGet/classStaticPrivateFieldSpecGet.js +9 -9
- package/helpers/babel/classStaticPrivateFieldSpecSet/classStaticPrivateFieldSpecSet.js +15 -15
- package/helpers/babel/classStaticPrivateMethodGet/classStaticPrivateMethodGet.js +6 -6
- package/helpers/babel/classStaticPrivateMethodSet/classStaticPrivateMethodSet.js +3 -3
- package/helpers/babel/construct/construct.js +16 -16
- package/helpers/babel/createClass/createClass.js +15 -15
- package/helpers/babel/createForOfIteratorHelper/createForOfIteratorHelper.js +60 -60
- package/helpers/babel/createForOfIteratorHelperLoose/createForOfIteratorHelperLoose.js +23 -23
- package/helpers/babel/createRawReactElement/createRawReactElement.js +50 -50
- package/helpers/babel/createSuper/createSuper.js +22 -22
- package/helpers/babel/decorate/decorate.js +403 -403
- package/helpers/babel/defaults/defaults.js +11 -11
- package/helpers/babel/defineEnumerableProperties/defineEnumerableProperties.js +23 -23
- package/helpers/babel/defineProperty/defineProperty.js +18 -18
- package/helpers/babel/extends/extends.js +14 -14
- package/helpers/babel/get/get.js +13 -13
- package/helpers/babel/getPrototypeOf/getPrototypeOf.js +4 -4
- package/helpers/babel/inherits/inherits.js +15 -15
- package/helpers/babel/inheritsLoose/inheritsLoose.js +7 -7
- package/helpers/babel/initializerDefineProperty/initializerDefineProperty.js +10 -10
- package/helpers/babel/initializerWarningHelper/initializerWarningHelper.js +6 -6
- package/helpers/babel/instanceof/instanceof.js +6 -6
- package/helpers/babel/interopRequireDefault/interopRequireDefault.js +3 -3
- package/helpers/babel/interopRequireWildcard/interopRequireWildcard.js +37 -37
- package/helpers/babel/isNativeFunction/isNativeFunction.js +4 -4
- package/helpers/babel/isNativeReflectConstruct/isNativeReflectConstruct.js +21 -21
- package/helpers/babel/iterableToArray/iterableToArray.js +7 -7
- package/helpers/babel/iterableToArrayLimit/iterableToArrayLimit.js +36 -36
- package/helpers/babel/iterableToArrayLimitLoose/iterableToArrayLimitLoose.js +10 -10
- package/helpers/babel/jsx/jsx.js +45 -45
- package/helpers/babel/maybeArrayLike/maybeArrayLike.js +10 -10
- package/helpers/babel/newArrowCheck/newArrowCheck.js +5 -5
- package/helpers/babel/nonIterableRest/nonIterableRest.js +5 -5
- package/helpers/babel/nonIterableSpread/nonIterableSpread.js +5 -5
- package/helpers/babel/objectDestructuringEmpty/objectDestructuringEmpty.js +3 -3
- package/helpers/babel/objectSpread/objectSpread.js +23 -23
- package/helpers/babel/objectSpread2/objectSpread2.js +33 -33
- package/helpers/babel/objectWithoutProperties/objectWithoutProperties.js +19 -19
- package/helpers/babel/objectWithoutPropertiesLoose/objectWithoutPropertiesLoose.js +13 -13
- package/helpers/babel/possibleConstructorReturn/possibleConstructorReturn.js +10 -10
- package/helpers/babel/readOnlyError/readOnlyError.js +4 -4
- package/helpers/babel/readme.md +9 -9
- package/helpers/babel/set/set.js +44 -44
- package/helpers/babel/setPrototypeOf/setPrototypeOf.js +6 -6
- package/helpers/babel/skipFirstGeneratorNext/skipFirstGeneratorNext.js +8 -8
- package/helpers/babel/slicedToArray/slicedToArray.js +10 -10
- package/helpers/babel/slicedToArrayLoose/slicedToArrayLoose.js +13 -13
- package/helpers/babel/superPropBase/superPropBase.js +10 -10
- package/helpers/babel/taggedTemplateLiteral/taggedTemplateLiteral.js +10 -10
- package/helpers/babel/taggedTemplateLiteralLoose/taggedTemplateLiteralLoose.js +7 -7
- package/helpers/babel/tdz/tdz.js +4 -4
- package/helpers/babel/temporalRef/temporalRef.js +6 -6
- package/helpers/babel/temporalUndefined/temporalUndefined.js +3 -3
- package/helpers/babel/toArray/toArray.js +10 -10
- package/helpers/babel/toConsumableArray/toConsumableArray.js +10 -10
- package/helpers/babel/toPrimitive/toPrimitive.js +10 -10
- package/helpers/babel/toPropertyKey/toPropertyKey.js +6 -6
- package/helpers/babel/typeof/typeof.js +14 -14
- package/helpers/babel/unsupportedIterableToArray/unsupportedIterableToArray.js +12 -12
- package/helpers/babel/wrapAsyncGenerator/wrapAsyncGenerator.js +8 -8
- package/helpers/babel/wrapNativeSuper/wrapNativeSuper.js +30 -30
- package/helpers/babel/wrapRegExp/wrapRegExp.js +63 -63
- package/helpers/babel/writeOnlyError/writeOnlyError.js +4 -4
- package/helpers/regenerator-runtime/regenerator-runtime.js +748 -748
- package/{LICENSE → license} +21 -21
- package/package.json +2 -2
- package/src/buildProject.js +300 -300
- package/src/execute.js +184 -184
- package/src/internal/browser-launcher/jsenv-browser-system.js +203 -199
- package/src/internal/building/buildUsingRollup.js +2 -10
- package/src/internal/compiling/babel_plugin_import_assertions.js +121 -121
- package/src/internal/compiling/babel_plugin_import_metadata.js +22 -22
- package/src/internal/compiling/babel_plugin_import_visitor.js +84 -84
- package/src/internal/compiling/compile-directory/getOrGenerateCompiledFile.js +268 -268
- package/src/internal/compiling/compile-directory/updateMeta.js +154 -154
- package/src/internal/compiling/compile-directory/validateCache.js +265 -265
- package/src/internal/compiling/compileFile.js +233 -224
- package/src/internal/compiling/compileHtml.js +550 -550
- package/src/internal/compiling/createCompiledFileService.js +291 -291
- package/src/internal/compiling/html_source_file_service.js +403 -404
- package/src/internal/compiling/js-compilation-service/jsenvTransform.js +272 -270
- package/src/internal/compiling/jsenvCompilerForHtml.js +374 -308
- package/src/internal/compiling/jsenvCompilerForJavaScript.js +2 -0
- package/src/internal/compiling/startCompileServer.js +1086 -1048
- package/src/internal/compiling/transformResultToCompilationResult.js +220 -220
- package/src/internal/executing/coverage/babel_plugin_instrument.js +90 -90
- package/src/internal/executing/coverage/reportToCoverage.js +193 -187
- package/src/internal/executing/executePlan.js +183 -183
- package/src/internal/executing/launchAndExecute.js +458 -458
- package/src/internal/generateGroupMap/featuresCompatMap.js +29 -0
- package/src/internal/generateGroupMap/jsenvBabelPluginCompatMap.js +1 -8
- package/src/internal/runtime/createBrowserRuntime/scanBrowserRuntimeFeatures.js +246 -246
- package/src/internal/runtime/createNodeRuntime/scanNodeRuntimeFeatures.js +112 -112
- package/src/internal/runtime/s.js +727 -727
- package/src/internal/toolbar/jsenv-logo.svg +144 -144
- package/src/internal/toolbar/toolbar.main.css +196 -196
- package/src/internal/toolbar/toolbar.main.js +227 -227
- package/src/internal/url_conversion.js +317 -317
- package/src/startExploring.js +309 -309
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
// https://github.com/babel/babel/blob/master/packages/babel-compat-data/data/native-modules.json#L1
|
|
2
|
+
|
|
3
|
+
export const featuresCompatMap = {
|
|
4
|
+
module: {
|
|
5
|
+
edge: "16",
|
|
6
|
+
firefox: "60",
|
|
7
|
+
chrome: "61",
|
|
8
|
+
safari: "10.1",
|
|
9
|
+
opera: "48",
|
|
10
|
+
ios: "10.3",
|
|
11
|
+
android: "61",
|
|
12
|
+
samsung: "8.2",
|
|
13
|
+
},
|
|
14
|
+
// https://caniuse.com/import-maps
|
|
15
|
+
importmap: {
|
|
16
|
+
edge: "89",
|
|
17
|
+
chrome: "89",
|
|
18
|
+
opera: "76",
|
|
19
|
+
samsung: "15",
|
|
20
|
+
},
|
|
21
|
+
import_assertion_type_json: {
|
|
22
|
+
chrome: "91",
|
|
23
|
+
edge: "91",
|
|
24
|
+
},
|
|
25
|
+
import_assertion_type_css: {
|
|
26
|
+
chrome: "93",
|
|
27
|
+
edge: "93",
|
|
28
|
+
},
|
|
29
|
+
}
|
|
@@ -443,14 +443,7 @@ jsenvBabelPluginCompatMap["global-this-as-jsenv-import"] = {
|
|
|
443
443
|
node: "12",
|
|
444
444
|
}
|
|
445
445
|
|
|
446
|
-
//
|
|
447
|
-
// chrome: "91",
|
|
448
|
-
// edge: "91",
|
|
449
|
-
// }
|
|
450
|
-
// jsenvBabelPluginCompatMap["transform-import-assertion-css"] = {
|
|
451
|
-
// chrome: "93",
|
|
452
|
-
// edge: "93",
|
|
453
|
-
// }
|
|
446
|
+
// needs support for both json and css
|
|
454
447
|
jsenvBabelPluginCompatMap["transform-import-assertions"] = {
|
|
455
448
|
chrome: "93",
|
|
456
449
|
edge: "93",
|
|
@@ -1,246 +1,246 @@
|
|
|
1
|
-
import { fetchJson } from "../../browser-utils/fetchJson.js"
|
|
2
|
-
import { computeCompileIdFromGroupId } from "../computeCompileIdFromGroupId.js"
|
|
3
|
-
import { detectBrowser } from "../detectBrowser/detectBrowser.js"
|
|
4
|
-
import { resolveGroup } from "../resolveGroup.js"
|
|
5
|
-
|
|
6
|
-
export const scanBrowserRuntimeFeatures = async ({
|
|
7
|
-
coverageHandledFromOutside = false,
|
|
8
|
-
failFastOnFeatureDetection = false,
|
|
9
|
-
} = {}) => {
|
|
10
|
-
const {
|
|
11
|
-
outDirectoryRelativeUrl,
|
|
12
|
-
inlineImportMapIntoHTML,
|
|
13
|
-
customCompilerPatterns,
|
|
14
|
-
compileServerGroupMap,
|
|
15
|
-
} = await fetchJson("/.jsenv/__compile_server_meta__.json")
|
|
16
|
-
|
|
17
|
-
const browser = detectBrowser()
|
|
18
|
-
const compileId = computeCompileIdFromGroupId({
|
|
19
|
-
groupId: resolveGroup(browser, compileServerGroupMap),
|
|
20
|
-
groupMap: compileServerGroupMap,
|
|
21
|
-
})
|
|
22
|
-
const groupInfo = compileServerGroupMap[compileId]
|
|
23
|
-
|
|
24
|
-
const featuresReport = {
|
|
25
|
-
importmap: undefined,
|
|
26
|
-
dynamicImport: undefined,
|
|
27
|
-
topLevelAwait: undefined,
|
|
28
|
-
jsonImportAssertions: undefined,
|
|
29
|
-
cssImportAssertions: undefined,
|
|
30
|
-
newStylesheet: undefined,
|
|
31
|
-
}
|
|
32
|
-
await detectSupportedFeatures({
|
|
33
|
-
featuresReport,
|
|
34
|
-
failFastOnFeatureDetection,
|
|
35
|
-
inlineImportMapIntoHTML,
|
|
36
|
-
})
|
|
37
|
-
const pluginRequiredNameArray = await pluginRequiredNamesFromGroupInfo(
|
|
38
|
-
groupInfo,
|
|
39
|
-
{
|
|
40
|
-
featuresReport,
|
|
41
|
-
coverageHandledFromOutside,
|
|
42
|
-
},
|
|
43
|
-
)
|
|
44
|
-
|
|
45
|
-
const canAvoidCompilation =
|
|
46
|
-
customCompilerPatterns.length === 0 &&
|
|
47
|
-
pluginRequiredNameArray.length === 0 &&
|
|
48
|
-
featuresReport.importmap &&
|
|
49
|
-
featuresReport.dynamicImport &&
|
|
50
|
-
featuresReport.topLevelAwait
|
|
51
|
-
|
|
52
|
-
return {
|
|
53
|
-
canAvoidCompilation,
|
|
54
|
-
featuresReport,
|
|
55
|
-
customCompilerPatterns,
|
|
56
|
-
pluginRequiredNameArray,
|
|
57
|
-
inlineImportMapIntoHTML,
|
|
58
|
-
outDirectoryRelativeUrl,
|
|
59
|
-
compileId,
|
|
60
|
-
browser,
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
const detectSupportedFeatures = async ({
|
|
65
|
-
featuresReport,
|
|
66
|
-
failFastOnFeatureDetection,
|
|
67
|
-
inlineImportMapIntoHTML,
|
|
68
|
-
}) => {
|
|
69
|
-
// start testing importmap support first and not in paralell
|
|
70
|
-
// so that there is not module script loaded beore importmap is injected
|
|
71
|
-
// it would log an error in chrome console and return undefined
|
|
72
|
-
const importmap = await supportsImportmap({
|
|
73
|
-
// chrome supports inline but not remote importmap
|
|
74
|
-
// https://github.com/WICG/import-maps/issues/235
|
|
75
|
-
|
|
76
|
-
// at this stage we won't know if the html file will use
|
|
77
|
-
// an importmap or not and if that importmap is inline or specified with an src
|
|
78
|
-
// so we should test if browser support local and remote importmap.
|
|
79
|
-
// But there exploring server can inline importmap by transforming html
|
|
80
|
-
// and in that case we can test only the local importmap support
|
|
81
|
-
// so we test importmap support and the remote one
|
|
82
|
-
remote: !inlineImportMapIntoHTML,
|
|
83
|
-
})
|
|
84
|
-
featuresReport.importmap = importmap
|
|
85
|
-
if (!importmap && failFastOnFeatureDetection) {
|
|
86
|
-
return
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
const dynamicImport = await supportsDynamicImport()
|
|
90
|
-
featuresReport.dynamicImport = dynamicImport
|
|
91
|
-
if (!dynamicImport && failFastOnFeatureDetection) {
|
|
92
|
-
return
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
const topLevelAwait = await supportsTopLevelAwait()
|
|
96
|
-
featuresReport.topLevelAwait = topLevelAwait
|
|
97
|
-
if (!topLevelAwait && failFastOnFeatureDetection) {
|
|
98
|
-
return
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
const pluginRequiredNamesFromGroupInfo = async (
|
|
103
|
-
groupInfo,
|
|
104
|
-
{ featuresReport, coverageHandledFromOutside },
|
|
105
|
-
) => {
|
|
106
|
-
const { pluginRequiredNameArray } = groupInfo
|
|
107
|
-
const requiredPluginNames = pluginRequiredNameArray.slice()
|
|
108
|
-
const markPluginAsSupported = (name) => {
|
|
109
|
-
const index = requiredPluginNames.indexOf(name)
|
|
110
|
-
if (index > -1) {
|
|
111
|
-
requiredPluginNames.splice(index, 1)
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
// When instrumentation CAN be handed by playwright
|
|
116
|
-
// https://playwright.dev/docs/api/class-chromiumcoverage#chromiumcoveragestartjscoverageoptions
|
|
117
|
-
// coverageHandledFromOutside is true and "transform-instrument" becomes non mandatory
|
|
118
|
-
if (coverageHandledFromOutside) {
|
|
119
|
-
markPluginAsSupported("transform-instrument")
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
if (pluginRequiredNameArray.includes("transform-import-assertions")) {
|
|
123
|
-
const jsonImportAssertions = await supportsJsonImportAssertions()
|
|
124
|
-
featuresReport.jsonImportAssertions = jsonImportAssertions
|
|
125
|
-
|
|
126
|
-
const cssImportAssertions = await supportsCssImportAssertions()
|
|
127
|
-
featuresReport.cssImportAssertions = cssImportAssertions
|
|
128
|
-
|
|
129
|
-
if (jsonImportAssertions && cssImportAssertions) {
|
|
130
|
-
markPluginAsSupported("transform-import-assertions")
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
if (pluginRequiredNameArray.includes("new-stylesheet-as-jsenv-import")) {
|
|
135
|
-
const newStylesheet = supportsNewStylesheet()
|
|
136
|
-
featuresReport.newStylesheet = newStylesheet
|
|
137
|
-
markPluginAsSupported("new-stylesheet-as-jsenv-import")
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
return requiredPluginNames
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
const supportsNewStylesheet = () => {
|
|
144
|
-
try {
|
|
145
|
-
// eslint-disable-next-line no-new
|
|
146
|
-
new CSSStyleSheet()
|
|
147
|
-
return true
|
|
148
|
-
} catch (e) {
|
|
149
|
-
return false
|
|
150
|
-
}
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
const supportsImportmap = async ({ remote = true } = {}) => {
|
|
154
|
-
const specifier = asBase64Url(`export default false`)
|
|
155
|
-
|
|
156
|
-
const importMap = {
|
|
157
|
-
imports: {
|
|
158
|
-
[specifier]: asBase64Url(`export default true`),
|
|
159
|
-
},
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
const importmapScript = document.createElement("script")
|
|
163
|
-
const importmapString = JSON.stringify(importMap, null, " ")
|
|
164
|
-
importmapScript.type = "importmap"
|
|
165
|
-
if (remote) {
|
|
166
|
-
importmapScript.src = `data:application/json;base64,${window.btoa(
|
|
167
|
-
importmapString,
|
|
168
|
-
)}`
|
|
169
|
-
} else {
|
|
170
|
-
importmapScript.textContent = importmapString
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
document.body.appendChild(importmapScript)
|
|
174
|
-
|
|
175
|
-
const scriptModule = document.createElement("script")
|
|
176
|
-
scriptModule.type = "module"
|
|
177
|
-
scriptModule.src = asBase64Url(
|
|
178
|
-
`import supported from "${specifier}"; window.__importmap_supported = supported`,
|
|
179
|
-
)
|
|
180
|
-
|
|
181
|
-
return new Promise((resolve, reject) => {
|
|
182
|
-
scriptModule.onload = () => {
|
|
183
|
-
const supported = window.__importmap_supported
|
|
184
|
-
delete window.__importmap_supported
|
|
185
|
-
document.body.removeChild(scriptModule)
|
|
186
|
-
document.body.removeChild(importmapScript)
|
|
187
|
-
resolve(supported)
|
|
188
|
-
}
|
|
189
|
-
scriptModule.onerror = () => {
|
|
190
|
-
document.body.removeChild(scriptModule)
|
|
191
|
-
document.body.removeChild(importmapScript)
|
|
192
|
-
reject()
|
|
193
|
-
}
|
|
194
|
-
document.body.appendChild(scriptModule)
|
|
195
|
-
})
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
const supportsDynamicImport = async () => {
|
|
199
|
-
const moduleSource = asBase64Url(`export default 42`)
|
|
200
|
-
try {
|
|
201
|
-
const namespace = await import(moduleSource)
|
|
202
|
-
return namespace.default === 42
|
|
203
|
-
} catch (e) {
|
|
204
|
-
return false
|
|
205
|
-
}
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
const supportsTopLevelAwait = async () => {
|
|
209
|
-
const moduleSource = asBase64Url(`export default await Promise.resolve(42)`)
|
|
210
|
-
try {
|
|
211
|
-
const namespace = await import(moduleSource)
|
|
212
|
-
return namespace.default === 42
|
|
213
|
-
} catch (e) {
|
|
214
|
-
return false
|
|
215
|
-
}
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
const supportsJsonImportAssertions = async () => {
|
|
219
|
-
const jsonBase64Url = asBase64Url("42", "application/json")
|
|
220
|
-
const moduleSource = asBase64Url(
|
|
221
|
-
`export { default } from "${jsonBase64Url}" assert { type: "json" }`,
|
|
222
|
-
)
|
|
223
|
-
try {
|
|
224
|
-
const namespace = await import(moduleSource)
|
|
225
|
-
return namespace.default === 42
|
|
226
|
-
} catch (e) {
|
|
227
|
-
return false
|
|
228
|
-
}
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
const supportsCssImportAssertions = async () => {
|
|
232
|
-
const cssBase64Url = asBase64Url("p { color: red; }", "text/css")
|
|
233
|
-
const moduleSource = asBase64Url(
|
|
234
|
-
`export { default } from "${cssBase64Url}" assert { type: "css" }`,
|
|
235
|
-
)
|
|
236
|
-
try {
|
|
237
|
-
const namespace = await import(moduleSource)
|
|
238
|
-
return namespace.default instanceof CSSStyleSheet
|
|
239
|
-
} catch (e) {
|
|
240
|
-
return false
|
|
241
|
-
}
|
|
242
|
-
}
|
|
243
|
-
|
|
244
|
-
const asBase64Url = (text, mimeType = "application/javascript") => {
|
|
245
|
-
return `data:${mimeType};base64,${window.btoa(text)}`
|
|
246
|
-
}
|
|
1
|
+
import { fetchJson } from "../../browser-utils/fetchJson.js"
|
|
2
|
+
import { computeCompileIdFromGroupId } from "../computeCompileIdFromGroupId.js"
|
|
3
|
+
import { detectBrowser } from "../detectBrowser/detectBrowser.js"
|
|
4
|
+
import { resolveGroup } from "../resolveGroup.js"
|
|
5
|
+
|
|
6
|
+
export const scanBrowserRuntimeFeatures = async ({
|
|
7
|
+
coverageHandledFromOutside = false,
|
|
8
|
+
failFastOnFeatureDetection = false,
|
|
9
|
+
} = {}) => {
|
|
10
|
+
const {
|
|
11
|
+
outDirectoryRelativeUrl,
|
|
12
|
+
inlineImportMapIntoHTML,
|
|
13
|
+
customCompilerPatterns,
|
|
14
|
+
compileServerGroupMap,
|
|
15
|
+
} = await fetchJson("/.jsenv/__compile_server_meta__.json")
|
|
16
|
+
|
|
17
|
+
const browser = detectBrowser()
|
|
18
|
+
const compileId = computeCompileIdFromGroupId({
|
|
19
|
+
groupId: resolveGroup(browser, compileServerGroupMap),
|
|
20
|
+
groupMap: compileServerGroupMap,
|
|
21
|
+
})
|
|
22
|
+
const groupInfo = compileServerGroupMap[compileId]
|
|
23
|
+
|
|
24
|
+
const featuresReport = {
|
|
25
|
+
importmap: undefined,
|
|
26
|
+
dynamicImport: undefined,
|
|
27
|
+
topLevelAwait: undefined,
|
|
28
|
+
jsonImportAssertions: undefined,
|
|
29
|
+
cssImportAssertions: undefined,
|
|
30
|
+
newStylesheet: undefined,
|
|
31
|
+
}
|
|
32
|
+
await detectSupportedFeatures({
|
|
33
|
+
featuresReport,
|
|
34
|
+
failFastOnFeatureDetection,
|
|
35
|
+
inlineImportMapIntoHTML,
|
|
36
|
+
})
|
|
37
|
+
const pluginRequiredNameArray = await pluginRequiredNamesFromGroupInfo(
|
|
38
|
+
groupInfo,
|
|
39
|
+
{
|
|
40
|
+
featuresReport,
|
|
41
|
+
coverageHandledFromOutside,
|
|
42
|
+
},
|
|
43
|
+
)
|
|
44
|
+
|
|
45
|
+
const canAvoidCompilation =
|
|
46
|
+
customCompilerPatterns.length === 0 &&
|
|
47
|
+
pluginRequiredNameArray.length === 0 &&
|
|
48
|
+
featuresReport.importmap &&
|
|
49
|
+
featuresReport.dynamicImport &&
|
|
50
|
+
featuresReport.topLevelAwait
|
|
51
|
+
|
|
52
|
+
return {
|
|
53
|
+
canAvoidCompilation,
|
|
54
|
+
featuresReport,
|
|
55
|
+
customCompilerPatterns,
|
|
56
|
+
pluginRequiredNameArray,
|
|
57
|
+
inlineImportMapIntoHTML,
|
|
58
|
+
outDirectoryRelativeUrl,
|
|
59
|
+
compileId,
|
|
60
|
+
browser,
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
const detectSupportedFeatures = async ({
|
|
65
|
+
featuresReport,
|
|
66
|
+
failFastOnFeatureDetection,
|
|
67
|
+
inlineImportMapIntoHTML,
|
|
68
|
+
}) => {
|
|
69
|
+
// start testing importmap support first and not in paralell
|
|
70
|
+
// so that there is not module script loaded beore importmap is injected
|
|
71
|
+
// it would log an error in chrome console and return undefined
|
|
72
|
+
const importmap = await supportsImportmap({
|
|
73
|
+
// chrome supports inline but not remote importmap
|
|
74
|
+
// https://github.com/WICG/import-maps/issues/235
|
|
75
|
+
|
|
76
|
+
// at this stage we won't know if the html file will use
|
|
77
|
+
// an importmap or not and if that importmap is inline or specified with an src
|
|
78
|
+
// so we should test if browser support local and remote importmap.
|
|
79
|
+
// But there exploring server can inline importmap by transforming html
|
|
80
|
+
// and in that case we can test only the local importmap support
|
|
81
|
+
// so we test importmap support and the remote one
|
|
82
|
+
remote: !inlineImportMapIntoHTML,
|
|
83
|
+
})
|
|
84
|
+
featuresReport.importmap = importmap
|
|
85
|
+
if (!importmap && failFastOnFeatureDetection) {
|
|
86
|
+
return
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
const dynamicImport = await supportsDynamicImport()
|
|
90
|
+
featuresReport.dynamicImport = dynamicImport
|
|
91
|
+
if (!dynamicImport && failFastOnFeatureDetection) {
|
|
92
|
+
return
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
const topLevelAwait = await supportsTopLevelAwait()
|
|
96
|
+
featuresReport.topLevelAwait = topLevelAwait
|
|
97
|
+
if (!topLevelAwait && failFastOnFeatureDetection) {
|
|
98
|
+
return
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
const pluginRequiredNamesFromGroupInfo = async (
|
|
103
|
+
groupInfo,
|
|
104
|
+
{ featuresReport, coverageHandledFromOutside },
|
|
105
|
+
) => {
|
|
106
|
+
const { pluginRequiredNameArray } = groupInfo
|
|
107
|
+
const requiredPluginNames = pluginRequiredNameArray.slice()
|
|
108
|
+
const markPluginAsSupported = (name) => {
|
|
109
|
+
const index = requiredPluginNames.indexOf(name)
|
|
110
|
+
if (index > -1) {
|
|
111
|
+
requiredPluginNames.splice(index, 1)
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
// When instrumentation CAN be handed by playwright
|
|
116
|
+
// https://playwright.dev/docs/api/class-chromiumcoverage#chromiumcoveragestartjscoverageoptions
|
|
117
|
+
// coverageHandledFromOutside is true and "transform-instrument" becomes non mandatory
|
|
118
|
+
if (coverageHandledFromOutside) {
|
|
119
|
+
markPluginAsSupported("transform-instrument")
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
if (pluginRequiredNameArray.includes("transform-import-assertions")) {
|
|
123
|
+
const jsonImportAssertions = await supportsJsonImportAssertions()
|
|
124
|
+
featuresReport.jsonImportAssertions = jsonImportAssertions
|
|
125
|
+
|
|
126
|
+
const cssImportAssertions = await supportsCssImportAssertions()
|
|
127
|
+
featuresReport.cssImportAssertions = cssImportAssertions
|
|
128
|
+
|
|
129
|
+
if (jsonImportAssertions && cssImportAssertions) {
|
|
130
|
+
markPluginAsSupported("transform-import-assertions")
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
if (pluginRequiredNameArray.includes("new-stylesheet-as-jsenv-import")) {
|
|
135
|
+
const newStylesheet = supportsNewStylesheet()
|
|
136
|
+
featuresReport.newStylesheet = newStylesheet
|
|
137
|
+
markPluginAsSupported("new-stylesheet-as-jsenv-import")
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
return requiredPluginNames
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
const supportsNewStylesheet = () => {
|
|
144
|
+
try {
|
|
145
|
+
// eslint-disable-next-line no-new
|
|
146
|
+
new CSSStyleSheet()
|
|
147
|
+
return true
|
|
148
|
+
} catch (e) {
|
|
149
|
+
return false
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
const supportsImportmap = async ({ remote = true } = {}) => {
|
|
154
|
+
const specifier = asBase64Url(`export default false`)
|
|
155
|
+
|
|
156
|
+
const importMap = {
|
|
157
|
+
imports: {
|
|
158
|
+
[specifier]: asBase64Url(`export default true`),
|
|
159
|
+
},
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
const importmapScript = document.createElement("script")
|
|
163
|
+
const importmapString = JSON.stringify(importMap, null, " ")
|
|
164
|
+
importmapScript.type = "importmap"
|
|
165
|
+
if (remote) {
|
|
166
|
+
importmapScript.src = `data:application/json;base64,${window.btoa(
|
|
167
|
+
importmapString,
|
|
168
|
+
)}`
|
|
169
|
+
} else {
|
|
170
|
+
importmapScript.textContent = importmapString
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
document.body.appendChild(importmapScript)
|
|
174
|
+
|
|
175
|
+
const scriptModule = document.createElement("script")
|
|
176
|
+
scriptModule.type = "module"
|
|
177
|
+
scriptModule.src = asBase64Url(
|
|
178
|
+
`import supported from "${specifier}"; window.__importmap_supported = supported`,
|
|
179
|
+
)
|
|
180
|
+
|
|
181
|
+
return new Promise((resolve, reject) => {
|
|
182
|
+
scriptModule.onload = () => {
|
|
183
|
+
const supported = window.__importmap_supported
|
|
184
|
+
delete window.__importmap_supported
|
|
185
|
+
document.body.removeChild(scriptModule)
|
|
186
|
+
document.body.removeChild(importmapScript)
|
|
187
|
+
resolve(supported)
|
|
188
|
+
}
|
|
189
|
+
scriptModule.onerror = () => {
|
|
190
|
+
document.body.removeChild(scriptModule)
|
|
191
|
+
document.body.removeChild(importmapScript)
|
|
192
|
+
reject()
|
|
193
|
+
}
|
|
194
|
+
document.body.appendChild(scriptModule)
|
|
195
|
+
})
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
const supportsDynamicImport = async () => {
|
|
199
|
+
const moduleSource = asBase64Url(`export default 42`)
|
|
200
|
+
try {
|
|
201
|
+
const namespace = await import(moduleSource)
|
|
202
|
+
return namespace.default === 42
|
|
203
|
+
} catch (e) {
|
|
204
|
+
return false
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
const supportsTopLevelAwait = async () => {
|
|
209
|
+
const moduleSource = asBase64Url(`export default await Promise.resolve(42)`)
|
|
210
|
+
try {
|
|
211
|
+
const namespace = await import(moduleSource)
|
|
212
|
+
return namespace.default === 42
|
|
213
|
+
} catch (e) {
|
|
214
|
+
return false
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
const supportsJsonImportAssertions = async () => {
|
|
219
|
+
const jsonBase64Url = asBase64Url("42", "application/json")
|
|
220
|
+
const moduleSource = asBase64Url(
|
|
221
|
+
`export { default } from "${jsonBase64Url}" assert { type: "json" }`,
|
|
222
|
+
)
|
|
223
|
+
try {
|
|
224
|
+
const namespace = await import(moduleSource)
|
|
225
|
+
return namespace.default === 42
|
|
226
|
+
} catch (e) {
|
|
227
|
+
return false
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
const supportsCssImportAssertions = async () => {
|
|
232
|
+
const cssBase64Url = asBase64Url("p { color: red; }", "text/css")
|
|
233
|
+
const moduleSource = asBase64Url(
|
|
234
|
+
`export { default } from "${cssBase64Url}" assert { type: "css" }`,
|
|
235
|
+
)
|
|
236
|
+
try {
|
|
237
|
+
const namespace = await import(moduleSource)
|
|
238
|
+
return namespace.default instanceof CSSStyleSheet
|
|
239
|
+
} catch (e) {
|
|
240
|
+
return false
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
const asBase64Url = (text, mimeType = "application/javascript") => {
|
|
245
|
+
return `data:${mimeType};base64,${window.btoa(text)}`
|
|
246
|
+
}
|