@jsenv/core 21.1.0 → 22.0.3

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 (30) hide show
  1. package/dist/.DS_Store +0 -0
  2. package/dist/jsenv_browser_system.js.map +16 -16
  3. package/{LICENSE → license} +0 -0
  4. package/main.js +0 -1
  5. package/package.json +50 -45
  6. package/readme.md +74 -51
  7. package/src/buildProject.js +1 -2
  8. package/src/commonJsToJavaScriptModule.js +88 -39
  9. package/src/executeTestPlan.js +2 -0
  10. package/src/internal/building/createJsenvRollupPlugin.js +2 -2
  11. package/src/internal/compiling/babel_plugins.js +44 -0
  12. package/src/internal/compiling/createCompiledFileService.js +14 -9
  13. package/src/internal/compiling/html_source_file_service.js +1 -1
  14. package/src/internal/compiling/js-compilation-service/babelHelper.js +10 -2
  15. package/src/internal/compiling/js-compilation-service/jsenvTransform.js +39 -40
  16. package/src/internal/compiling/js-compilation-service/transformBabelHelperToImportBabelPlugin.js +3 -0
  17. package/src/internal/compiling/jsenvCompilerForImportmap.js +2 -1
  18. package/src/internal/compiling/load_babel_plugin_map_from_file.js +49 -0
  19. package/src/internal/compiling/rollup_plugin_commonjs_named_exports.js +186 -0
  20. package/src/internal/compiling/startCompileServer.js +79 -4
  21. package/src/internal/executing/coverage/relativeUrlToEmptyCoverage.js +21 -13
  22. package/src/internal/executing/executePlan.js +8 -10
  23. package/src/internal/generateGroupMap/generateGroupMap.js +0 -12
  24. package/src/internal/generateGroupMap/jsenvBabelPluginCompatMap.js +3 -0
  25. package/src/internal/import-resolution/import-resolver-importmap.js +1 -1
  26. package/src/internal/import-resolution/import-resolver-node.js +1 -1
  27. package/src/internal/runtime/createBrowserRuntime/createBrowserRuntime.js +1 -1
  28. package/src/internal/runtime/createNodeRuntime/createNodeSystem.js +6 -2
  29. package/src/internal/minimalBabelPluginArray.js +0 -16
  30. package/src/jsenvBabelPluginMap.js +0 -76
package/dist/.DS_Store ADDED
Binary file
@@ -18,17 +18,17 @@
18
18
  "../node_modules/@jsenv/uneval/src/internal/escapeString.js",
19
19
  "../node_modules/@jsenv/uneval/src/uneval.js",
20
20
  "../src/internal/unevalException.js",
21
- "../node_modules/@jsenv/import-map/src/internal/assertImportMap.js",
22
- "../node_modules/@jsenv/import-map/src/internal/hasScheme.js",
23
- "../node_modules/@jsenv/import-map/src/internal/urlToScheme.js",
24
- "../node_modules/@jsenv/import-map/src/internal/urlToPathname.js",
25
- "../node_modules/@jsenv/import-map/src/internal/urlToOrigin.js",
26
- "../node_modules/@jsenv/import-map/src/internal/pathnameToParentPathname.js",
27
- "../node_modules/@jsenv/import-map/src/resolveUrl.js",
28
- "../node_modules/@jsenv/import-map/src/internal/tryUrlResolution.js",
29
- "../node_modules/@jsenv/import-map/src/resolveSpecifier.js",
30
- "../node_modules/@jsenv/import-map/src/sortImportMap.js",
31
- "../node_modules/@jsenv/import-map/src/normalizeImportMap.js",
21
+ "../node_modules/@jsenv/importmap/src/internal/assertImportMap.js",
22
+ "../node_modules/@jsenv/importmap/src/internal/hasScheme.js",
23
+ "../node_modules/@jsenv/importmap/src/internal/urlToScheme.js",
24
+ "../node_modules/@jsenv/importmap/src/internal/urlToPathname.js",
25
+ "../node_modules/@jsenv/importmap/src/internal/urlToOrigin.js",
26
+ "../node_modules/@jsenv/importmap/src/internal/pathnameToParentPathname.js",
27
+ "../node_modules/@jsenv/importmap/src/resolveUrl.js",
28
+ "../node_modules/@jsenv/importmap/src/internal/tryUrlResolution.js",
29
+ "../node_modules/@jsenv/importmap/src/resolveSpecifier.js",
30
+ "../node_modules/@jsenv/importmap/src/sortImportMap.js",
31
+ "../node_modules/@jsenv/importmap/src/normalizeImportMap.js",
32
32
  "../src/internal/memoize.js",
33
33
  "../helpers/babel/objectWithoutPropertiesLoose/objectWithoutPropertiesLoose.js",
34
34
  "../helpers/babel/objectWithoutProperties/objectWithoutProperties.js",
@@ -36,9 +36,9 @@
36
36
  "../node_modules/@jsenv/logger/src/createDetailedMessage.js",
37
37
  "../src/internal/browser-utils/fetchUsingXHR.js",
38
38
  "../src/internal/browser-utils/fetch-browser.js",
39
- "../node_modules/@jsenv/import-map/src/internal/pathnameToExtension.js",
40
- "../node_modules/@jsenv/import-map/src/applyImportMap.js",
41
- "../node_modules/@jsenv/import-map/src/resolveImport.js",
39
+ "../node_modules/@jsenv/importmap/src/internal/pathnameToExtension.js",
40
+ "../node_modules/@jsenv/importmap/src/applyImportMap.js",
41
+ "../node_modules/@jsenv/importmap/src/resolveImport.js",
42
42
  "../src/internal/runtime/module-registration.js",
43
43
  "../src/internal/import-resolution/default-extension.js",
44
44
  "../src/internal/import-resolution/import-resolver-importmap.js",
@@ -102,7 +102,7 @@
102
102
  "import { urlToPathname } from \"./internal/urlToPathname.js\"\nimport { pathnameToExtension } from \"./internal/pathnameToExtension.js\"\nimport { resolveUrl } from \"./resolveUrl.js\"\nimport { applyImportMap } from \"./applyImportMap.js\"\n\nexport const resolveImport = ({\n specifier,\n importer,\n importMap,\n defaultExtension = true,\n createBareSpecifierError,\n onImportMapping = () => {},\n}) => {\n return applyDefaultExtension({\n url: importMap\n ? applyImportMap({\n importMap,\n specifier,\n importer,\n createBareSpecifierError,\n onImportMapping,\n })\n : resolveUrl(specifier, importer),\n importer,\n defaultExtension,\n })\n}\n\nconst applyDefaultExtension = ({ url, importer, defaultExtension }) => {\n if (urlToPathname(url).endsWith(\"/\")) {\n return url\n }\n\n if (typeof defaultExtension === \"string\") {\n const extension = pathnameToExtension(url)\n if (extension === \"\") {\n return `${url}${defaultExtension}`\n }\n return url\n }\n\n if (defaultExtension === true) {\n const extension = pathnameToExtension(url)\n if (extension === \"\" && importer) {\n const importerPathname = urlToPathname(importer)\n const importerExtension = pathnameToExtension(importerPathname)\n return `${url}${importerExtension}`\n }\n }\n return url\n}\n",
103
103
  "import { createDetailedMessage } from \"@jsenv/logger\"\n\nexport const fromFunctionReturningNamespace = (fn, data) => {\n return fromFunctionReturningRegisteredModule(() => {\n // should we compute the namespace here\n // or as it is done below, defer to execute ?\n // I think defer to execute is better\n return [\n [],\n (_export) => {\n return {\n execute: () => {\n const namespace = fn()\n _export(namespace)\n },\n }\n },\n ]\n }, data)\n}\n\nconst fromFunctionReturningRegisteredModule = (fn, data) => {\n try {\n return fn()\n } catch (error) {\n if (error.name === \"SyntaxError\") {\n throw new Error(\n createDetailedMessage(`Syntax error in module.`, {\n \"syntax error stack\": error.stack,\n ...getModuleDetails(data),\n }),\n )\n }\n throw new Error(\n createDetailedMessage(`Module instantiation error.`, {\n [\"instantiation error stack\"]: error.stack,\n ...getModuleDetails(data),\n }),\n )\n }\n}\n\nexport const fromUrl = async ({\n url,\n importerUrl,\n fetchSource,\n instantiateJavaScript,\n compileServerOrigin,\n compileDirectoryRelativeUrl,\n}) => {\n let moduleResponse\n try {\n moduleResponse = await fetchSource(url, {\n importerUrl,\n })\n\n if (moduleResponse.status === 404) {\n throw new Error(\n createDetailedMessage(\n `Module file cannot be found.`,\n getModuleDetails({\n url,\n importerUrl,\n compileServerOrigin,\n compileDirectoryRelativeUrl,\n notFound: true,\n }),\n ),\n )\n }\n } catch (e) {\n e.code = \"NETWORK_FAILURE\"\n throw e\n }\n\n const contentType = moduleResponse.headers[\"content-type\"] || \"\"\n\n if (moduleResponse.status === 500 && contentType === \"application/json\") {\n const bodyAsJson = await moduleResponse.json()\n if (\n bodyAsJson.message &&\n bodyAsJson.filename &&\n \"columnNumber\" in bodyAsJson\n ) {\n const error = new Error(\n createDetailedMessage(`Module file cannot be parsed.`, {\n [\"parsing error message\"]: bodyAsJson.message,\n ...getModuleDetails({\n url,\n importerUrl,\n compileServerOrigin,\n compileDirectoryRelativeUrl,\n }),\n }),\n )\n error.parsingError = bodyAsJson\n throw error\n }\n }\n\n if (moduleResponse.status < 200 || moduleResponse.status >= 300) {\n throw new Error(\n createDetailedMessage(`Module file response status is unexpected.`, {\n [\"status\"]: moduleResponse.status,\n [\"allowed status\"]: \"200 to 299\",\n [\"statusText\"]: moduleResponse.statusText,\n ...getModuleDetails({\n url,\n importerUrl,\n compileServerOrigin,\n compileDirectoryRelativeUrl,\n }),\n }),\n )\n }\n\n // don't forget to keep in sync with loadModule in createJsenvRollupPlugin.js\n if (\n contentType === \"application/javascript\" ||\n contentType === \"text/javascript\"\n ) {\n const bodyAsText = await moduleResponse.text()\n return fromFunctionReturningRegisteredModule(\n () => instantiateJavaScript(bodyAsText, moduleResponse.url),\n {\n url: moduleResponse.url,\n importerUrl,\n compileServerOrigin,\n compileDirectoryRelativeUrl,\n },\n )\n }\n\n if (contentType === \"application/json\" || contentType.endsWith(\"+json\")) {\n const bodyAsJson = await moduleResponse.json()\n return fromFunctionReturningNamespace(\n () => {\n return {\n default: bodyAsJson,\n }\n },\n {\n url: moduleResponse.url,\n importerUrl,\n compileServerOrigin,\n compileDirectoryRelativeUrl,\n },\n )\n }\n\n if (contentType) {\n console.warn(\n createDetailedMessage(`Ressource content-type is unusual`, {\n \"content-type\": contentType,\n \"allowed content-type\": [\"application/javascript\", \"application/json\"],\n ...getModuleDetails({\n url,\n importerUrl,\n compileServerOrigin,\n compileDirectoryRelativeUrl,\n }),\n \"suggestion\": `Prefer import.meta.url as documented in https://github.com/jsenv/jsenv-core/blob/master/docs/building/readme.md#How-to-reference-js-assets`,\n }),\n )\n } else {\n console.warn(`Ressource content-type is missing`, {\n \"allowed content-type\": [\"application/javascript\", \"application/json\"],\n ...getModuleDetails({\n url,\n importerUrl,\n compileServerOrigin,\n compileDirectoryRelativeUrl,\n }),\n })\n }\n\n return fromFunctionReturningNamespace(\n () => {\n return {\n default: moduleResponse.url,\n }\n },\n {\n url: moduleResponse.url,\n importerUrl,\n compileServerOrigin,\n compileDirectoryRelativeUrl,\n },\n )\n}\n// const textToBase64 =\n// typeof window === \"object\"\n// ? (text) => window.btoa(window.unescape(window.encodeURIComponent(text)))\n// : (text) => Buffer.from(text, \"utf8\").toString(\"base64\")\n\nconst getModuleDetails = ({\n url,\n importerUrl,\n compileServerOrigin,\n compileDirectoryRelativeUrl,\n notFound = false,\n}) => {\n const relativeUrl = tryToFindProjectRelativeUrl(url, {\n compileServerOrigin,\n compileDirectoryRelativeUrl,\n })\n\n const importerRelativeUrl = tryToFindProjectRelativeUrl(importerUrl, {\n compileServerOrigin,\n compileDirectoryRelativeUrl,\n })\n\n const details = notFound\n ? {\n ...(importerUrl\n ? { [\"import declared in\"]: importerRelativeUrl || importerUrl }\n : {}),\n ...(relativeUrl ? { file: relativeUrl } : {}),\n [\"file url\"]: url,\n }\n : {\n ...(relativeUrl ? { file: relativeUrl } : {}),\n [\"file url\"]: url,\n ...(importerUrl\n ? { [\"imported by\"]: importerRelativeUrl || importerUrl }\n : {}),\n }\n\n return details\n}\n\nexport const tryToFindProjectRelativeUrl = (\n url,\n { compileServerOrigin, compileDirectoryRelativeUrl },\n) => {\n if (!url) {\n return null\n }\n\n if (!url.startsWith(`${compileServerOrigin}/`)) {\n return null\n }\n\n if (url === compileServerOrigin) {\n return null\n }\n\n const afterOrigin = url.slice(`${compileServerOrigin}/`.length)\n if (!afterOrigin.startsWith(compileDirectoryRelativeUrl)) {\n return null\n }\n\n const afterCompileDirectory = afterOrigin.slice(\n compileDirectoryRelativeUrl.length,\n )\n return afterCompileDirectory\n}\n",
