@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.
Files changed (133) hide show
  1. package/dist/jsenv_browser_system.js +46 -39
  2. package/dist/jsenv_browser_system.js.map +14 -14
  3. package/dist/jsenv_compile_proxy.js.map +6 -6
  4. package/dist/jsenv_exploring_index.js.map +5 -5
  5. package/dist/jsenv_exploring_redirector.js.map +12 -12
  6. package/dist/jsenv_toolbar.js.map +7 -7
  7. package/dist/jsenv_toolbar_injector.js.map +5 -5
  8. package/helpers/babel/.eslintrc.cjs +24 -24
  9. package/helpers/babel/AsyncGenerator/AsyncGenerator.js +81 -81
  10. package/helpers/babel/AwaitValue/AwaitValue.js +3 -3
  11. package/helpers/babel/applyDecoratorDescriptor/applyDecoratorDescriptor.js +33 -33
  12. package/helpers/babel/arrayLikeToArray/arrayLikeToArray.js +7 -7
  13. package/helpers/babel/arrayWithHoles/arrayWithHoles.js +4 -4
  14. package/helpers/babel/arrayWithoutHoles/arrayWithoutHoles.js +6 -6
  15. package/helpers/babel/assertThisInitialized/assertThisInitialized.js +7 -7
  16. package/helpers/babel/asyncGeneratorDelegate/asyncGeneratorDelegate.js +40 -40
  17. package/helpers/babel/asyncIterator/asyncIterator.js +12 -12
  18. package/helpers/babel/asyncToGenerator/asyncToGenerator.js +34 -34
  19. package/helpers/babel/awaitAsyncGenerator/awaitAsyncGenerator.js +5 -5
  20. package/helpers/babel/classApplyDescriptorDestructureSet/classApplyDescriptorDestructureSet.js +20 -20
  21. package/helpers/babel/classApplyDescriptorGet/classApplyDescriptorGet.js +6 -6
  22. package/helpers/babel/classApplyDescriptorSet/classApplyDescriptorSet.js +13 -13
  23. package/helpers/babel/classCallCheck/classCallCheck.js +5 -5
  24. package/helpers/babel/classCheckPrivateStaticAccess/classCheckPrivateStaticAccess.js +5 -5
  25. package/helpers/babel/classCheckPrivateStaticFieldDescriptor/classCheckPrivateStaticFieldDescriptor.js +6 -6
  26. package/helpers/babel/classExtractFieldDescriptor/classExtractFieldDescriptor.js +7 -7
  27. package/helpers/babel/classNameTDZError/classNameTDZError.js +4 -4
  28. package/helpers/babel/classPrivateFieldDestructureSet/classPrivateFieldDestructureSet.js +7 -7
  29. package/helpers/babel/classPrivateFieldGet/classPrivateFieldGet.js +7 -7
  30. package/helpers/babel/classPrivateFieldLooseBase/classPrivateFieldLooseBase.js +6 -6
  31. package/helpers/babel/classPrivateFieldLooseKey/classPrivateFieldLooseKey.js +5 -5
  32. package/helpers/babel/classPrivateFieldSet/classPrivateFieldSet.js +8 -8
  33. package/helpers/babel/classPrivateMethodGet/classPrivateMethodGet.js +6 -6
  34. package/helpers/babel/classPrivateMethodSet/classPrivateMethodSet.js +3 -3
  35. package/helpers/babel/classStaticPrivateFieldSpecGet/classStaticPrivateFieldSpecGet.js +9 -9
  36. package/helpers/babel/classStaticPrivateFieldSpecSet/classStaticPrivateFieldSpecSet.js +15 -15
  37. package/helpers/babel/classStaticPrivateMethodGet/classStaticPrivateMethodGet.js +6 -6
  38. package/helpers/babel/classStaticPrivateMethodSet/classStaticPrivateMethodSet.js +3 -3
  39. package/helpers/babel/construct/construct.js +16 -16
  40. package/helpers/babel/createClass/createClass.js +15 -15
  41. package/helpers/babel/createForOfIteratorHelper/createForOfIteratorHelper.js +60 -60
  42. package/helpers/babel/createForOfIteratorHelperLoose/createForOfIteratorHelperLoose.js +23 -23
  43. package/helpers/babel/createRawReactElement/createRawReactElement.js +50 -50
  44. package/helpers/babel/createSuper/createSuper.js +22 -22
  45. package/helpers/babel/decorate/decorate.js +403 -403
  46. package/helpers/babel/defaults/defaults.js +11 -11
  47. package/helpers/babel/defineEnumerableProperties/defineEnumerableProperties.js +23 -23
  48. package/helpers/babel/defineProperty/defineProperty.js +18 -18
  49. package/helpers/babel/extends/extends.js +14 -14
  50. package/helpers/babel/get/get.js +13 -13
  51. package/helpers/babel/getPrototypeOf/getPrototypeOf.js +4 -4
  52. package/helpers/babel/inherits/inherits.js +15 -15
  53. package/helpers/babel/inheritsLoose/inheritsLoose.js +7 -7
  54. package/helpers/babel/initializerDefineProperty/initializerDefineProperty.js +10 -10
  55. package/helpers/babel/initializerWarningHelper/initializerWarningHelper.js +6 -6
  56. package/helpers/babel/instanceof/instanceof.js +6 -6
  57. package/helpers/babel/interopRequireDefault/interopRequireDefault.js +3 -3
  58. package/helpers/babel/interopRequireWildcard/interopRequireWildcard.js +37 -37
  59. package/helpers/babel/isNativeFunction/isNativeFunction.js +4 -4
  60. package/helpers/babel/isNativeReflectConstruct/isNativeReflectConstruct.js +21 -21
  61. package/helpers/babel/iterableToArray/iterableToArray.js +7 -7
  62. package/helpers/babel/iterableToArrayLimit/iterableToArrayLimit.js +36 -36
  63. package/helpers/babel/iterableToArrayLimitLoose/iterableToArrayLimitLoose.js +10 -10
  64. package/helpers/babel/jsx/jsx.js +45 -45
  65. package/helpers/babel/maybeArrayLike/maybeArrayLike.js +10 -10
  66. package/helpers/babel/newArrowCheck/newArrowCheck.js +5 -5
  67. package/helpers/babel/nonIterableRest/nonIterableRest.js +5 -5
  68. package/helpers/babel/nonIterableSpread/nonIterableSpread.js +5 -5
  69. package/helpers/babel/objectDestructuringEmpty/objectDestructuringEmpty.js +3 -3
  70. package/helpers/babel/objectSpread/objectSpread.js +23 -23
  71. package/helpers/babel/objectSpread2/objectSpread2.js +33 -33
  72. package/helpers/babel/objectWithoutProperties/objectWithoutProperties.js +19 -19
  73. package/helpers/babel/objectWithoutPropertiesLoose/objectWithoutPropertiesLoose.js +13 -13
  74. package/helpers/babel/possibleConstructorReturn/possibleConstructorReturn.js +10 -10
  75. package/helpers/babel/readOnlyError/readOnlyError.js +4 -4
  76. package/helpers/babel/readme.md +9 -9
  77. package/helpers/babel/set/set.js +44 -44
  78. package/helpers/babel/setPrototypeOf/setPrototypeOf.js +6 -6
  79. package/helpers/babel/skipFirstGeneratorNext/skipFirstGeneratorNext.js +8 -8
  80. package/helpers/babel/slicedToArray/slicedToArray.js +10 -10
  81. package/helpers/babel/slicedToArrayLoose/slicedToArrayLoose.js +13 -13
  82. package/helpers/babel/superPropBase/superPropBase.js +10 -10
  83. package/helpers/babel/taggedTemplateLiteral/taggedTemplateLiteral.js +10 -10
  84. package/helpers/babel/taggedTemplateLiteralLoose/taggedTemplateLiteralLoose.js +7 -7
  85. package/helpers/babel/tdz/tdz.js +4 -4
  86. package/helpers/babel/temporalRef/temporalRef.js +6 -6
  87. package/helpers/babel/temporalUndefined/temporalUndefined.js +3 -3
  88. package/helpers/babel/toArray/toArray.js +10 -10
  89. package/helpers/babel/toConsumableArray/toConsumableArray.js +10 -10
  90. package/helpers/babel/toPrimitive/toPrimitive.js +10 -10
  91. package/helpers/babel/toPropertyKey/toPropertyKey.js +6 -6
  92. package/helpers/babel/typeof/typeof.js +14 -14
  93. package/helpers/babel/unsupportedIterableToArray/unsupportedIterableToArray.js +12 -12
  94. package/helpers/babel/wrapAsyncGenerator/wrapAsyncGenerator.js +8 -8
  95. package/helpers/babel/wrapNativeSuper/wrapNativeSuper.js +30 -30
  96. package/helpers/babel/wrapRegExp/wrapRegExp.js +63 -63
  97. package/helpers/babel/writeOnlyError/writeOnlyError.js +4 -4
  98. package/helpers/regenerator-runtime/regenerator-runtime.js +748 -748
  99. package/{LICENSE → license} +21 -21
  100. package/package.json +2 -2
  101. package/src/buildProject.js +300 -300
  102. package/src/execute.js +184 -184
  103. package/src/internal/browser-launcher/jsenv-browser-system.js +203 -199
  104. package/src/internal/building/buildUsingRollup.js +2 -10
  105. package/src/internal/compiling/babel_plugin_import_assertions.js +121 -121
  106. package/src/internal/compiling/babel_plugin_import_metadata.js +22 -22
  107. package/src/internal/compiling/babel_plugin_import_visitor.js +84 -84
  108. package/src/internal/compiling/compile-directory/getOrGenerateCompiledFile.js +268 -268
  109. package/src/internal/compiling/compile-directory/updateMeta.js +154 -154
  110. package/src/internal/compiling/compile-directory/validateCache.js +265 -265
  111. package/src/internal/compiling/compileFile.js +233 -224
  112. package/src/internal/compiling/compileHtml.js +550 -550
  113. package/src/internal/compiling/createCompiledFileService.js +291 -291
  114. package/src/internal/compiling/html_source_file_service.js +403 -404
  115. package/src/internal/compiling/js-compilation-service/jsenvTransform.js +272 -270
  116. package/src/internal/compiling/jsenvCompilerForHtml.js +374 -308
  117. package/src/internal/compiling/jsenvCompilerForJavaScript.js +2 -0
  118. package/src/internal/compiling/startCompileServer.js +1086 -1048
  119. package/src/internal/compiling/transformResultToCompilationResult.js +220 -220
  120. package/src/internal/executing/coverage/babel_plugin_instrument.js +90 -90
  121. package/src/internal/executing/coverage/reportToCoverage.js +193 -187
  122. package/src/internal/executing/executePlan.js +183 -183
  123. package/src/internal/executing/launchAndExecute.js +458 -458
  124. package/src/internal/generateGroupMap/featuresCompatMap.js +29 -0
  125. package/src/internal/generateGroupMap/jsenvBabelPluginCompatMap.js +1 -8
  126. package/src/internal/runtime/createBrowserRuntime/scanBrowserRuntimeFeatures.js +246 -246
  127. package/src/internal/runtime/createNodeRuntime/scanNodeRuntimeFeatures.js +112 -112
  128. package/src/internal/runtime/s.js +727 -727
  129. package/src/internal/toolbar/jsenv-logo.svg +144 -144
  130. package/src/internal/toolbar/toolbar.main.css +196 -196
  131. package/src/internal/toolbar/toolbar.main.js +227 -227
  132. package/src/internal/url_conversion.js +317 -317
  133. 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
- // jsenvBabelPluginCompatMap["transform-import-assertion-json"] = {
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
+ }