@jsenv/core 24.4.8 → 24.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/build_manifest.js +4 -4
- package/dist/compile_proxy/asset-manifest.json +1 -2
- package/dist/compile_proxy/{compile_proxy-e666f204.html → compile_proxy-1dfca609.html} +254 -218
- package/dist/redirector/asset-manifest.json +1 -2
- package/dist/redirector/{redirector-bee67b92.html → redirector-d1316407.html} +254 -218
- package/dist/toolbar/asset-manifest.json +1 -2
- package/dist/toolbar/{toolbar-d13f2c3c.html → toolbar-201c4093.html} +254 -218
- package/dist/toolbar_injector/asset-manifest.json +1 -1
- package/dist/toolbar_injector/{toolbar_injector-828ec83b.js → toolbar_injector-84042210.js} +2 -2
- package/dist/toolbar_injector/{toolbar_injector-828ec83b.js.map → toolbar_injector-84042210.js.map} +2 -2
- package/package.json +1 -1
- package/src/buildProject.js +2 -0
- package/src/internal/building/buildUsingRollup.js +16 -28
- package/src/internal/building/{bundleWorker.js → js/babel_plugin_inline_worker_imports.js} +25 -61
- package/src/internal/building/js/parseJsRessource.js +12 -13
- package/src/internal/building/js/transform_worker.js +55 -0
- package/src/internal/building/resolve_import_url_helper.js +2 -1
- package/src/internal/building/ressource_builder.js +59 -15
- package/src/internal/building/{createJsenvRollupPlugin.js → rollup_plugin_jsenv.js} +80 -9
- package/src/internal/building/url_loader.js +0 -2
- package/src/internal/compiling/createCompiledFileService.js +3 -3
- package/dist/compile_proxy/assets/s.js-fcba0e35.map +0 -246
- package/dist/redirector/assets/s.js-fcba0e35.map +0 -246
- package/dist/toolbar/assets/s.js-fcba0e35.map +0 -246
- package/src/internal/building/buildServiceWorker.js +0 -75
|
@@ -746,7 +746,7 @@
|
|
|
746
746
|
return then ? value.then(then) : value;
|
|
747
747
|
}
|
|
748
748
|
|
|
749
|
-
var TOOLBAR_BUILD_RELATIVE_URL = "dist/toolbar/toolbar-
|
|
749
|
+
var TOOLBAR_BUILD_RELATIVE_URL = "dist/toolbar/toolbar-201c4093.html";
|
|
750
750
|
|
|
751
751
|
function _call(body, then, direct) {
|
|
752
752
|
if (direct) {
|
|
@@ -970,4 +970,4 @@
|
|
|
970
970
|
|
|
971
971
|
})();
|
|
972
972
|
|
|
973
|
-
//# sourceMappingURL=toolbar_injector-
|
|
973
|
+
//# sourceMappingURL=toolbar_injector-84042210.js.map
|
package/dist/toolbar_injector/{toolbar_injector-828ec83b.js.map → toolbar_injector-84042210.js.map}
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
|
-
"file": "toolbar_injector-
|
|
3
|
+
"file": "toolbar_injector-84042210.js",
|
|
4
4
|
"sources": [
|
|
5
5
|
"../../helpers/babel/typeof/typeof.js",
|
|
6
6
|
"../../helpers/babel/defineProperty/defineProperty.js",
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
"import { fetchUrl } from \"./fetch-browser.js\"\n\nexport const fetchJson = async (url, options = {}) => {\n const response = await fetchUrl(url, options)\n const object = await response.json()\n return object\n}\n",
|
|
26
26
|
"import { fetchJson } from \"../../browser_utils/fetchJson.js\"\n\nexport const fetchExploringJson = async ({ signal } = {}) => {\n try {\n const exploringInfo = await fetchJson(\"/.jsenv/exploring.json\", {\n signal,\n })\n return exploringInfo\n } catch (e) {\n if (signal && signal.aborted && e.name === \"AbortError\") {\n throw e\n }\n throw new Error(\n `Cannot communicate with exploring server due to a network error\n--- error stack ---\n${e.stack}`,\n )\n }\n}\n",
|
|
27
27
|
"export const updateIframeOverflowOnParentWindow = () => {\n if (!window.parent) {\n // can happen while parent iframe reloads\n return\n }\n\n const aTooltipIsOpened =\n document.querySelector(\"[data-tooltip-visible]\") ||\n document.querySelector(\"[data-tooltip-auto-visible]\")\n const settingsAreOpened = document.querySelector(\"#settings[data-active]\")\n\n if (aTooltipIsOpened || settingsAreOpened) {\n enableIframeOverflowOnParentWindow()\n } else {\n disableIframeOverflowOnParentWindow()\n }\n}\n\nlet iframeOverflowEnabled = false\nconst enableIframeOverflowOnParentWindow = () => {\n if (iframeOverflowEnabled) return\n iframeOverflowEnabled = true\n\n const iframe = getToolbarIframe()\n const transitionDuration = iframe.style.transitionDuration\n setStyles(iframe, { \"height\": \"100%\", \"transition-duration\": \"0ms\" })\n if (transitionDuration) {\n setTimeout(() => {\n setStyles(iframe, { \"transition-duration\": transitionDuration })\n })\n }\n}\n\nconst disableIframeOverflowOnParentWindow = () => {\n if (!iframeOverflowEnabled) return\n iframeOverflowEnabled = false\n\n const iframe = getToolbarIframe()\n const transitionDuration = iframe.style.transitionDuration\n setStyles(iframe, { \"height\": \"40px\", \"transition-duration\": \"0ms\" })\n if (transitionDuration) {\n setTimeout(() => {\n setStyles(iframe, { \"transition-duration\": transitionDuration })\n })\n }\n}\n\nexport const getToolbarIframe = () => {\n const iframes = Array.from(window.parent.document.querySelectorAll(\"iframe\"))\n return iframes.find((iframe) => iframe.contentWindow === window)\n}\n\nexport const forceHideElement = (element) => {\n element.setAttribute(\"data-force-hide\", \"\")\n}\n\nexport const removeForceHideElement = (element) => {\n element.removeAttribute(\"data-force-hide\")\n}\n\nexport const setStyles = (element, styles) => {\n const elementStyle = element.style\n const restoreStyles = Object.keys(styles).map((styleName) => {\n let restore\n if (styleName in elementStyle) {\n const currentStyle = elementStyle[styleName]\n restore = () => {\n elementStyle[styleName] = currentStyle\n }\n } else {\n restore = () => {\n delete elementStyle[styleName]\n }\n }\n\n elementStyle[styleName] = styles[styleName]\n\n return restore\n })\n return () => {\n restoreStyles.forEach((restore) => restore())\n }\n}\n\nexport const setAttributes = (element, attributes) => {\n Object.keys(attributes).forEach((name) => {\n element.setAttribute(name, attributes[name])\n })\n}\n\nexport const getDocumentScroll = () => {\n return {\n x: document.documentElement.scrollLeft,\n y: document.documentElement.scrollTop,\n }\n}\n\nexport const toolbarSectionIsActive = (element) => {\n return element.hasAttribute(\"data-active\")\n}\n\nexport const activateToolbarSection = (element) => {\n element.setAttribute(\"data-active\", \"\")\n}\n\nexport const deactivateToolbarSection = (element) => {\n element.removeAttribute(\"data-active\")\n}\n",
|
|
28
|
-
"import { fetchExploringJson } from \"@jsenv/core/src/internal/dev_server/exploring/fetchExploringJson.js\"\nimport { setAttributes, setStyles } from \"./util/dom.js\"\n\n// eslint-disable-next-line no-undef\nconst TOOLBAR_BUILD_RELATIVE_URL = \"dist/toolbar/toolbar-
|
|
28
|
+
"import { fetchExploringJson } from \"@jsenv/core/src/internal/dev_server/exploring/fetchExploringJson.js\"\nimport { setAttributes, setStyles } from \"./util/dom.js\"\n\n// eslint-disable-next-line no-undef\nconst TOOLBAR_BUILD_RELATIVE_URL = \"dist/toolbar/toolbar-201c4093.html\"\nconst jsenvLogoSvgUrl = new URL(\"./jsenv-logo.svg\", import.meta.url)\n\nconst injectToolbar = async () => {\n await new Promise((resolve) => {\n if (window.requestIdleCallback) {\n window.requestIdleCallback(resolve)\n } else {\n window.requestAnimationFrame(resolve)\n }\n })\n\n const { jsenvDirectoryRelativeUrl } = await fetchExploringJson()\n const jsenvDirectoryServerUrl = resolveUrl(\n jsenvDirectoryRelativeUrl,\n document.location.origin,\n )\n\n const placeholder = getToolbarPlaceholder()\n\n const iframe = document.createElement(\"iframe\")\n setAttributes(iframe, {\n tabindex: -1,\n // sandbox: \"allow-forms allow-modals allow-pointer-lock allow-popups allow-presentation allow-same-origin allow-scripts allow-top-navigation-by-user-activation\",\n // allow: \"accelerometer; ambient-light-sensor; camera; encrypted-media; geolocation; gyroscope; microphone; midi; payment; vr\",\n allowtransparency: true,\n })\n setStyles(iframe, {\n \"position\": \"fixed\",\n \"zIndex\": 1000,\n \"bottom\": 0,\n \"left\": 0,\n \"width\": \"100%\",\n \"height\": 0,\n /* ensure toolbar children are not focusable when hidden */\n \"visibility\": \"hidden\",\n \"transition-duration\": \"300ms\",\n \"transition-property\": \"height, visibility\",\n \"border\": \"none\",\n })\n const iframeLoadedPromise = iframeToLoadedPromise(iframe)\n const jsenvToolbarHtmlServerUrl = resolveUrl(\n TOOLBAR_BUILD_RELATIVE_URL,\n jsenvDirectoryServerUrl,\n )\n // set iframe src BEFORE putting it into the DOM (prevent firefox adding an history entry)\n iframe.setAttribute(\"src\", jsenvToolbarHtmlServerUrl)\n placeholder.parentNode.replaceChild(iframe, placeholder)\n\n await iframeLoadedPromise\n iframe.removeAttribute(\"tabindex\")\n\n const div = document.createElement(\"div\")\n div.innerHTML = `\n<div id=\"jsenv-toolbar-trigger\">\n <svg id=\"jsenv-toolbar-trigger-icon\">\n <use xlink:href=\"${jsenvLogoSvgUrl}#jsenv-logo\"></use>\n </svg>\n <style>\n #jsenv-toolbar-trigger {\n display: block;\n overflow: hidden;\n position: fixed;\n z-index: 1000;\n bottom: -32px;\n right: 20px;\n height: 40px;\n width: 40px;\n padding: 0;\n margin: 0;\n border-radius: 5px 5px 0 0;\n border: 1px solid rgba(0, 0, 0, 0.33);\n border-bottom: none;\n box-shadow: 0px 0px 6px 2px rgba(0, 0, 0, 0.46);\n background: transparent;\n text-align: center;\n transition: 600ms;\n }\n\n #jsenv-toolbar-trigger:hover {\n cursor: pointer;\n }\n\n #jsenv-toolbar-trigger[data-expanded] {\n bottom: 0;\n }\n\n #jsenv-toolbar-trigger-icon {\n width: 35px;\n height: 35px;\n opacity: 0;\n transition: 600ms;\n }\n\n #jsenv-toolbar-trigger[data-expanded] #jsenv-toolbar-trigger-icon {\n opacity: 1;\n }\n </style>\n</div>`\n const toolbarTrigger = div.firstElementChild\n iframe.parentNode.appendChild(toolbarTrigger)\n\n let timer\n toolbarTrigger.onmouseenter = () => {\n toolbarTrigger.setAttribute(\"data-animate\", \"\")\n timer = setTimeout(expandToolbarTrigger, 500)\n }\n toolbarTrigger.onmouseleave = () => {\n clearTimeout(timer)\n collapseToolbarTrigger()\n }\n toolbarTrigger.onfocus = () => {\n toolbarTrigger.removeAttribute(\"data-animate\")\n expandToolbarTrigger()\n }\n toolbarTrigger.onblur = () => {\n toolbarTrigger.removeAttribute(\"data-animate\")\n clearTimeout(timer)\n collapseToolbarTrigger()\n }\n toolbarTrigger.onclick = () => {\n sendCommandToToolbar(iframe, \"showToolbar\")\n }\n\n const showToolbarTrigger = () => {\n toolbarTrigger.style.display = \"block\"\n }\n\n const hideToolbarTrigger = () => {\n toolbarTrigger.style.display = \"none\"\n }\n\n const expandToolbarTrigger = () => {\n toolbarTrigger.setAttribute(\"data-expanded\", \"\")\n }\n\n const collapseToolbarTrigger = () => {\n toolbarTrigger.removeAttribute(\"data-expanded\", \"\")\n }\n\n hideToolbarTrigger()\n addToolbarEventCallback(iframe, \"toolbar-visibility-change\", (visible) => {\n if (visible) {\n hideToolbarTrigger()\n } else {\n showToolbarTrigger()\n }\n })\n addToolbarEventCallback(iframe, \"toolbar_ready\", () => {\n sendCommandToToolbar(iframe, \"renderToolbar\")\n })\n\n return iframe\n}\n\nconst addToolbarEventCallback = (iframe, eventName, callback) => {\n const messageEventCallback = (messageEvent) => {\n const { data } = messageEvent\n if (typeof data !== \"object\") {\n return\n }\n const { __jsenv__ } = data\n if (!__jsenv__) {\n return\n }\n if (__jsenv__.event !== eventName) {\n return\n }\n callback(__jsenv__.data)\n }\n\n window.addEventListener(\"message\", messageEventCallback, false)\n return () => {\n window.removeEventListener(\"message\", messageEventCallback, false)\n }\n}\n\nconst sendCommandToToolbar = (iframe, command, ...args) => {\n iframe.contentWindow.postMessage(\n {\n __jsenv__: {\n command,\n args,\n },\n },\n window.origin,\n )\n}\n\nconst getToolbarPlaceholder = () => {\n const placeholder = queryPlaceholder()\n if (placeholder) {\n if (document.body.contains(placeholder)) {\n return placeholder\n }\n // otherwise iframe would not be visible because in <head>\n console.warn(\n \"element with [data-jsenv-toolbar-placeholder] must be inside document.body\",\n )\n return createTooolbarPlaceholder()\n }\n return createTooolbarPlaceholder()\n}\n\nconst queryPlaceholder = () => {\n return document.querySelector(\"[data-jsenv-toolbar-placeholder]\")\n}\n\nconst createTooolbarPlaceholder = () => {\n const placeholder = document.createElement(\"span\")\n document.body.appendChild(placeholder)\n return placeholder\n}\n\nconst iframeToLoadedPromise = (iframe) => {\n return new Promise((resolve) => {\n const onload = () => {\n iframe.removeEventListener(\"load\", onload, true)\n resolve()\n }\n iframe.addEventListener(\"load\", onload, true)\n })\n}\n\nconst resolveUrl = (url, baseUrl) => String(new URL(url, baseUrl))\n\nif (document.readyState === \"complete\") {\n injectToolbar()\n} else {\n window.addEventListener(\"load\", injectToolbar)\n}\n"
|
|
29
29
|
],
|
|
30
30
|
"names": [
|
|
31
31
|
"nativeTypeOf",
|
package/package.json
CHANGED
package/src/buildProject.js
CHANGED
|
@@ -79,6 +79,7 @@ export const buildProject = async ({
|
|
|
79
79
|
// https://github.com/cssnano/cssnano/tree/master/packages/cssnano-preset-default
|
|
80
80
|
minifyCssOptions,
|
|
81
81
|
|
|
82
|
+
workers = {},
|
|
82
83
|
serviceWorkers = {},
|
|
83
84
|
serviceWorkerFinalizer,
|
|
84
85
|
|
|
@@ -237,6 +238,7 @@ export const buildProject = async ({
|
|
|
237
238
|
minifyJsOptions,
|
|
238
239
|
minifyCssOptions,
|
|
239
240
|
|
|
241
|
+
workers,
|
|
240
242
|
serviceWorkers,
|
|
241
243
|
serviceWorkerFinalizer,
|
|
242
244
|
|
|
@@ -8,7 +8,6 @@ import {
|
|
|
8
8
|
} from "@jsenv/filesystem"
|
|
9
9
|
import { createDetailedMessage } from "@jsenv/logger"
|
|
10
10
|
|
|
11
|
-
import { buildServiceWorker } from "@jsenv/core/src/internal/building/buildServiceWorker.js"
|
|
12
11
|
import { humanizeUrl } from "@jsenv/core/src/internal/building/url_trace.js"
|
|
13
12
|
import {
|
|
14
13
|
isNodePartOfSupportedRuntimes,
|
|
@@ -16,7 +15,7 @@ import {
|
|
|
16
15
|
} from "@jsenv/core/src/internal/generateGroupMap/runtime_support.js"
|
|
17
16
|
import { featuresCompatMap } from "@jsenv/core/src/internal/generateGroupMap/featuresCompatMap.js"
|
|
18
17
|
import { createRuntimeCompat } from "@jsenv/core/src/internal/generateGroupMap/runtime_compat.js"
|
|
19
|
-
import { createJsenvRollupPlugin } from "./
|
|
18
|
+
import { createJsenvRollupPlugin } from "./rollup_plugin_jsenv.js"
|
|
20
19
|
|
|
21
20
|
export const buildUsingRollup = async ({
|
|
22
21
|
buildOperation,
|
|
@@ -48,6 +47,9 @@ export const buildUsingRollup = async ({
|
|
|
48
47
|
externalImportSpecifiers,
|
|
49
48
|
externalImportUrlPatterns,
|
|
50
49
|
importPaths,
|
|
50
|
+
workers,
|
|
51
|
+
serviceWorkers,
|
|
52
|
+
serviceWorkerFinalizer,
|
|
51
53
|
|
|
52
54
|
urlVersioning,
|
|
53
55
|
urlVersionningForEntryPoints,
|
|
@@ -62,9 +64,6 @@ export const buildUsingRollup = async ({
|
|
|
62
64
|
minifyJsOptions,
|
|
63
65
|
minifyCssOptions,
|
|
64
66
|
minifyHtmlOptions,
|
|
65
|
-
|
|
66
|
-
serviceWorkers,
|
|
67
|
-
serviceWorkerFinalizer,
|
|
68
67
|
}) => {
|
|
69
68
|
const node = isNodePartOfSupportedRuntimes(runtimeSupport)
|
|
70
69
|
const browser = isBrowserPartOfSupportedRuntimes(runtimeSupport)
|
|
@@ -121,6 +120,9 @@ export const buildUsingRollup = async ({
|
|
|
121
120
|
externalImportSpecifiers,
|
|
122
121
|
externalImportUrlPatterns,
|
|
123
122
|
importPaths,
|
|
123
|
+
workers,
|
|
124
|
+
serviceWorkers,
|
|
125
|
+
serviceWorkerFinalizer,
|
|
124
126
|
|
|
125
127
|
urlVersioning,
|
|
126
128
|
urlVersionningForEntryPoints,
|
|
@@ -157,7 +159,16 @@ export const buildUsingRollup = async ({
|
|
|
157
159
|
if (e.plugin === "jsenv") {
|
|
158
160
|
const jsenvPluginErrorMessage = getLastErrorMessage()
|
|
159
161
|
if (jsenvPluginErrorMessage) {
|
|
162
|
+
// rollup is adding properties to the original error
|
|
163
|
+
// making it a bit harder to read
|
|
164
|
+
// It does not add useful information so we restore the error
|
|
165
|
+
delete e.code
|
|
166
|
+
delete e.hook
|
|
167
|
+
delete e.id
|
|
168
|
+
delete e.watchFiles
|
|
169
|
+
delete e.plugin
|
|
160
170
|
e.message = jsenvPluginErrorMessage
|
|
171
|
+
throw e
|
|
161
172
|
}
|
|
162
173
|
throw e
|
|
163
174
|
}
|
|
@@ -219,29 +230,6 @@ export const buildUsingRollup = async ({
|
|
|
219
230
|
await writeFile(fileBuildUrl, buildFileContents[buildRelativeUrl])
|
|
220
231
|
}),
|
|
221
232
|
)
|
|
222
|
-
|
|
223
|
-
await Promise.all(
|
|
224
|
-
Object.keys(serviceWorkers).map(
|
|
225
|
-
async (serviceWorkerProjectRelativeUrl) => {
|
|
226
|
-
const serviceWorkerBuildRelativeUrl =
|
|
227
|
-
serviceWorkers[serviceWorkerProjectRelativeUrl]
|
|
228
|
-
await buildServiceWorker({
|
|
229
|
-
projectDirectoryUrl,
|
|
230
|
-
buildDirectoryUrl,
|
|
231
|
-
serviceWorkerProjectRelativeUrl,
|
|
232
|
-
serviceWorkerBuildRelativeUrl,
|
|
233
|
-
serviceWorkerTransformer: (code) =>
|
|
234
|
-
serviceWorkerFinalizer(code, {
|
|
235
|
-
buildManifest,
|
|
236
|
-
rollupBuild,
|
|
237
|
-
lineBreakNormalization,
|
|
238
|
-
}),
|
|
239
|
-
|
|
240
|
-
minify,
|
|
241
|
-
})
|
|
242
|
-
},
|
|
243
|
-
),
|
|
244
|
-
)
|
|
245
233
|
}
|
|
246
234
|
|
|
247
235
|
return {
|
|
@@ -1,73 +1,24 @@
|
|
|
1
|
-
import { readFileSync } from "fs"
|
|
2
1
|
import {
|
|
3
2
|
resolveUrl,
|
|
4
|
-
urlToFileSystemPath,
|
|
5
3
|
fileSystemPathToUrl,
|
|
4
|
+
urlToFileSystemPath,
|
|
6
5
|
} from "@jsenv/filesystem"
|
|
7
|
-
import { createDetailedMessage } from "@jsenv/logger"
|
|
8
|
-
import { require } from "@jsenv/core/src/internal/require.js"
|
|
9
|
-
|
|
10
|
-
export const bundleWorker = ({ workerScriptUrl, workerScriptSourceMap }) => {
|
|
11
|
-
const { code, map } = transformWorkerScript(workerScriptUrl, {
|
|
12
|
-
workerScriptSourceMap,
|
|
13
|
-
})
|
|
14
|
-
return { code, map }
|
|
15
|
-
}
|
|
16
6
|
|
|
17
|
-
const
|
|
18
|
-
|
|
19
|
-
{
|
|
7
|
+
export const babelPluginInlineWorkerImports = (
|
|
8
|
+
babel,
|
|
9
|
+
{ readImportedScript },
|
|
20
10
|
) => {
|
|
21
|
-
const
|
|
22
|
-
let scriptContent
|
|
23
|
-
try {
|
|
24
|
-
scriptContent = String(readFileSync(scriptPath))
|
|
25
|
-
} catch (e) {
|
|
26
|
-
if (e.code === "ENOENT") {
|
|
27
|
-
if (importerUrl) {
|
|
28
|
-
throw new Error(
|
|
29
|
-
createDetailedMessage(`no file found for an import in a worker.`, {
|
|
30
|
-
["worker url"]: importerUrl,
|
|
31
|
-
["imported url"]: scriptUrl,
|
|
32
|
-
}),
|
|
33
|
-
)
|
|
34
|
-
}
|
|
35
|
-
throw new Error(`no worker file at ${scriptUrl}`)
|
|
36
|
-
}
|
|
37
|
-
throw e
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
const { transformSync } = require("@babel/core")
|
|
41
|
-
const { code, map } = transformSync(scriptContent, {
|
|
42
|
-
filename: scriptPath,
|
|
43
|
-
configFile: false,
|
|
44
|
-
babelrc: false, // trust only these options, do not read any babelrc config file
|
|
45
|
-
ast: false,
|
|
46
|
-
inputSourceMap: workerScriptSourceMap,
|
|
47
|
-
sourceMaps: true,
|
|
48
|
-
// sourceFileName: scriptPath,
|
|
49
|
-
plugins: [[babelPluginInlineImportScripts, {}]],
|
|
50
|
-
})
|
|
51
|
-
return { code, map }
|
|
52
|
-
}
|
|
11
|
+
const { types } = babel
|
|
53
12
|
|
|
54
|
-
const babelPluginInlineImportScripts = (api) => {
|
|
55
|
-
const { types, parse } = api
|
|
56
13
|
return {
|
|
57
|
-
name: "transform-inline-
|
|
14
|
+
name: "transform-inline-worker-imports",
|
|
58
15
|
|
|
59
16
|
visitor: {
|
|
60
|
-
CallExpression: (
|
|
61
|
-
path,
|
|
62
|
-
{
|
|
63
|
-
file: {
|
|
64
|
-
opts: { filename },
|
|
65
|
-
},
|
|
66
|
-
},
|
|
67
|
-
) => {
|
|
17
|
+
CallExpression: (path, opts) => {
|
|
68
18
|
const calleePath = path.get("callee")
|
|
69
19
|
|
|
70
20
|
const replaceImportScriptsWithFileContents = () => {
|
|
21
|
+
const filename = opts.filename
|
|
71
22
|
const fileUrl = fileSystemPathToUrl(filename)
|
|
72
23
|
|
|
73
24
|
let previousArgType = ""
|
|
@@ -97,11 +48,24 @@ const babelPluginInlineImportScripts = (api) => {
|
|
|
97
48
|
|
|
98
49
|
if (previousArgType === "local") {
|
|
99
50
|
const nodes = importedUrls.reduce((previous, importedUrl) => {
|
|
100
|
-
const
|
|
101
|
-
|
|
51
|
+
const importedScriptCode = readImportedScript(importedUrl)
|
|
52
|
+
const { ast } = babel.transformSync(importedScriptCode, {
|
|
53
|
+
filename: urlToFileSystemPath(importedUrl),
|
|
54
|
+
configFile: false,
|
|
55
|
+
babelrc: false, // trust only these options, do not read any babelrc config file
|
|
56
|
+
ast: true,
|
|
57
|
+
sourceMaps: true,
|
|
58
|
+
// sourceFileName: scriptPath,
|
|
59
|
+
plugins: [
|
|
60
|
+
[
|
|
61
|
+
babelPluginInlineWorkerImports,
|
|
62
|
+
{
|
|
63
|
+
readImportedScript,
|
|
64
|
+
},
|
|
65
|
+
],
|
|
66
|
+
],
|
|
102
67
|
})
|
|
103
|
-
|
|
104
|
-
return [...previous, ...importedSourceAst.program.body]
|
|
68
|
+
return [...previous, ...ast.program.body]
|
|
105
69
|
}, [])
|
|
106
70
|
|
|
107
71
|
calleePath.parentPath.replaceWithMultiple(nodes)
|
|
@@ -4,7 +4,7 @@ import {
|
|
|
4
4
|
getJavaScriptSourceMappingUrl,
|
|
5
5
|
setJavaScriptSourceMappingUrl,
|
|
6
6
|
} from "@jsenv/core/src/internal/sourceMappingURLUtils.js"
|
|
7
|
-
import {
|
|
7
|
+
import { transformWorker } from "./transform_worker.js"
|
|
8
8
|
|
|
9
9
|
export const parseJsRessource = async (
|
|
10
10
|
jsRessource,
|
|
@@ -47,19 +47,18 @@ export const parseJsRessource = async (
|
|
|
47
47
|
map = JSON.parse(String(sourcemapRessource.bufferBeforeBuild))
|
|
48
48
|
}
|
|
49
49
|
|
|
50
|
-
// in case this js asset is a worker,
|
|
51
|
-
// importScripts are inlined
|
|
52
|
-
//
|
|
53
|
-
//
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
workerScriptSourceMap: map,
|
|
50
|
+
// in case this js asset is a worker, we transform it so that
|
|
51
|
+
// importScripts() calls are inlined
|
|
52
|
+
// We could also parse each importScripts call and decide to inline
|
|
53
|
+
// or not. For now inlining/concatenation is forced
|
|
54
|
+
if (jsRessource.isWorker || jsRessource.isServiceWorker) {
|
|
55
|
+
const transformResult = await transformWorker({
|
|
56
|
+
url: asOriginalUrl(jsUrl),
|
|
57
|
+
code: String(jsRessource.bufferBeforeBuild),
|
|
58
|
+
map,
|
|
60
59
|
})
|
|
61
|
-
code =
|
|
62
|
-
map =
|
|
60
|
+
code = transformResult.code
|
|
61
|
+
map = transformResult.map
|
|
63
62
|
} else {
|
|
64
63
|
code = jsString
|
|
65
64
|
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
// we could inline a worker by doing
|
|
2
|
+
// var blob = new Blob(code, { type: 'text/javascript' })
|
|
3
|
+
// window.URL.createObjectURL(blob)
|
|
4
|
+
|
|
5
|
+
import { readFileSync } from "fs"
|
|
6
|
+
import { urlToFileSystemPath } from "@jsenv/filesystem"
|
|
7
|
+
import { createDetailedMessage } from "@jsenv/logger"
|
|
8
|
+
|
|
9
|
+
import { babelPluginInlineWorkerImports } from "./babel_plugin_inline_worker_imports.js"
|
|
10
|
+
|
|
11
|
+
export const transformWorker = async ({ url, code, map }) => {
|
|
12
|
+
const { transformSync } = await import("@babel/core")
|
|
13
|
+
|
|
14
|
+
const transformResult = transformSync(code, {
|
|
15
|
+
filename: urlToFileSystemPath(url),
|
|
16
|
+
configFile: false,
|
|
17
|
+
babelrc: false, // trust only these options, do not read any babelrc config file
|
|
18
|
+
ast: false,
|
|
19
|
+
inputSourceMap: map,
|
|
20
|
+
sourceMaps: true,
|
|
21
|
+
// sourceFileName: scriptPath,
|
|
22
|
+
plugins: [
|
|
23
|
+
[
|
|
24
|
+
babelPluginInlineWorkerImports,
|
|
25
|
+
{
|
|
26
|
+
readImportedScript: readWorkerFile,
|
|
27
|
+
},
|
|
28
|
+
],
|
|
29
|
+
],
|
|
30
|
+
})
|
|
31
|
+
code = transformResult.code
|
|
32
|
+
map = transformResult.map
|
|
33
|
+
return { code, map }
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export const readWorkerFile = (url, importerUrl) => {
|
|
37
|
+
const filePath = urlToFileSystemPath(url)
|
|
38
|
+
try {
|
|
39
|
+
const code = String(readFileSync(filePath))
|
|
40
|
+
return code
|
|
41
|
+
} catch (e) {
|
|
42
|
+
if (e.code === "ENOENT") {
|
|
43
|
+
if (importerUrl) {
|
|
44
|
+
throw new Error(
|
|
45
|
+
createDetailedMessage(`no file found for an import in a worker.`, {
|
|
46
|
+
["worker url"]: importerUrl,
|
|
47
|
+
["imported url"]: url,
|
|
48
|
+
}),
|
|
49
|
+
)
|
|
50
|
+
}
|
|
51
|
+
throw new Error(`no worker file at ${url}`)
|
|
52
|
+
}
|
|
53
|
+
throw e
|
|
54
|
+
}
|
|
55
|
+
}
|
|
@@ -4,7 +4,8 @@ window.__resolveImportUrl__ = (url, baseUrl) => {
|
|
|
4
4
|
|
|
5
5
|
if (importmapNode) {
|
|
6
6
|
const importmap = JSON.parse(importmapNode.textContent)
|
|
7
|
-
|
|
7
|
+
const specifier = importmap.imports[url] || url
|
|
8
|
+
return new URL(specifier, baseUrl)
|
|
8
9
|
}
|
|
9
10
|
|
|
10
11
|
return new URL(url, baseUrl)
|
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
urlToParentUrl,
|
|
6
6
|
urlToFilename,
|
|
7
7
|
} from "@jsenv/filesystem"
|
|
8
|
-
import { createLogger } from "@jsenv/logger"
|
|
8
|
+
import { createLogger, loggerToLevels } from "@jsenv/logger"
|
|
9
9
|
|
|
10
10
|
import { setJavaScriptSourceMappingUrl } from "@jsenv/core/src/internal/sourceMappingURLUtils.js"
|
|
11
11
|
import { racePromises } from "../promise_race.js"
|
|
@@ -143,6 +143,9 @@ export const createRessourceBuilder = (
|
|
|
143
143
|
contentType,
|
|
144
144
|
bufferBeforeBuild,
|
|
145
145
|
})
|
|
146
|
+
if (!reference) {
|
|
147
|
+
return null
|
|
148
|
+
}
|
|
146
149
|
await reference.ressource.getReadyPromise()
|
|
147
150
|
return reference
|
|
148
151
|
}
|
|
@@ -229,10 +232,18 @@ export const createRessourceBuilder = (
|
|
|
229
232
|
|
|
230
233
|
let ressourceUrl
|
|
231
234
|
let isExternal = false
|
|
235
|
+
let isWorker = false
|
|
236
|
+
let isServiceWorker = false
|
|
232
237
|
if (typeof ressourceUrlResolution === "object") {
|
|
233
|
-
if (ressourceUrlResolution.
|
|
238
|
+
if (ressourceUrlResolution.isExternal) {
|
|
234
239
|
isExternal = true
|
|
235
240
|
}
|
|
241
|
+
if (ressourceUrlResolution.isWorker) {
|
|
242
|
+
isWorker = true
|
|
243
|
+
}
|
|
244
|
+
if (ressourceUrlResolution.isServiceWorker) {
|
|
245
|
+
isServiceWorker = true
|
|
246
|
+
}
|
|
236
247
|
ressourceUrl = ressourceUrlResolution.url
|
|
237
248
|
} else {
|
|
238
249
|
ressourceUrl = ressourceUrlResolution
|
|
@@ -292,6 +303,8 @@ export const createRessourceBuilder = (
|
|
|
292
303
|
isExternal,
|
|
293
304
|
isInline,
|
|
294
305
|
isPlaceholder,
|
|
306
|
+
isWorker,
|
|
307
|
+
isServiceWorker,
|
|
295
308
|
fileNamePattern,
|
|
296
309
|
urlVersioningDisabled,
|
|
297
310
|
})
|
|
@@ -330,14 +343,16 @@ export const createRessourceBuilder = (
|
|
|
330
343
|
} else {
|
|
331
344
|
ressource.references.push(reference)
|
|
332
345
|
const effects = ressource.applyReferenceEffects(reference, { isJsModule })
|
|
333
|
-
logger.debug
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
346
|
+
if (loggerToLevels(logger).debug) {
|
|
347
|
+
logger.debug(
|
|
348
|
+
formatFoundReference({
|
|
349
|
+
reference,
|
|
350
|
+
referenceEffects: effects,
|
|
351
|
+
showReferenceSourceLocation,
|
|
352
|
+
shortenUrl,
|
|
353
|
+
}),
|
|
354
|
+
)
|
|
355
|
+
}
|
|
341
356
|
}
|
|
342
357
|
|
|
343
358
|
return reference
|
|
@@ -356,9 +371,11 @@ export const createRessourceBuilder = (
|
|
|
356
371
|
isExternal = false,
|
|
357
372
|
isInline = false,
|
|
358
373
|
isPlaceholder = false,
|
|
374
|
+
isWorker = false,
|
|
375
|
+
isServiceWorker = false,
|
|
359
376
|
|
|
360
377
|
fileNamePattern,
|
|
361
|
-
urlVersioningDisabled =
|
|
378
|
+
urlVersioningDisabled = isServiceWorker,
|
|
362
379
|
}) => {
|
|
363
380
|
const ressource = {
|
|
364
381
|
contentType,
|
|
@@ -373,6 +390,8 @@ export const createRessourceBuilder = (
|
|
|
373
390
|
isInline,
|
|
374
391
|
isExternal,
|
|
375
392
|
isPlaceholder,
|
|
393
|
+
isWorker,
|
|
394
|
+
isServiceWorker,
|
|
376
395
|
|
|
377
396
|
urlVersioningDisabled,
|
|
378
397
|
fileNamePattern,
|
|
@@ -424,12 +443,13 @@ export const createRessourceBuilder = (
|
|
|
424
443
|
|
|
425
444
|
const response = await urlFetcher.fetchUrl(ressource.url, {
|
|
426
445
|
contentTypeExpected: ressource.firstStrongReference.contentTypeExpected,
|
|
427
|
-
urlTrace: () =>
|
|
428
|
-
createRessourceTrace({
|
|
446
|
+
urlTrace: () => {
|
|
447
|
+
return createRessourceTrace({
|
|
429
448
|
ressource,
|
|
430
449
|
createUrlSiteFromReference,
|
|
431
450
|
findRessourceByUrl,
|
|
432
|
-
})
|
|
451
|
+
})
|
|
452
|
+
},
|
|
433
453
|
})
|
|
434
454
|
if (response.url !== ressource.url) {
|
|
435
455
|
const urlBeforeRedirection = ressource.url
|
|
@@ -875,7 +895,7 @@ export const createRessourceBuilder = (
|
|
|
875
895
|
? String(referenceSource)
|
|
876
896
|
: ""
|
|
877
897
|
|
|
878
|
-
|
|
898
|
+
const urlSite = {
|
|
879
899
|
type:
|
|
880
900
|
referenceRessource && referenceRessource.isJsModule
|
|
881
901
|
? "import"
|
|
@@ -885,6 +905,30 @@ export const createRessourceBuilder = (
|
|
|
885
905
|
column: referenceColumn,
|
|
886
906
|
source: referenceSourceAsString,
|
|
887
907
|
}
|
|
908
|
+
|
|
909
|
+
if (!referenceRessource.isInline) {
|
|
910
|
+
return urlSite
|
|
911
|
+
}
|
|
912
|
+
const { firstStrongReference } = referenceRessource
|
|
913
|
+
if (!firstStrongReference) {
|
|
914
|
+
return urlSite
|
|
915
|
+
}
|
|
916
|
+
const htmlUrlSite = createUrlSiteFromReference(firstStrongReference)
|
|
917
|
+
// when the html node is injected there is no line in the source file to target
|
|
918
|
+
if (htmlUrlSite.line === undefined) {
|
|
919
|
+
return urlSite
|
|
920
|
+
}
|
|
921
|
+
const importerRessource = findRessourceByUrl(
|
|
922
|
+
firstStrongReference.referenceUrl,
|
|
923
|
+
)
|
|
924
|
+
if (!importerRessource || importerRessource.contentType !== "text/html") {
|
|
925
|
+
return urlSite
|
|
926
|
+
}
|
|
927
|
+
return {
|
|
928
|
+
...htmlUrlSite,
|
|
929
|
+
line: htmlUrlSite.line + urlSite.line,
|
|
930
|
+
column: htmlUrlSite.column + urlSite.column,
|
|
931
|
+
}
|
|
888
932
|
}
|
|
889
933
|
|
|
890
934
|
const showReferenceSourceLocation = (reference) => {
|