104
104
  "export const applyDefaultExtension = (specifier, importer) => {\n if (!importer) {\n return specifier\n }\n\n const importerExtension = urlToExtension(importer)\n const fakeUrl = new URL(specifier, importer).href\n const specifierExtension = urlToExtension(fakeUrl)\n if (specifierExtension !== \"\") {\n return specifier\n }\n\n // I guess typescript still expect default extension to be .ts\n // in a tsx file.\n if (importerExtension === \"tsx\") {\n return `${specifier}.ts`\n }\n\n // extension magic\n return `${specifier}${importerExtension}`\n}\n\nconst urlToExtension = (url) => {\n return pathnameToExtension(urlToPathname(url))\n}\n\nconst urlToPathname = (url) => new URL(url).pathname\n\nconst pathnameToExtension = (pathname) => {\n const slashLastIndex = pathname.lastIndexOf(\"/\")\n if (slashLastIndex !== -1) {\n pathname = pathname.slice(slashLastIndex + 1)\n }\n\n const dotLastIndex = pathname.lastIndexOf(\".\")\n if (dotLastIndex === -1) return \"\"\n // if (dotLastIndex === pathname.length - 1) return \"\"\n const extension = pathname.slice(dotLastIndex)\n return extension\n}\n",
105
- "import { createDetailedMessage } from \"@jsenv/logger\"\nimport { resolveImport } from \"@jsenv/import-map/src/resolveImport.js\"\n\nimport { tryToFindProjectRelativeUrl } from \"@jsenv/core/src/internal/runtime/module-registration.js\"\n\nimport { applyDefaultExtension } from \"./default-extension.js\"\n\nexport const createImportResolverForImportmap = async ({\n // projectDirectoryUrl,\n compileServerOrigin,\n compileDirectoryRelativeUrl,\n importMap,\n importMapUrl,\n importDefaultExtension,\n onBareSpecifierError = () => {},\n}) => {\n const _resolveImport = (specifier, importer) => {\n if (importDefaultExtension) {\n specifier = applyDefaultExtension(specifier, importer)\n }\n return resolveImport({\n specifier,\n importer,\n importMap,\n createBareSpecifierError: ({ specifier, importer }) => {\n const bareSpecifierError = createBareSpecifierError({\n specifier,\n importer:\n tryToFindProjectRelativeUrl(importer, {\n compileServerOrigin,\n compileDirectoryRelativeUrl,\n }) || importer,\n importMapUrl:\n tryToFindProjectRelativeUrl(importMapUrl, {\n compileServerOrigin,\n compileDirectoryRelativeUrl,\n }) || importMapUrl,\n importMap,\n })\n onBareSpecifierError(bareSpecifierError)\n return bareSpecifierError\n },\n })\n }\n\n return { resolveImport: _resolveImport }\n}\n\nconst createBareSpecifierError = ({ specifier, importer, importMapUrl }) => {\n const detailedMessage = createDetailedMessage(\"Unmapped bare specifier.\", {\n specifier,\n importer,\n ...(importMapUrl\n ? {\n \"how to fix\": `Add a mapping for \"${specifier}\" into the importmap file at ${importMapUrl}`,\n }\n : {\n \"how to fix\": `Add an importmap with a mapping for \"${specifier}\"`,\n \"suggestion\": `Generate importmap using https://github.com/jsenv/importmap-node-module`,\n }),\n })\n\n return new Error(detailedMessage)\n}\n",
105
+ "import { createDetailedMessage } from \"@jsenv/logger\"\nimport { resolveImport } from \"@jsenv/importmap/src/resolveImport.js\"\n\nimport { tryToFindProjectRelativeUrl } from \"@jsenv/core/src/internal/runtime/module-registration.js\"\n\nimport { applyDefaultExtension } from \"./default-extension.js\"\n\nexport const createImportResolverForImportmap = async ({\n // projectDirectoryUrl,\n compileServerOrigin,\n compileDirectoryRelativeUrl,\n importMap,\n importMapUrl,\n importDefaultExtension,\n onBareSpecifierError = () => {},\n}) => {\n const _resolveImport = (specifier, importer) => {\n if (importDefaultExtension) {\n specifier = applyDefaultExtension(specifier, importer)\n }\n return resolveImport({\n specifier,\n importer,\n importMap,\n createBareSpecifierError: ({ specifier, importer }) => {\n const bareSpecifierError = createBareSpecifierError({\n specifier,\n importer:\n tryToFindProjectRelativeUrl(importer, {\n compileServerOrigin,\n compileDirectoryRelativeUrl,\n }) || importer,\n importMapUrl:\n tryToFindProjectRelativeUrl(importMapUrl, {\n compileServerOrigin,\n compileDirectoryRelativeUrl,\n }) || importMapUrl,\n importMap,\n })\n onBareSpecifierError(bareSpecifierError)\n return bareSpecifierError\n },\n })\n }\n\n return { resolveImport: _resolveImport }\n}\n\nconst createBareSpecifierError = ({ specifier, importer, importMapUrl }) => {\n const detailedMessage = createDetailedMessage(\"Unmapped bare specifier.\", {\n specifier,\n importer,\n ...(importMapUrl\n ? {\n \"how to fix\": `Add a mapping for \"${specifier}\" into the importmap file at ${importMapUrl}`,\n }\n : {\n \"how to fix\": `Add an importmap with a mapping for \"${specifier}\"`,\n \"suggestion\": `Generate importmap using https://github.com/jsenv/importmap-node-module`,\n }),\n })\n\n return new Error(detailedMessage)\n}\n",
106
106
  "/* eslint-env browser */\n\nconst { performance } = window\n\nexport const measureAsyncFnPerf = performance\n ? async (fn, name) => {\n const perfMarkStartName = `${name}_start`\n\n performance.mark(perfMarkStartName)\n try {\n const value = await fn()\n return value\n } finally {\n performance.measure(name, perfMarkStartName)\n }\n }\n : async (fn) => {\n return fn()\n }\n",
107
107
  "/*\n* SJS 6.10.3\n* Minimal SystemJS Build\n*/\n(function () {\n\n function errMsg(errCode, msg) {\n return (msg || \"\") + \" (SystemJS https://git.io/JvFET#\" + errCode + \")\";\n }\n\n var hasSymbol = typeof Symbol !== 'undefined';\n var hasSelf = typeof self !== 'undefined';\n var hasDocument = typeof document !== 'undefined';\n\n var envGlobal = hasSelf ? self : global;\n\n var baseUrl;\n\n if (hasDocument) {\n var baseEl = document.querySelector('base[href]');\n if (baseEl)\n baseUrl = baseEl.href;\n }\n\n if (!baseUrl && typeof location !== 'undefined') {\n baseUrl = location.href.split('#')[0].split('?')[0];\n var lastSepIndex = baseUrl.lastIndexOf('/');\n if (lastSepIndex !== -1)\n baseUrl = baseUrl.slice(0, lastSepIndex + 1);\n }\n\n var backslashRegEx = /\\\\/g;\n function resolveIfNotPlainOrUrl (relUrl, parentUrl) {\n if (relUrl.indexOf('\\\\') !== -1)\n relUrl = relUrl.replace(backslashRegEx, '/');\n // protocol-relative\n if (relUrl[0] === '/' && relUrl[1] === '/') {\n return parentUrl.slice(0, parentUrl.indexOf(':') + 1) + relUrl;\n }\n // relative-url\n else if (relUrl[0] === '.' && (relUrl[1] === '/' || relUrl[1] === '.' && (relUrl[2] === '/' || relUrl.length === 2 && (relUrl += '/')) ||\n relUrl.length === 1 && (relUrl += '/')) ||\n relUrl[0] === '/') {\n var parentProtocol = parentUrl.slice(0, parentUrl.indexOf(':') + 1);\n // Disabled, but these cases will give inconsistent results for deep backtracking\n //if (parentUrl[parentProtocol.length] !== '/')\n // throw Error('Cannot resolve');\n // read pathname from parent URL\n // pathname taken to be part after leading \"/\"\n var pathname;\n if (parentUrl[parentProtocol.length + 1] === '/') {\n // resolving to a :// so we need to read out the auth and host\n if (parentProtocol !== 'file:') {\n pathname = parentUrl.slice(parentProtocol.length + 2);\n pathname = pathname.slice(pathname.indexOf('/') + 1);\n }\n else {\n pathname = parentUrl.slice(8);\n }\n }\n else {\n // resolving to :/ so pathname is the /... part\n pathname = parentUrl.slice(parentProtocol.length + (parentUrl[parentProtocol.length] === '/'));\n }\n\n if (relUrl[0] === '/')\n return parentUrl.slice(0, parentUrl.length - pathname.length - 1) + relUrl;\n\n // join together and split for removal of .. and . segments\n // looping the string instead of anything fancy for perf reasons\n // '../../../../../z' resolved to 'x/y' is just 'z'\n var segmented = pathname.slice(0, pathname.lastIndexOf('/') + 1) + relUrl;\n\n var output = [];\n var segmentIndex = -1;\n for (var i = 0; i < segmented.length; i++) {\n // busy reading a segment - only terminate on '/'\n if (segmentIndex !== -1) {\n if (segmented[i] === '/') {\n output.push(segmented.slice(segmentIndex, i + 1));\n segmentIndex = -1;\n }\n }\n\n // new segment - check if it is relative\n else if (segmented[i] === '.') {\n // ../ segment\n if (segmented[i + 1] === '.' && (segmented[i + 2] === '/' || i + 2 === segmented.length)) {\n output.pop();\n i += 2;\n }\n // ./ segment\n else if (segmented[i + 1] === '/' || i + 1 === segmented.length) {\n i += 1;\n }\n else {\n // the start of a new segment as below\n segmentIndex = i;\n }\n }\n // it is the start of a new segment\n else {\n segmentIndex = i;\n }\n }\n // finish reading out the last segment\n if (segmentIndex !== -1)\n output.push(segmented.slice(segmentIndex));\n return parentUrl.slice(0, parentUrl.length - pathname.length) + output.join('');\n }\n }\n\n /*\n * Import maps implementation\n *\n * To make lookups fast we pre-resolve the entire import map\n * and then match based on backtracked hash lookups\n *\n */\n\n function resolveUrl (relUrl, parentUrl) {\n return resolveIfNotPlainOrUrl(relUrl, parentUrl) || (relUrl.indexOf(':') !== -1 ? relUrl : resolveIfNotPlainOrUrl('./' + relUrl, parentUrl));\n }\n\n function resolveAndComposePackages (packages, outPackages, baseUrl, parentMap, parentUrl) {\n for (var p in packages) {\n var resolvedLhs = resolveIfNotPlainOrUrl(p, baseUrl) || p;\n var rhs = packages[p];\n // package fallbacks not currently supported\n if (typeof rhs !== 'string')\n continue;\n var mapped = resolveImportMap(parentMap, resolveIfNotPlainOrUrl(rhs, baseUrl) || rhs, parentUrl);\n if (!mapped) {\n targetWarning('W1', p, rhs);\n }\n else\n outPackages[resolvedLhs] = mapped;\n }\n }\n\n function resolveAndComposeImportMap (json, baseUrl, outMap) {\n if (json.imports)\n resolveAndComposePackages(json.imports, outMap.imports, baseUrl, outMap, null);\n\n var u;\n for (u in json.scopes || {}) {\n var resolvedScope = resolveUrl(u, baseUrl);\n resolveAndComposePackages(json.scopes[u], outMap.scopes[resolvedScope] || (outMap.scopes[resolvedScope] = {}), baseUrl, outMap, resolvedScope);\n }\n\n for (u in json.depcache || {})\n outMap.depcache[resolveUrl(u, baseUrl)] = json.depcache[u];\n\n for (u in json.integrity || {})\n outMap.integrity[resolveUrl(u, baseUrl)] = json.integrity[u];\n }\n\n function getMatch (path, matchObj) {\n if (matchObj[path])\n return path;\n var sepIndex = path.length;\n do {\n var segment = path.slice(0, sepIndex + 1);\n if (segment in matchObj)\n return segment;\n } while ((sepIndex = path.lastIndexOf('/', sepIndex - 1)) !== -1)\n }\n\n function applyPackages (id, packages) {\n var pkgName = getMatch(id, packages);\n if (pkgName) {\n var pkg = packages[pkgName];\n if (pkg === null) return;\n if (id.length > pkgName.length && pkg[pkg.length - 1] !== '/') {\n targetWarning('W2', pkgName, pkg);\n }\n else\n return pkg + id.slice(pkgName.length);\n }\n }\n\n function targetWarning (code, match, target, msg) {\n console.warn(errMsg(code, [target, match].join(', ') ));\n }\n\n function resolveImportMap (importMap, resolvedOrPlain, parentUrl) {\n var scopes = importMap.scopes;\n var scopeUrl = parentUrl && getMatch(parentUrl, scopes);\n while (scopeUrl) {\n var packageResolution = applyPackages(resolvedOrPlain, scopes[scopeUrl]);\n if (packageResolution)\n return packageResolution;\n scopeUrl = getMatch(scopeUrl.slice(0, scopeUrl.lastIndexOf('/')), scopes);\n }\n return applyPackages(resolvedOrPlain, importMap.imports) || resolvedOrPlain.indexOf(':') !== -1 && resolvedOrPlain;\n }\n\n /*\n * SystemJS Core\n *\n * Provides\n * - System.import\n * - System.register support for\n * live bindings, function hoisting through circular references,\n * reexports, dynamic import, import.meta.url, top-level await\n * - System.getRegister to get the registration\n * - Symbol.toStringTag support in Module objects\n * - Hookable System.createContext to customize import.meta\n * - System.onload(err, id, deps) handler for tracing / hot-reloading\n *\n * Core comes with no System.prototype.resolve or\n * System.prototype.instantiate implementations\n */\n\n var toStringTag = hasSymbol && Symbol.toStringTag;\n var REGISTRY = hasSymbol ? Symbol() : '@';\n\n function SystemJS () {\n this[REGISTRY] = {};\n }\n\n var systemJSPrototype = SystemJS.prototype;\n\n systemJSPrototype.import = function (id, parentUrl) {\n var loader = this;\n return Promise.resolve(loader.prepareImport())\n .then(function() {\n return loader.resolve(id, parentUrl);\n })\n .then(function (id) {\n var load = getOrCreateLoad(loader, id);\n return load.C || topLevelLoad(loader, load);\n });\n };\n\n // Hookable createContext function -> allowing eg custom import meta\n systemJSPrototype.createContext = function (parentId) {\n var loader = this;\n return {\n url: parentId,\n resolve: function (id, parentUrl) {\n return Promise.resolve(loader.resolve(id, parentUrl || parentId));\n }\n };\n };\n function loadToId (load) {\n return load.id;\n }\n function triggerOnload (loader, load, err, isErrSource) {\n loader.onload(err, load.id, load.d && load.d.map(loadToId), !!isErrSource);\n if (err)\n throw err;\n }\n\n var lastRegister;\n systemJSPrototype.register = function (deps, declare) {\n lastRegister = [deps, declare];\n };\n\n /*\n * getRegister provides the last anonymous System.register call\n */\n systemJSPrototype.getRegister = function () {\n var _lastRegister = lastRegister;\n lastRegister = undefined;\n return _lastRegister;\n };\n\n function getOrCreateLoad (loader, id, firstParentUrl) {\n var load = loader[REGISTRY][id];\n if (load)\n return load;\n\n var importerSetters = [];\n var ns = Object.create(null);\n if (toStringTag)\n Object.defineProperty(ns, toStringTag, { value: 'Module' });\n\n var instantiatePromise = Promise.resolve()\n .then(function () {\n return loader.instantiate(id, firstParentUrl);\n })\n .then(function (registration) {\n if (!registration)\n throw Error(errMsg(2, id ));\n function _export (name, value) {\n // note if we have hoisted exports (including reexports)\n load.h = true;\n var changed = false;\n if (typeof name === 'string') {\n if (!(name in ns) || ns[name] !== value) {\n ns[name] = value;\n changed = true;\n }\n }\n else {\n for (var p in name) {\n var value = name[p];\n if (!(p in ns) || ns[p] !== value) {\n ns[p] = value;\n changed = true;\n }\n }\n\n if (name && name.__esModule) {\n ns.__esModule = name.__esModule;\n }\n }\n if (changed)\n for (var i = 0; i < importerSetters.length; i++) {\n var setter = importerSetters[i];\n if (setter) setter(ns);\n }\n return value;\n }\n var declared = registration[1](_export, registration[1].length === 2 ? {\n import: function (importId) {\n return loader.import(importId, id);\n },\n meta: loader.createContext(id)\n } : undefined);\n load.e = declared.execute || function () {};\n return [registration[0], declared.setters || []];\n }, function (err) {\n load.e = null;\n load.er = err;\n throw err;\n });\n\n var linkPromise = instantiatePromise\n .then(function (instantiation) {\n return Promise.all(instantiation[0].map(function (dep, i) {\n var setter = instantiation[1][i];\n return Promise.resolve(loader.resolve(dep, id))\n .then(function (depId) {\n var depLoad = getOrCreateLoad(loader, depId, id);\n // depLoad.I may be undefined for already-evaluated\n return Promise.resolve(depLoad.I)\n .then(function () {\n if (setter) {\n depLoad.i.push(setter);\n // only run early setters when there are hoisted exports of that module\n // the timing works here as pending hoisted export calls will trigger through importerSetters\n if (depLoad.h || !depLoad.I)\n setter(depLoad.n);\n }\n return depLoad;\n });\n });\n }))\n .then(function (depLoads) {\n load.d = depLoads;\n });\n });\n\n // Capital letter = a promise function\n return load = loader[REGISTRY][id] = {\n id: id,\n // importerSetters, the setters functions registered to this dependency\n // we retain this to add more later\n i: importerSetters,\n // module namespace object\n n: ns,\n\n // instantiate\n I: instantiatePromise,\n // link\n L: linkPromise,\n // whether it has hoisted exports\n h: false,\n\n // On instantiate completion we have populated:\n // dependency load records\n d: undefined,\n // execution function\n e: undefined,\n\n // On execution we have populated:\n // the execution error if any\n er: undefined,\n // in the case of TLA, the execution promise\n E: undefined,\n\n // On execution, L, I, E cleared\n\n // Promise for top-level completion\n C: undefined,\n\n // parent instantiator / executor\n p: undefined\n };\n }\n\n function instantiateAll (loader, load, parent, loaded) {\n if (!loaded[load.id]) {\n loaded[load.id] = true;\n // load.L may be undefined for already-instantiated\n return Promise.resolve(load.L)\n .then(function () {\n if (!load.p || load.p.e === null)\n load.p = parent;\n return Promise.all(load.d.map(function (dep) {\n return instantiateAll(loader, dep, parent, loaded);\n }));\n })\n .catch(function (err) {\n if (load.er)\n throw err;\n load.e = null;\n throw err;\n });\n }\n }\n\n function topLevelLoad (loader, load) {\n return load.C = instantiateAll(loader, load, load, {})\n .then(function () {\n return postOrderExec(loader, load, {});\n })\n .then(function () {\n return load.n;\n });\n }\n\n // the closest we can get to call(undefined)\n var nullContext = Object.freeze(Object.create(null));\n\n // returns a promise if and only if a top-level await subgraph\n // throws on sync errors\n function postOrderExec (loader, load, seen) {\n if (seen[load.id])\n return;\n seen[load.id] = true;\n\n if (!load.e) {\n if (load.er)\n throw load.er;\n if (load.E)\n return load.E;\n return;\n }\n\n // deps execute first, unless circular\n var depLoadPromises;\n load.d.forEach(function (depLoad) {\n try {\n var depLoadPromise = postOrderExec(loader, depLoad, seen);\n if (depLoadPromise)\n (depLoadPromises = depLoadPromises || []).push(depLoadPromise);\n }\n catch (err) {\n load.e = null;\n load.er = err;\n throw err;\n }\n });\n if (depLoadPromises)\n return Promise.all(depLoadPromises).then(doExec);\n\n return doExec();\n\n function doExec () {\n try {\n var execPromise = load.e.call(nullContext);\n if (execPromise) {\n execPromise = execPromise.then(function () {\n load.C = load.n;\n load.E = null; // indicates completion\n if (!true) ;\n }, function (err) {\n load.er = err;\n load.E = null;\n if (!true) ;\n throw err;\n });\n return load.E = execPromise;\n }\n // (should be a promise, but a minify optimization to leave out Promise.resolve)\n load.C = load.n;\n load.L = load.I = undefined;\n }\n catch (err) {\n load.er = err;\n throw err;\n }\n finally {\n load.e = null;\n }\n }\n }\n\n envGlobal.System = new SystemJS();\n\n /*\n * SystemJS browser attachments for script and import map processing\n */\n\n var importMapPromise = Promise.resolve();\n var importMap = { imports: {}, scopes: {}, depcache: {}, integrity: {} };\n\n // Scripts are processed immediately, on the first System.import, and on DOMReady.\n // Import map scripts are processed only once (by being marked) and in order for each phase.\n // This is to avoid using DOM mutation observers in core, although that would be an alternative.\n var processFirst = hasDocument;\n systemJSPrototype.prepareImport = function (doProcessScripts) {\n if (processFirst || doProcessScripts) {\n processScripts();\n processFirst = false;\n }\n return importMapPromise;\n };\n if (hasDocument) {\n processScripts();\n window.addEventListener('DOMContentLoaded', processScripts);\n }\n\n function processScripts () {\n [].forEach.call(document.querySelectorAll('script'), function (script) {\n if (script.sp) // sp marker = systemjs processed\n return;\n // TODO: deprecate systemjs-module in next major now that we have auto import\n if (script.type === 'systemjs-module') {\n script.sp = true;\n if (!script.src)\n return;\n System.import(script.src.slice(0, 7) === 'import:' ? script.src.slice(7) : resolveUrl(script.src, baseUrl)).catch(function (e) {\n // if there is a script load error, dispatch an \"error\" event\n // on the script tag.\n if (e.message.indexOf('https://git.io/JvFET#3') > -1) {\n var event = document.createEvent('Event');\n event.initEvent('error', false, false);\n script.dispatchEvent(event);\n }\n return Promise.reject(e);\n });\n }\n else if (script.type === 'systemjs-importmap') {\n script.sp = true;\n var fetchPromise = script.src ? fetch(script.src, { integrity: script.integrity }).then(function (res) {\n if (!res.ok)\n throw Error( res.status );\n return res.text();\n }).catch(function (err) {\n err.message = errMsg('W4', script.src ) + '\\n' + err.message;\n console.warn(err);\n if (typeof script.onerror === 'function') {\n script.onerror();\n }\n return '{}';\n }) : script.innerHTML;\n importMapPromise = importMapPromise.then(function () {\n return fetchPromise;\n }).then(function (text) {\n extendImportMap(importMap, text, script.src || baseUrl);\n });\n }\n });\n }\n\n function extendImportMap (importMap, newMapText, newMapUrl) {\n var newMap = {};\n try {\n newMap = JSON.parse(newMapText);\n } catch (err) {\n console.warn(Error(( errMsg('W5') )));\n }\n resolveAndComposeImportMap(newMap, newMapUrl, importMap);\n }\n\n /*\n * Script instantiation loading\n */\n\n if (hasDocument) {\n window.addEventListener('error', function (evt) {\n lastWindowErrorUrl = evt.filename;\n lastWindowError = evt.error;\n });\n var baseOrigin = location.origin;\n }\n\n systemJSPrototype.createScript = function (url) {\n var script = document.createElement('script');\n script.async = true;\n // Only add cross origin for actual cross origin\n // this is because Safari triggers for all\n // - https://bugs.webkit.org/show_bug.cgi?id=171566\n if (url.indexOf(baseOrigin + '/'))\n script.crossOrigin = 'anonymous';\n var integrity = importMap.integrity[url];\n if (integrity)\n script.integrity = integrity;\n script.src = url;\n return script;\n };\n\n // Auto imports -> script tags can be inlined directly for load phase\n var lastAutoImportDeps, lastAutoImportTimeout;\n var autoImportCandidates = {};\n var systemRegister = systemJSPrototype.register;\n var inlineScriptCount = 0\n systemJSPrototype.register = function (deps, declare) {\n if (hasDocument && document.readyState === 'loading' && typeof deps !== 'string') {\n var scripts = document.querySelectorAll('script[src]');\n var lastScript = scripts[scripts.length - 1];\n var lastAutoImportUrl\n lastAutoImportDeps = deps;\n if (lastScript) {\n lastAutoImportUrl = lastScript.src;\n }\n else {\n inlineScriptCount++\n lastAutoImportUrl = document.location.href + \"__inline_script__\" + inlineScriptCount ;\n }\n // if this is already a System load, then the instantiate has already begun\n // so this re-import has no consequence\n var loader = this;\n lastAutoImportTimeout = setTimeout(function () {\n autoImportCandidates[lastAutoImportUrl] = [deps, declare];\n loader.import(lastAutoImportUrl);\n });\n }\n else {\n lastAutoImportDeps = undefined;\n }\n return systemRegister.call(this, deps, declare);\n };\n\n var lastWindowErrorUrl, lastWindowError;\n systemJSPrototype.instantiate = function (url, firstParentUrl) {\n var autoImportRegistration = autoImportCandidates[url];\n if (autoImportRegistration) {\n delete autoImportCandidates[url];\n return autoImportRegistration;\n }\n var loader = this;\n return new Promise(function (resolve, reject) {\n var script = systemJSPrototype.createScript(url);\n script.addEventListener('error', function () {\n reject(Error(errMsg(3, [url, firstParentUrl].join(', ') )));\n });\n script.addEventListener('load', function () {\n document.head.removeChild(script);\n // Note that if an error occurs that isn't caught by this if statement,\n // that getRegister will return null and a \"did not instantiate\" error will be thrown.\n if (lastWindowErrorUrl === url) {\n reject(lastWindowError);\n }\n else {\n var register = loader.getRegister(url);\n // Clear any auto import registration for dynamic import scripts during load\n if (register && register[0] === lastAutoImportDeps)\n clearTimeout(lastAutoImportTimeout);\n resolve(register);\n }\n });\n document.head.appendChild(script);\n });\n };\n\n /*\n * Fetch loader, sets up shouldFetch and fetch hooks\n */\n systemJSPrototype.shouldFetch = function () {\n return false;\n };\n if (typeof fetch !== 'undefined')\n systemJSPrototype.fetch = fetch;\n\n var instantiate = systemJSPrototype.instantiate;\n var jsContentTypeRegEx = /^(text|application)\\/(x-)?javascript(;|$)/;\n systemJSPrototype.instantiate = function (url, parent) {\n var loader = this;\n if (!this.shouldFetch(url))\n return instantiate.apply(this, arguments);\n return this.fetch(url, {\n credentials: 'same-origin',\n integrity: importMap.integrity[url]\n })\n .then(function (res) {\n if (!res.ok)\n throw Error(errMsg(7, [res.status, res.statusText, url, parent].join(', ') ));\n var contentType = res.headers.get('content-type');\n if (!contentType || !jsContentTypeRegEx.test(contentType))\n throw Error(errMsg(4, contentType ));\n return res.text().then(function (source) {\n if (source.indexOf('//# sourceURL=') < 0)\n source += '\\n//# sourceURL=' + url;\n (0, eval)(source);\n return loader.getRegister(url);\n });\n });\n };\n\n systemJSPrototype.resolve = function (id, parentUrl) {\n parentUrl = parentUrl || !true || baseUrl;\n return resolveImportMap(( importMap), resolveIfNotPlainOrUrl(id, parentUrl) || id, parentUrl) || throwUnresolved(id, parentUrl);\n };\n\n function throwUnresolved (id, parentUrl) {\n throw Error(errMsg(8, [id, parentUrl].join(', ') ));\n }\n\n var systemInstantiate = systemJSPrototype.instantiate;\n systemJSPrototype.instantiate = function (url, firstParentUrl) {\n var preloads = ( importMap).depcache[url];\n if (preloads) {\n for (var i = 0; i < preloads.length; i++)\n getOrCreateLoad(this, this.resolve(preloads[i], url), url);\n }\n return systemInstantiate.call(this, url, firstParentUrl);\n };\n\n /*\n * Supports loading System.register in workers\n */\n\n if (hasSelf && typeof importScripts === 'function')\n systemJSPrototype.instantiate = function (url) {\n var loader = this;\n return Promise.resolve().then(function () {\n importScripts(url);\n return loader.getRegister(url);\n });\n };\n\n}());\n",
108
108
  "export const valueInstall = (object, name, value) => {\n const has = name in object\n const previous = object[name]\n\n object[name] = value\n\n return () => {\n if (has) {\n object[name] = previous\n } else {\n delete object[name]\n }\n }\n}\n",
@@ -111,7 +111,7 @@
111
111
  "export const displayErrorInDocument = (error) => {\n const title = \"An error occured\"\n let theme\n let message\n\n if (error && error.parsingError) {\n theme = \"light\"\n const { parsingError } = error\n message = errorToHTML(\n parsingError.messageHTML || escapeHtml(parsingError.message),\n )\n } else {\n theme = \"dark\"\n message = errorToHTML(error)\n }\n\n const css = `\n .jsenv-console {\n background: rgba(0, 0, 0, 0.8);\n position: absolute;\n top: 0;\n left: 0;\n width: 100%;\n display: flex;\n flex-direction: column;\n align-items: center\n z-index: 1000;\n width: 100%;\n box-sizing: border-box;\n padding: 1em;\n }\n\n .jsenv-console h1 {\n color: red;\n display: flex;\n align-items: center;\n }\n\n #button-close-jsenv-console {\n margin-left: 10px;\n }\n\n .jsenv-console pre {\n overflow: auto;\n max-width: 70em;\n /* avoid scrollbar to hide the text behind it */\n padding: 20px;\n }\n\n .jsenv-console pre[data-theme=\"dark\"] {\n background: transparent;\n border: 1px solid black;\n }\n\n .jsenv-console pre[data-theme=\"light\"] {\n background: #1E1E1E;\n border: 1px solid white;\n color: #EEEEEE;\n }\n\n .jsenv-console pre[data-theme=\"light\"] a {\n color: inherit;\n }\n `\n const html = `\n <style type=\"text/css\">${css}></style>\n <div class=\"jsenv-console\">\n <h1>${title} <button id=\"button-close-jsenv-console\">X</button></h1>\n <pre data-theme=\"${theme}\">${message}</pre>\n </div>\n `\n const removeJsenvConsole = appendHMTLInside(html, document.body)\n\n document.querySelector(\"#button-close-jsenv-console\").onclick = () => {\n removeJsenvConsole()\n }\n}\n\nconst escapeHtml = (string) => {\n return string\n .replace(/&/g, \"&amp;\")\n .replace(/</g, \"&lt;\")\n .replace(/>/g, \"&gt;\")\n .replace(/\"/g, \"&quot;\")\n .replace(/'/g, \"&#039;\")\n}\n\nconst errorToHTML = (error) => {\n let html\n\n if (error && error instanceof Error) {\n // stackTrace formatted by V8\n if (Error.captureStackTrace) {\n html = escapeHtml(error.stack)\n } else {\n // other stack trace such as firefox do not contain error.message\n html = escapeHtml(`${error.message}\n ${error.stack}`)\n }\n } else if (typeof error === \"string\") {\n html = error\n } else {\n html = JSON.stringify(error)\n }\n\n const htmlWithCorrectLineBreaks = html.replace(/\\n/g, \"\\n\")\n const htmlWithLinks = stringToStringWithLink(htmlWithCorrectLineBreaks, {\n transform: (url) => {\n return { href: url, text: url }\n },\n })\n return htmlWithLinks\n}\n\n// `Error: yo\n// at Object.execute (http://127.0.0.1:57300/build/src/__test__/file-throw.js:9:13)\n// at doExec (http://127.0.0.1:3000/src/__test__/file-throw.js:452:38)\n// at postOrderExec (http://127.0.0.1:3000/src/__test__/file-throw.js:448:16)\n// at http://127.0.0.1:3000/src/__test__/file-throw.js:399:18`.replace(/(?:https?|ftp|file):\\/\\/(.*+)$/gm, (...args) => {\n// debugger\n// })\nconst stringToStringWithLink = (\n source,\n {\n transform = (url) => {\n return {\n href: url,\n text: url,\n }\n },\n } = {},\n) => {\n return source.replace(/(?:https?|ftp|file):\\/\\/\\S+/gm, (match) => {\n let linkHTML = \"\"\n\n const lastChar = match[match.length - 1]\n\n // hotfix because our url regex sucks a bit\n const endsWithSeparationChar = lastChar === \")\" || lastChar === \":\"\n if (endsWithSeparationChar) {\n match = match.slice(0, -1)\n }\n\n const lineAndColumnPattern = /:([0-9]+):([0-9]+)$/\n const lineAndColumMatch = match.match(lineAndColumnPattern)\n if (lineAndColumMatch) {\n const lineAndColumnString = lineAndColumMatch[0]\n const lineNumber = lineAndColumMatch[1]\n const columnNumber = lineAndColumMatch[2]\n const url = match.slice(0, -lineAndColumnString.length)\n const { href, text } = transform(url)\n linkHTML = link({ href, text: `${text}:${lineNumber}:${columnNumber}` })\n } else {\n const linePattern = /:([0-9]+)$/\n const lineMatch = match.match(linePattern)\n if (lineMatch) {\n const lineString = lineMatch[0]\n const lineNumber = lineMatch[1]\n const url = match.slice(0, -lineString.length)\n const { href, text } = transform(url)\n linkHTML = link({\n href,\n text: `${text}:${lineNumber}`,\n })\n } else {\n const url = match\n const { href, text } = transform(url)\n linkHTML = link({ href, text })\n }\n }\n\n if (endsWithSeparationChar) {\n return `${linkHTML}${lastChar}`\n }\n return linkHTML\n })\n}\n\nconst link = ({ href, text = href }) => `<a href=\"${href}\">${text}</a>`\n\nconst appendHMTLInside = (html, parentNode) => {\n const temoraryParent = document.createElement(\"div\")\n temoraryParent.innerHTML = html\n return transferChildren(temoraryParent, parentNode)\n}\n\nconst transferChildren = (fromNode, toNode) => {\n const childNodes = [].slice.call(fromNode.childNodes, 0)\n let i = 0\n while (i < childNodes.length) {\n toNode.appendChild(childNodes[i])\n i++\n }\n return () => {\n let c = 0\n while (c < childNodes.length) {\n fromNode.appendChild(childNodes[c])\n c++\n }\n }\n}\n",
112
112
  "const { Notification } = window\n\nconst displayErrorNotificationNotAvailable = () => {}\n\nconst displayErrorNotificationImplementation = async (error, { icon } = {}) => {\n const permission = await Notification.requestPermission()\n\n if (permission === \"granted\") {\n const notification = new Notification(\"An error occured\", {\n lang: \"en\",\n body: error.stack,\n icon,\n })\n notification.onclick = () => {\n window.focus()\n }\n }\n}\n\nexport const displayErrorNotification =\n typeof Notification === \"function\"\n ? displayErrorNotificationImplementation\n : displayErrorNotificationNotAvailable\n",
113
113
  "export const makeNamespaceTransferable = (namespace) => {\n const transferableNamespace = {}\n Object.keys(namespace).forEach((key) => {\n const value = namespace[key]\n transferableNamespace[key] = isTransferable(value)\n ? value\n : hideNonTransferableValue(value)\n })\n return transferableNamespace\n}\n\nconst hideNonTransferableValue = (value) => {\n if (typeof value === \"function\") {\n return `[[HIDDEN: ${value.name} function cannot be transfered]]`\n }\n\n if (typeof value === \"symbol\") {\n return `[[HIDDEN: symbol function cannot be transfered]]`\n }\n\n return `[[HIDDEN: ${\n value.constructor ? value.constructor.name : \"object\"\n } cannot be transfered]]`\n}\n\n// https://stackoverflow.com/a/32673910/2634179\nconst isTransferable = (value) => {\n const seenArray = []\n const visit = () => {\n if (typeof value === \"function\") return false\n\n if (typeof value === \"symbol\") return false\n\n if (value === null) return false\n\n if (typeof value === \"object\") {\n const constructorName = value.constructor.namespace\n\n if (supportedTypes.includes(constructorName)) {\n return true\n }\n\n const maybe = maybeTypes.includes(constructorName)\n if (maybe) {\n const visited = seenArray.includes(value)\n if (visited) {\n // we don't really know until we are done visiting the object\n // implementing it properly means waiting for the recursion to be done\n // let's just\n return true\n }\n seenArray.push(value)\n\n if (constructorName === \"Array\" || constructorName === \"Object\") {\n return Object.keys(value).every((key) => isTransferable(value[key]))\n }\n if (constructorName === \"Map\") {\n return (\n [...value.keys()].every(isTransferable) &&\n [...value.values()].every(isTransferable)\n )\n }\n if (constructorName === \"Set\") {\n return [...value.keys()].every(isTransferable)\n }\n }\n\n // Error, DOM Node and others\n return false\n }\n return true\n }\n\n return visit(value)\n}\n\nconst supportedTypes = [\n \"Boolean\",\n \"Number\",\n \"String\",\n \"Date\",\n \"RegExp\",\n \"Blob\",\n \"FileList\",\n \"ImageData\",\n \"ImageBitmap\",\n \"ArrayBuffer\",\n]\n\nconst maybeTypes = [\"Array\", \"Object\", \"Map\", \"Set\"]\n",
114
- "import { normalizeImportMap } from \"@jsenv/import-map/src/normalizeImportMap.js\"\n\nimport { unevalException } from \"../../unevalException.js\"\n// do not use memoize from @jsenv/filesystem to avoid pulling @jsenv/filesystem code into the browser build\nimport { memoize } from \"../../memoize.js\"\nimport { fetchUrl } from \"../../browser-utils/fetch-browser.js\"\nimport { createImportResolverForImportmap } from \"../../import-resolution/import-resolver-importmap.js\"\nimport { measureAsyncFnPerf } from \"../../perf_browser.js\"\n\nimport { createBrowserSystem } from \"./createBrowserSystem.js\"\nimport { displayErrorInDocument } from \"./displayErrorInDocument.js\"\nimport { displayErrorNotification } from \"./displayErrorNotification.js\"\nimport { makeNamespaceTransferable } from \"./makeNamespaceTransferable.js\"\n\nconst memoizedCreateBrowserSystem = memoize(createBrowserSystem)\n\nexport const createBrowserRuntime = async ({\n compileServerOrigin,\n outDirectoryRelativeUrl,\n compileId,\n}) => {\n const fetchSource = (url) => {\n return fetchUrl(url, {\n credentials: \"same-origin\",\n })\n }\n\n const fetchJson = async (url) => {\n const response = await fetchSource(url)\n const json = await response.json()\n return json\n }\n\n const outDirectoryUrl = `${compileServerOrigin}/${outDirectoryRelativeUrl}`\n const envUrl = String(new URL(\"env.json\", outDirectoryUrl))\n const { importDefaultExtension } = await fetchJson(envUrl)\n const compileDirectoryRelativeUrl = `${outDirectoryRelativeUrl}${compileId}/`\n // if there is an importmap in the document we use it instead of fetching.\n // systemjs style with systemjs-importmap\n const importmapScript = document.querySelector(\n `script[type=\"jsenv-importmap\"]`,\n )\n let importMap\n let importMapUrl\n if (importmapScript) {\n let importmapRaw\n if (importmapScript.src) {\n importMapUrl = importmapScript.src\n const importmapFileResponse = await fetchSource(importMapUrl)\n importmapRaw =\n importmapFileResponse.status === 404\n ? {}\n : await importmapFileResponse.json()\n } else {\n importMapUrl = document.location.href\n importmapRaw = JSON.parse(importmapScript.textContent) || {}\n }\n importMap = normalizeImportMap(importmapRaw, importMapUrl)\n }\n\n const importResolver = await createImportResolverForImportmap({\n // projectDirectoryUrl,\n compileServerOrigin,\n compileDirectoryRelativeUrl,\n importMap,\n importMapUrl,\n importDefaultExtension,\n })\n\n const importFile = async (specifier) => {\n const browserSystem = await memoizedCreateBrowserSystem({\n compileServerOrigin,\n compileDirectoryRelativeUrl,\n fetchSource,\n importResolver,\n })\n return browserSystem.import(specifier)\n }\n\n const executeFile = async (\n specifier,\n {\n transferableNamespace = false,\n errorExposureInConsole = true,\n errorExposureInNotification = false,\n errorExposureInDocument = true,\n executionExposureOnWindow = false,\n errorTransform = (error) => error,\n measurePerformance,\n } = {},\n ) => {\n const browserSystem = await memoizedCreateBrowserSystem({\n compileServerOrigin,\n compileDirectoryRelativeUrl,\n fetchSource,\n importResolver,\n })\n\n const importUsingSystemJs = async () => {\n try {\n let namespace = await browserSystem.import(specifier)\n\n if (transferableNamespace) {\n namespace = makeNamespaceTransferable(namespace)\n }\n\n return {\n status: \"completed\",\n namespace,\n coverage: readCoverage(),\n }\n } catch (error) {\n let transformedError\n try {\n transformedError = await errorTransform(error)\n } catch (e) {\n transformedError = error\n }\n\n if (errorExposureInConsole) {\n displayErrorInConsole(transformedError)\n }\n if (errorExposureInNotification) {\n displayErrorNotification(transformedError)\n }\n if (errorExposureInDocument) {\n displayErrorInDocument(transformedError)\n }\n\n return {\n status: \"errored\",\n exceptionSource: unevalException(transformedError),\n coverage: readCoverage(),\n }\n }\n }\n\n const executionResult = await (measurePerformance\n ? measureAsyncFnPerf(importUsingSystemJs, `jsenv_file_import`)\n : importUsingSystemJs())\n if (executionExposureOnWindow) {\n window.__executionResult__ = executionResult\n }\n return executionResult\n }\n\n return {\n compileDirectoryRelativeUrl,\n importFile,\n executeFile,\n }\n}\n\nconst readCoverage = () => window.__coverage__\n\nconst displayErrorInConsole = (error) => {\n console.error(error)\n}\n",
114
+ "import { normalizeImportMap } from \"@jsenv/importmap/src/normalizeImportMap.js\"\n\nimport { unevalException } from \"../../unevalException.js\"\n// do not use memoize from @jsenv/filesystem to avoid pulling @jsenv/filesystem code into the browser build\nimport { memoize } from \"../../memoize.js\"\nimport { fetchUrl } from \"../../browser-utils/fetch-browser.js\"\nimport { createImportResolverForImportmap } from \"../../import-resolution/import-resolver-importmap.js\"\nimport { measureAsyncFnPerf } from \"../../perf_browser.js\"\n\nimport { createBrowserSystem } from \"./createBrowserSystem.js\"\nimport { displayErrorInDocument } from \"./displayErrorInDocument.js\"\nimport { displayErrorNotification } from \"./displayErrorNotification.js\"\nimport { makeNamespaceTransferable } from \"./makeNamespaceTransferable.js\"\n\nconst memoizedCreateBrowserSystem = memoize(createBrowserSystem)\n\nexport const createBrowserRuntime = async ({\n compileServerOrigin,\n outDirectoryRelativeUrl,\n compileId,\n}) => {\n const fetchSource = (url) => {\n return fetchUrl(url, {\n credentials: \"same-origin\",\n })\n }\n\n const fetchJson = async (url) => {\n const response = await fetchSource(url)\n const json = await response.json()\n return json\n }\n\n const outDirectoryUrl = `${compileServerOrigin}/${outDirectoryRelativeUrl}`\n const envUrl = String(new URL(\"env.json\", outDirectoryUrl))\n const { importDefaultExtension } = await fetchJson(envUrl)\n const compileDirectoryRelativeUrl = `${outDirectoryRelativeUrl}${compileId}/`\n // if there is an importmap in the document we use it instead of fetching.\n // systemjs style with systemjs-importmap\n const importmapScript = document.querySelector(\n `script[type=\"jsenv-importmap\"]`,\n )\n let importMap\n let importMapUrl\n if (importmapScript) {\n let importmapRaw\n if (importmapScript.src) {\n importMapUrl = importmapScript.src\n const importmapFileResponse = await fetchSource(importMapUrl)\n importmapRaw =\n importmapFileResponse.status === 404\n ? {}\n : await importmapFileResponse.json()\n } else {\n importMapUrl = document.location.href\n importmapRaw = JSON.parse(importmapScript.textContent) || {}\n }\n importMap = normalizeImportMap(importmapRaw, importMapUrl)\n }\n\n const importResolver = await createImportResolverForImportmap({\n // projectDirectoryUrl,\n compileServerOrigin,\n compileDirectoryRelativeUrl,\n importMap,\n importMapUrl,\n importDefaultExtension,\n })\n\n const importFile = async (specifier) => {\n const browserSystem = await memoizedCreateBrowserSystem({\n compileServerOrigin,\n compileDirectoryRelativeUrl,\n fetchSource,\n importResolver,\n })\n return browserSystem.import(specifier)\n }\n\n const executeFile = async (\n specifier,\n {\n transferableNamespace = false,\n errorExposureInConsole = true,\n errorExposureInNotification = false,\n errorExposureInDocument = true,\n executionExposureOnWindow = false,\n errorTransform = (error) => error,\n measurePerformance,\n } = {},\n ) => {\n const browserSystem = await memoizedCreateBrowserSystem({\n compileServerOrigin,\n compileDirectoryRelativeUrl,\n fetchSource,\n importResolver,\n })\n\n const importUsingSystemJs = async () => {\n try {\n let namespace = await browserSystem.import(specifier)\n\n if (transferableNamespace) {\n namespace = makeNamespaceTransferable(namespace)\n }\n\n return {\n status: \"completed\",\n namespace,\n coverage: readCoverage(),\n }\n } catch (error) {\n let transformedError\n try {\n transformedError = await errorTransform(error)\n } catch (e) {\n transformedError = error\n }\n\n if (errorExposureInConsole) {\n displayErrorInConsole(transformedError)\n }\n if (errorExposureInNotification) {\n displayErrorNotification(transformedError)\n }\n if (errorExposureInDocument) {\n displayErrorInDocument(transformedError)\n }\n\n return {\n status: \"errored\",\n exceptionSource: unevalException(transformedError),\n coverage: readCoverage(),\n }\n }\n }\n\n const executionResult = await (measurePerformance\n ? measureAsyncFnPerf(importUsingSystemJs, `jsenv_file_import`)\n : importUsingSystemJs())\n if (executionExposureOnWindow) {\n window.__executionResult__ = executionResult\n }\n return executionResult\n }\n\n return {\n compileDirectoryRelativeUrl,\n importFile,\n executeFile,\n }\n}\n\nconst readCoverage = () => window.__coverage__\n\nconst displayErrorInConsole = (error) => {\n console.error(error)\n}\n",
115
115
  "export const stackToString = (stack, { error, indent }) => {\n const name = error.name || \"Error\"\n const message = error.message || \"\"\n const stackString = stack\n .map((callSite) => `\\n${indent}at ${callSite}`)\n .join(\"\")\n\n return `${name}: ${message}${stackString}`\n}\n",
116
116
  "/* eslint-env browser, node */\n\nexport const parseDataUrl = (dataUrl) => {\n const afterDataProtocol = dataUrl.slice(\"data:\".length)\n const commaIndex = afterDataProtocol.indexOf(\",\")\n const beforeComma = afterDataProtocol.slice(0, commaIndex)\n\n let mediaType\n let base64Flag\n if (beforeComma.endsWith(`;base64`)) {\n mediaType = beforeComma.slice(0, -`;base64`.length)\n base64Flag = true\n } else {\n mediaType = beforeComma\n base64Flag = false\n }\n\n const afterComma = afterDataProtocol.slice(commaIndex + 1)\n return {\n mediaType: mediaType === \"\" ? \"text/plain;charset=US-ASCII\" : mediaType,\n base64Flag,\n data: afterComma,\n }\n}\n\nexport const stringifyDataUrl = ({ mediaType, base64Flag = true, data }) => {\n if (!mediaType || mediaType === \"text/plain;charset=US-ASCII\") {\n // can be a buffer or a string, hence check on data.length instead of !data or data === ''\n if (data.length === 0) {\n return `data:,`\n }\n if (base64Flag) {\n return `data:,${data}`\n }\n return `data:,${dataToBase64(data)}`\n }\n if (base64Flag) {\n return `data:${mediaType};base64,${dataToBase64(data)}`\n }\n return `data:${mediaType},${data}`\n}\n\nexport const dataUrlToRawData = ({ base64Flag, data }) => {\n return base64Flag ? base64ToString(data) : data\n}\n\nexport const dataToBase64 =\n typeof window === \"object\"\n ? window.atob\n : (data) => Buffer.from(data).toString(\"base64\")\n\nexport const base64ToString =\n typeof window === \"object\"\n ? window.btoa\n : (base64String) => Buffer.from(base64String, \"base64\").toString(\"utf8\")\n",
117
117
  "export const getJavaScriptSourceMappingUrl = (javaScriptSource) => {\n let sourceMappingUrl\n replaceSourceMappingUrl(\n javaScriptSource,\n javascriptSourceMappingUrlCommentRegexp,\n (value) => {\n sourceMappingUrl = value\n },\n )\n return sourceMappingUrl\n}\n\nexport const setJavaScriptSourceMappingUrl = (\n javaScriptSource,\n sourceMappingFileUrl,\n) => {\n let replaced\n const sourceAfterReplace = replaceSourceMappingUrl(\n javaScriptSource,\n javascriptSourceMappingUrlCommentRegexp,\n () => {\n replaced = true\n return sourceMappingFileUrl\n ? writeJavaScriptSourceMappingURL(sourceMappingFileUrl)\n : \"\"\n },\n )\n if (replaced) {\n return sourceAfterReplace\n }\n\n return sourceMappingFileUrl\n ? `${javaScriptSource}\n${writeJavaScriptSourceMappingURL(sourceMappingFileUrl)}`\n : javaScriptSource\n}\n\nexport const getCssSourceMappingUrl = (cssSource) => {\n let sourceMappingUrl\n replaceSourceMappingUrl(\n cssSource,\n cssSourceMappingUrlCommentRegExp,\n (value) => {\n sourceMappingUrl = value\n },\n )\n return sourceMappingUrl\n}\n\nexport const setCssSourceMappingUrl = (cssSource, sourceMappingFileUrl) => {\n let replaced\n const sourceAfterReplace = replaceSourceMappingUrl(\n cssSource,\n cssSourceMappingUrlCommentRegExp,\n () => {\n replaced = true\n return sourceMappingFileUrl\n ? writeCssSourceMappingUrl(sourceMappingFileUrl)\n : \"\"\n },\n )\n if (replaced) {\n return sourceAfterReplace\n }\n return sourceMappingFileUrl\n ? `${cssSource}\n${writeCssSourceMappingUrl(sourceMappingFileUrl)}`\n : cssSource\n}\n\nconst javascriptSourceMappingUrlCommentRegexp =\n /\\/\\/ ?# ?sourceMappingURL=([^\\s'\"]+)/g\nconst cssSourceMappingUrlCommentRegExp =\n /\\/\\*# ?sourceMappingURL=([^\\s'\"]+) \\*\\//g\n\n// ${\"//#\"} is to avoid a parser thinking there is a sourceMappingUrl for this file\nconst writeJavaScriptSourceMappingURL = (value) =>\n `${\"//#\"} sourceMappingURL=${value}`\nconst writeCssSourceMappingUrl = (value) => `/*# sourceMappingURL=${value} */`\n\nexport const sourcemapToBase64Url = (sourcemap) => {\n const asBase64 = Buffer.from(JSON.stringify(sourcemap)).toString(\"base64\")\n return `data:application/json;charset=utf-8;base64,${asBase64}`\n}\n\nconst replaceSourceMappingUrl = (source, regexp, callback) => {\n let lastSourceMappingUrl\n let matchSourceMappingUrl\n while ((matchSourceMappingUrl = regexp.exec(source))) {\n lastSourceMappingUrl = matchSourceMappingUrl\n }\n if (lastSourceMappingUrl) {\n const index = lastSourceMappingUrl.index\n const before = source.slice(0, index)\n const after = source.slice(index)\n const mappedAfter = after.replace(regexp, (match, firstGroup) => {\n return callback(firstGroup)\n })\n return `${before}${mappedAfter}`\n }\n return source\n}\n",
File without changes
package/main.js CHANGED
@@ -5,7 +5,6 @@ export { textToJavaScriptModule } from "./src/textToJavaScriptModule.js"
5
5
  export { execute } from "./src/execute.js"
6
6
  export { executeTestPlan } from "./src/executeTestPlan.js"
7
7
  export { importUsingChildProcess } from "./src/importUsingChildProcess.js"
8
- export { jsenvBabelPluginMap } from "./src/jsenvBabelPluginMap.js"
9
8
  export { jsenvCoverageConfig } from "./src/jsenvCoverageConfig.js"
10
9
  export { jsenvExplorableConfig } from "./src/jsenvExplorableConfig.js"
11
10
  export { jsenvServiceWorkerFinalizer } from "./src/jsenvServiceWorkerFinalizer.js"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jsenv/core",
3
- "version": "21.1.0",
3
+ "version": "22.0.3",
4
4
  "description": "Tool to develop, test and build js projects",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -11,8 +11,7 @@
11
11
  "node": ">=14.9.0"
12
12
  },
13
13
  "publishConfig": {
14
- "access": "public",
15
- "registry": "https://registry.npmjs.org"
14
+ "access": "public"
16
15
  },
17
16
  "type": "module",
18
17
  "exports": {
@@ -42,9 +41,8 @@
42
41
  "test-build": "node ./script/test/test_build.js",
43
42
  "test-launch-browser": "node ./script/test/test-launch-browser.js",
44
43
  "test-launch-node": "node ./script/test/test-launch-node.js",
45
- "measure-performances": "node ./script/performance/generate_performance_report.js --local",
46
- "measure-test-plan-performances": "node ./script/performance/measure_test_plan/measure_test_plan.js --local",
47
- "measure-import-performances": "node ./script/performance/measure_import/measure_import.js --local",
44
+ "measure-performances": "node --expose-gc ./script/performance/generate_performance_report.js --local",
45
+ "measure-test-plan-performances": "node --expose-gc ./script/performance/measure_test_plan/measure_test_plan.js --local",
48
46
  "prettier-format": "node ./script/prettier/prettier_format.mjs",
49
47
  "prettier-format-stage": "npm run prettier-format -- --staged",
50
48
  "prettier-check": "npm run prettier-format -- --dry-run",
@@ -59,55 +57,26 @@
59
57
  "@babel/helpers": "7.15.4",
60
58
  "@babel/parser": "7.15.7",
61
59
  "@babel/plugin-proposal-dynamic-import": "7.14.5",
62
- "@babel/plugin-proposal-json-strings": "7.14.5",
63
- "@babel/plugin-proposal-numeric-separator": "7.14.5",
64
- "@babel/plugin-proposal-object-rest-spread": "7.15.6",
65
- "@babel/plugin-proposal-optional-catch-binding": "7.14.5",
66
- "@babel/plugin-proposal-optional-chaining": "7.14.5",
67
- "@babel/plugin-proposal-unicode-property-regex": "7.14.5",
68
60
  "@babel/plugin-syntax-dynamic-import": "7.8.3",
69
61
  "@babel/plugin-syntax-import-meta": "7.10.4",
70
62
  "@babel/plugin-syntax-numeric-separator": "7.10.4",
71
- "@babel/plugin-syntax-object-rest-spread": "7.8.3",
72
- "@babel/plugin-syntax-optional-catch-binding": "7.8.3",
73
- "@babel/plugin-transform-arrow-functions": "7.14.5",
74
- "@babel/plugin-transform-block-scoped-functions": "7.14.5",
75
- "@babel/plugin-transform-block-scoping": "7.15.3",
76
- "@babel/plugin-transform-classes": "7.15.4",
77
- "@babel/plugin-transform-computed-properties": "7.14.5",
78
- "@babel/plugin-transform-destructuring": "7.14.7",
79
- "@babel/plugin-transform-dotall-regex": "7.14.5",
80
- "@babel/plugin-transform-duplicate-keys": "7.14.5",
81
- "@babel/plugin-transform-exponentiation-operator": "7.14.5",
82
- "@babel/plugin-transform-for-of": "7.15.4",
83
- "@babel/plugin-transform-function-name": "7.14.5",
84
- "@babel/plugin-transform-literals": "7.14.5",
85
63
  "@babel/plugin-transform-modules-systemjs": "7.15.4",
86
- "@babel/plugin-transform-new-target": "7.14.5",
87
- "@babel/plugin-transform-object-super": "7.14.5",
88
- "@babel/plugin-transform-parameters": "7.15.4",
89
- "@babel/plugin-transform-regenerator": "7.14.5",
90
- "@babel/plugin-transform-shorthand-properties": "7.14.5",
91
- "@babel/plugin-transform-spread": "7.14.6",
92
- "@babel/plugin-transform-sticky-regex": "7.14.5",
93
- "@babel/plugin-transform-template-literals": "7.14.5",
94
- "@babel/plugin-transform-typeof-symbol": "7.14.5",
95
- "@babel/plugin-transform-unicode-regex": "7.14.5",
96
64
  "@c88/v8-coverage": "0.1.1",
97
65
  "@jsenv/cancellation": "3.0.0",
98
66
  "@jsenv/filesystem": "2.2.0",
99
- "@jsenv/import-map": "6.13.3",
67
+ "@jsenv/importmap": "1.1.0",
100
68
  "@jsenv/logger": "4.0.1",
101
69
  "@jsenv/node-signals": "2.0.1",
102
70
  "@jsenv/server": "7.2.0",
103
71
  "@jsenv/uneval": "1.6.0",
104
- "@rollup/plugin-commonjs": "20.0.0",
72
+ "@rollup/plugin-commonjs": "21.0.0",
105
73
  "@rollup/plugin-json": "4.1.0",
106
74
  "@rollup/plugin-node-resolve": "13.0.5",
107
75
  "@rollup/plugin-replace": "3.0.0",
108
- "ansi-to-html": "0.7.1",
76
+ "ansi-to-html": "0.7.2",
109
77
  "babel-plugin-transform-async-to-promises": "0.8.15",
110
78
  "bytes": "3.1.0",
79
+ "cjs-module-lexer": "1.2.2",
111
80
  "cssnano": "5.0.8",
112
81
  "cssnano-preset-default": "5.1.4",
113
82
  "cuid": "2.1.8",
@@ -115,19 +84,22 @@
115
84
  "html-minifier": "4.0.0",
116
85
  "humanize-duration": "3.27.0",
117
86
  "is-unicode-supported": "1.1.0",
87
+ "is-valid-identifier": "2.0.2",
118
88
  "istanbul-lib-coverage": "3.0.1",
119
89
  "istanbul-lib-instrument": "5.0.2",
120
90
  "istanbul-lib-report": "3.0.0",
121
91
  "istanbul-reports": "3.0.2",
122
92
  "magic-string": "0.25.7",
123
93
  "parse5": "6.0.1",
124
- "playwright": "1.15.0",
125
- "postcss": "8.3.8",
94
+ "playwright": "1.15.1",
95
+ "postcss": "8.3.9",
126
96
  "postcss-value-parser": "4.1.0",
127
97
  "regenerator-runtime": "0.13.9",
128
- "rollup": "2.57.0",
98
+ "resolve": "1.20.0",
99
+ "rollup": "2.58.0",
129
100
  "rollup-plugin-node-builtins-brofs": "2.1.3",
130
101
  "rollup-plugin-node-globals": "1.4.0",
102
+ "rollup-plugin-polyfill-node": "0.7.0",
131
103
  "source-map": "0.7.3",
132
104
  "string-width": "5.0.1",
133
105
  "supports-color": "9.0.2",
@@ -135,19 +107,50 @@
135
107
  "terser": "5.9.0",
136
108
  "tree-kill": "1.2.2",
137
109
  "v8-to-istanbul": "8.1.0",
110
+ "vm2": "3.9.3",
138
111
  "wrap-ansi": "8.0.1"
139
112
  },
140
113
  "devDependencies": {
141
114
  "@babel/eslint-parser": "7.15.7",
115
+ "@babel/plugin-proposal-json-strings": "7.14.5",
116
+ "@babel/plugin-proposal-numeric-separator": "7.14.5",
117
+ "@babel/plugin-proposal-object-rest-spread": "7.15.6",
118
+ "@babel/plugin-proposal-optional-catch-binding": "7.14.5",
119
+ "@babel/plugin-proposal-optional-chaining": "7.14.5",
120
+ "@babel/plugin-proposal-unicode-property-regex": "7.14.5",
121
+ "@babel/plugin-syntax-object-rest-spread": "7.8.3",
122
+ "@babel/plugin-syntax-optional-catch-binding": "7.8.3",
123
+ "@babel/plugin-transform-arrow-functions": "7.14.5",
124
+ "@babel/plugin-transform-block-scoped-functions": "7.14.5",
125
+ "@babel/plugin-transform-block-scoping": "7.15.3",
126
+ "@babel/plugin-transform-classes": "7.15.4",
127
+ "@babel/plugin-transform-computed-properties": "7.14.5",
128
+ "@babel/plugin-transform-destructuring": "7.14.7",
129
+ "@babel/plugin-transform-dotall-regex": "7.14.5",
130
+ "@babel/plugin-transform-duplicate-keys": "7.14.5",
131
+ "@babel/plugin-transform-exponentiation-operator": "7.14.5",
132
+ "@babel/plugin-transform-for-of": "7.15.4",
133
+ "@babel/plugin-transform-function-name": "7.14.5",
134
+ "@babel/plugin-transform-literals": "7.14.5",
135
+ "@babel/plugin-transform-new-target": "7.14.5",
136
+ "@babel/plugin-transform-object-super": "7.14.5",
137
+ "@babel/plugin-transform-parameters": "7.15.4",
142
138
  "@babel/plugin-transform-react-jsx": "7.14.9",
139
+ "@babel/plugin-transform-regenerator": "7.14.5",
140
+ "@babel/plugin-transform-shorthand-properties": "7.14.5",
141
+ "@babel/plugin-transform-spread": "7.14.6",
142
+ "@babel/plugin-transform-sticky-regex": "7.14.5",
143
+ "@babel/plugin-transform-template-literals": "7.14.5",
144
+ "@babel/plugin-transform-typeof-symbol": "7.14.5",
143
145
  "@babel/plugin-transform-typescript": "7.15.4",
146
+ "@babel/plugin-transform-unicode-regex": "7.14.5",
147
+ "@babel/preset-env": "7.15.6",
144
148
  "@jsenv/assert": "2.3.1",
145
149
  "@jsenv/codecov-upload": "3.5.0",
146
- "@jsenv/eslint-config": "16.0.4",
150
+ "@jsenv/eslint-config": "16.0.6",
147
151
  "@jsenv/github-release-package": "1.2.3",
148
152
  "@jsenv/importmap-eslint-resolver": "5.1.2",
149
- "@jsenv/importmap-node-module": "2.2.1",
150
- "@jsenv/node-module-import-map": "13.6.1",
153
+ "@jsenv/importmap-node-module": "2.3.1",
151
154
  "@jsenv/package-publish": "1.6.2",
152
155
  "@jsenv/performance-impact": "1.7.0",
153
156
  "@jsenv/prettier-check-project": "5.6.1",
@@ -155,10 +158,12 @@
155
158
  "eslint": "7.32.0",
156
159
  "eslint-plugin-html": "6.2.0",
157
160
  "eslint-plugin-import": "2.24.2",
161
+ "eslint-plugin-react": "7.26.1",
158
162
  "node-notifier": "10.0.0",
159
163
  "preact": "10.5.14",
160
164
  "prettier": "2.4.1",
161
165
  "react": "17.0.2",
166
+ "react-dom": "17.0.2",
162
167
  "redux": "4.1.1"
163
168
  }
164
169
  }
package/readme.md CHANGED
@@ -6,7 +6,7 @@
6
6
  - A development server
7
7
  - A build tool to optimize files for production
8
8
 
9
- Jsenv integrates naturally with standard html, css and js. It can be configured to work with TypeScript and React.
9
+ Jsenv integrates naturally with standard html, css and js. It can be configured to work with React and JSX.
10
10
 
11
11
  # Jsenv iconic features
12
12
 
@@ -330,23 +330,66 @@ npm install --save-dev @jsenv/core
330
330
 
331
331
  Jsenv can execute standard JavaScript and be configured to run non-standard JavaScript.
332
332
 
333
- Standard corresponds to [JavaScript Modules](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Modules), destructuring, optional chaining and so on.
333
+ _non-standard JavaScript examples:_
334
334
 
335
- Non-standard corresponds to [CommonJS modules](https://code-trotter.com/web/understand-the-different-javascript-modules-formats/#commonjs-cjs), [JSX](https://reactjs.org/docs/introducing-jsx.html) or [TypeScript](https://www.typescriptlang.org).
335
+ - [CommonJS modules](https://code-trotter.com/web/understand-the-different-javascript-modules-formats/#commonjs-cjs)
336
+ - [JSX](https://reactjs.org/docs/introducing-jsx.html)
336
337
 
337
338
  > Keep in mind one of your dependency may use non-standard JavaScript. For instance react uses CommonJS modules.
338
339
 
339
340
  ## jsenv.config.mjs
340
341
 
341
- We recommend to regroup configuration in a _jsenv.config.mjs_ file at the root of your working directory.
342
-
343
- To get a better idea see [jsenv.config.js](./jsenv.config.js). The file can be imported and passed using the spread operator. This technic helps to see jsenv custom configuration quickly and share it between files.
342
+ Jsenv codebase regroups configuration in a top level [jsenv.config.mjs](./jsenv.config.js) file.
343
+ The file is meant to be imported and passed using the spread operator.
344
344
 
345
345
  ![screenshot about jsenv config import and spread operator](./docs/jsenv-config-spread.png)
346
346
 
347
347
  — See [script/test/test.js](https://github.com/jsenv/jsenv-core/blob/e44e362241e8e2142010322cb4552983b3bc9744/script/test/test.js#L2)
348
348
 
349
- That being said it's only a recommendation. There is nothing enforcing or checking the presence of _jsenv.config.mjs_.
349
+ This technic helps to see jsenv custom configuration quickly and share it between files. That being said you are free to organize your configuration as you want.
350
+
351
+ ## babel.config.cjs
352
+
353
+ When code needs to be transformed, the project must contain a [babel config file](https://babeljs.io/docs/en/config-files).
354
+
355
+ There is 2 scenarios where it happens:
356
+
357
+ - Code needs to be compatible with old browsers
358
+ - Code is not standard (jsx for instance)
359
+
360
+ In that case, it's recommended to use the following babel plugins declared in `babel.config.cjs`
361
+
362
+ ```js
363
+ /*
364
+ * This file is used to configure a list of babel plugins as documented in
365
+ * https://babeljs.io/docs/en/config-files
366
+ *
367
+ * During dev: babel plugins natively supported by browsers and Node.js are not used.
368
+ * During build:
369
+ * - When "runtimeSupport" is configured, babel plugins already supported by these runtime won't be used
370
+ * See https://github.com/jsenv/jsenv-template-pwa/blob/main/jsenv.config.mjs#L12
371
+ * - Otherwise all babel plugins are use
372
+ *
373
+ */
374
+
375
+ // "@babel/preset-env" transforms async function to generators
376
+ // but it's verbose and slow compared to using promises, so we:
377
+ // 1. Exclude "transform-async-to-generator", "transform-regenerator"
378
+ // 2. Enable "babel-plugin-transform-async-to-promises"
379
+ // See https://github.com/babel/babel/issues/8121
380
+ module.exports = {
381
+ presets: [
382
+ [
383
+ "@babel/preset-env",
384
+ {
385
+ modules: false,
386
+ exclude: ["transform-async-to-generator", "transform-regenerator"],
387
+ },
388
+ ],
389
+ ],
390
+ plugins: ["babel-plugin-transform-async-to-promises"],
391
+ }
392
+ ```
350
393
 
351
394
  ## CommonJS
352
395
 
@@ -355,7 +398,7 @@ CommonJS module format rely on `module.exports` and `require`. It was invented b
355
398
  _jsenv.config.mjs to use code written in CommonJS_:
356
399
 
357
400
  ```js
358
- import { jsenvBabelPluginMap, commonJsToJavaScriptModule } from "@jsenv/core"
401
+ import { commonJsToJavaScriptModule } from "@jsenv/core"
359
402
 
360
403
  export const customCompilers = {
361
404
  "./node_modules/whatever/index.js": commonJsToJavaScriptModule,
@@ -364,25 +407,16 @@ export const customCompilers = {
364
407
 
365
408
  ## React
366
409
 
367
- React is written in CommonJS and comes with jsx. If you use react and or jsx it requires some configuration.
410
+ When your code imports react, it needs to be configured as shown below.
368
411
 
369
- _jsenv.config.mjs for react and jsx:_
412
+ _jsenv.config.mjs:_
370
413
 
371
414
  ```js
372
- import { createRequire } from "module"
373
- import { jsenvBabelPluginMap, commonJsToJavaScriptModule } from "@jsenv/core"
374
-
375
- const require = createRequire(import.meta.url)
376
- const transformReactJSX = require("@babel/plugin-transform-react-jsx")
377
-
378
- export const babelPluginMap = {
379
- ...jsenvBabelPluginMap,
380
- "transform-react-jsx": [
381
- transformReactJSX,
382
- { pragma: "React.createElement", pragmaFrag: "React.Fragment" },
383
- ],
384
- }
415
+ import { commonJsToJavaScriptModule } from "@jsenv/core"
385
416
 
417
+ // "react" and "react-dom" are written in commonJs, they
418
+ // must be converted to javascript modules
419
+ // see https://github.com/jsenv/jsenv-core/blob/master/docs/shared-parameters.md#customCompilers
386
420
  export const customCompilers = {
387
421
  "./node_modules/react/index.js": commonJsToJavaScriptModule,
388
422
  "./node_modules/react-dom/index.js": (options) => {
@@ -391,7 +425,7 @@ export const customCompilers = {
391
425
  }
392
426
  ```
393
427
 
394
- You must also add an importmap file in your html to remap react imports.
428
+ You must also add an [importmap](https://github.com/WICG/import-maps#import-maps) file in your html to remap react imports.
395
429
 
396
430
  ```html
397
431
  <script type="importmap">
@@ -404,41 +438,30 @@ You must also add an importmap file in your html to remap react imports.
404
438
  </script>
405
439
  ```
406
440
 
407
- See also
441
+ ## JSX
408
442
 
409
- - [@jsenv/importmap-node-module](https://github.com/jsenv/importmap-node-module#import-map-node-module)
410
- - [babelPluginMap](./docs/shared-parameters.md#babelPluginMap)
411
- - [customCompilers](./docs/shared-parameters.md#customCompilers)
412
- - [transform-react-jsx on babel](https://babeljs.io/docs/en/next/babel-plugin-transform-react-jsx.html)
413
- - [importmap spec](https://github.com/WICG/import-maps#import-maps)
414
-
415
- </details>
443
+ If you want to use jsx, you need [@babel/plugin-transform-react-jsx](https://babeljs.io/docs/en/next/babel-plugin-transform-react-jsx.html) in your babel config file.
416
444
 
417
- ## TypeScript (experimental)
445
+ ```console
446
+ npm i --save-dev @babel/plugin-transform-react-jsx
447
+ ```
418
448
 
419
- _jsenv.config.mjs for TypeScript_:
449
+ _babel.config.cjs_:
420
450
 
421
451
  ```js
422
- import { createRequire } from "module"
423
- import { jsenvBabelPluginMap } from "@jsenv/core"
424
-
425
- const require = createRequire(import.meta.url)
426
- const transformTypeScript = require("@babel/plugin-transform-typescript")
427
-
428
- export const babelPluginMap = {
429
- ...jsenvBabelPluginMap,
430
- "transform-typescript": [transformTypeScript, { allowNamespaces: true }],
452
+ module.exports = {
453
+ plugins: [
454
+ [
455
+ "@babel/plugin-transform-react-jsx",
456
+ {
457
+ pragma: "React.createElement",
458
+ pragmaFrag: "React.Fragment",
459
+ },
460
+ ],
461
+ ],
431
462
  }
432
-
433
- export const importDefaultExtension = true
434
463
  ```
435
464
 
436
- See also
437
-
438
- - [babelPluginMap](./docs/shared-parameters.md#babelPluginMap)
439
- - [importDefaultExtension](./docs/shared-parameters.md#importDefaultExtension)
440
- - [transform-typescript on babel](https://babeljs.io/docs/en/next/babel-plugin-transform-typescript.html)
441
-
442
465
  # See also
443
466
 
444
467
  | Link | Description |
@@ -17,7 +17,6 @@ import {
17
17
  jsenvBrowserRuntimeSupport,
18
18
  jsenvNodeRuntimeSupport,
19
19
  } from "./internal/generateGroupMap/jsenvRuntimeSupport.js"
20
- import { jsenvBabelPluginMap } from "./jsenvBabelPluginMap.js"
21
20
 
22
21
  export const buildProject = async ({
23
22
  cancellationToken = createCancellationToken(),
@@ -39,7 +38,7 @@ export const buildProject = async ({
39
38
  systemJsUrl,
40
39
  globalName,
41
40
  globals = {},
42
- babelPluginMap = jsenvBabelPluginMap,
41
+ babelPluginMap,
43
42
  runtimeSupport = format === "global" ||
44
43
  format === "systemjs" ||
45
44
  format === "esmodule"