larry babby and threejs for glsl

This commit is contained in:
Sam
2024-06-24 21:24:00 +12:00
parent 87d5dc634d
commit 907ebae4c0
6474 changed files with 1279596 additions and 8 deletions

View File

@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2017-present Devon Govett
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@@ -0,0 +1,545 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
function _plugin() {
const data = require("@parcel/plugin");
_plugin = function () {
return data;
};
return data;
}
function _utils() {
const data = require("@parcel/utils");
_utils = function () {
return data;
};
return data;
}
function _diagnostic() {
const data = require("@parcel/diagnostic");
_diagnostic = function () {
return data;
};
return data;
}
function _path() {
const data = _interopRequireDefault(require("path"));
_path = function () {
return data;
};
return data;
}
function _nullthrows() {
const data = _interopRequireDefault(require("nullthrows"));
_nullthrows = function () {
return data;
};
return data;
}
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
// Used for as="" in preload/prefetch
const TYPE_TO_RESOURCE_PRIORITY = {
css: 'style',
js: 'script'
};
const BROWSER_PRELOAD_LOADER = './helpers/browser/preload-loader';
const BROWSER_PREFETCH_LOADER = './helpers/browser/prefetch-loader';
const LOADERS = {
browser: {
css: './helpers/browser/css-loader',
html: './helpers/browser/html-loader',
js: './helpers/browser/js-loader',
wasm: './helpers/browser/wasm-loader',
IMPORT_POLYFILL: './helpers/browser/import-polyfill'
},
worker: {
js: './helpers/worker/js-loader',
wasm: './helpers/worker/wasm-loader',
IMPORT_POLYFILL: false
},
node: {
css: './helpers/node/css-loader',
html: './helpers/node/html-loader',
js: './helpers/node/js-loader',
wasm: './helpers/node/wasm-loader',
IMPORT_POLYFILL: null
}
};
function getLoaders(ctx) {
if (ctx.isWorker()) return LOADERS.worker;
if (ctx.isBrowser()) return LOADERS.browser;
if (ctx.isNode()) return LOADERS.node;
return null;
}
// This cache should be invalidated if new dependencies get added to the bundle without the bundle objects changing
// This can happen when we reuse the BundleGraph between subsequent builds
let bundleDependencies = new WeakMap();
let defaultConfig = {
splitManifestThreshold: 100000
};
const CONFIG_SCHEMA = {
type: 'object',
properties: {
splitManifestThreshold: {
type: 'number'
}
},
additionalProperties: false
};
var _default = exports.default = new (_plugin().Runtime)({
async loadConfig({
config,
options
}) {
let packageKey = '@parcel/runtime-js';
let conf = await config.getConfig([], {
packageKey
});
if (!conf) {
return defaultConfig;
}
_utils().validateSchema.diagnostic(CONFIG_SCHEMA, {
data: conf === null || conf === void 0 ? void 0 : conf.contents,
source: await options.inputFS.readFile(conf.filePath, 'utf8'),
filePath: conf.filePath,
prependKey: `/${(0, _diagnostic().encodeJSONKeyComponent)(packageKey)}`
}, packageKey, `Invalid config for ${packageKey}`);
return {
...defaultConfig,
...(conf === null || conf === void 0 ? void 0 : conf.contents)
};
},
apply({
bundle,
bundleGraph,
options,
config
}) {
// Dependency ids in code replaced with referenced bundle names
// Loader runtime added for bundle groups that don't have a native loader (e.g. HTML/CSS/Worker - isURL?),
// and which are not loaded by a parent bundle.
// Loaders also added for modules that were moved to a separate bundle because they are a different type
// (e.g. WASM, HTML). These should be preloaded prior to the bundle being executed. Replace the entry asset(s)
// with the preload module.
if (bundle.type !== 'js') {
return;
}
let {
asyncDependencies,
otherDependencies
} = getDependencies(bundle);
let assets = [];
for (let dependency of asyncDependencies) {
let resolved = bundleGraph.resolveAsyncDependency(dependency, bundle);
if (resolved == null) {
continue;
}
if (resolved.type === 'asset') {
if (!bundle.env.shouldScopeHoist) {
// If this bundle already has the asset this dependency references,
// return a simple runtime of `Promise.resolve(internalRequire(assetId))`.
// The linker handles this for scope-hoisting.
assets.push({
filePath: __filename,
code: `module.exports = Promise.resolve(module.bundle.root(${JSON.stringify(bundleGraph.getAssetPublicId(resolved.value))}))`,
dependency,
env: {
sourceType: 'module'
}
});
}
} else {
// Resolve the dependency to a bundle. If inline, export the dependency id,
// which will be replaced with the contents of that bundle later.
let referencedBundle = bundleGraph.getReferencedBundle(dependency, bundle);
if ((referencedBundle === null || referencedBundle === void 0 ? void 0 : referencedBundle.bundleBehavior) === 'inline') {
assets.push({
filePath: _path().default.join(__dirname, `/bundles/${referencedBundle.id}.js`),
code: `module.exports = Promise.resolve(${JSON.stringify(dependency.id)});`,
dependency,
env: {
sourceType: 'module'
}
});
continue;
}
let loaderRuntime = getLoaderRuntime({
bundle,
dependency,
bundleGraph,
bundleGroup: resolved.value,
options
});
if (loaderRuntime != null) {
assets.push(loaderRuntime);
}
}
}
for (let dependency of otherDependencies) {
var _dependency$meta;
// Resolve the dependency to a bundle. If inline, export the dependency id,
// which will be replaced with the contents of that bundle later.
let referencedBundle = bundleGraph.getReferencedBundle(dependency, bundle);
if ((referencedBundle === null || referencedBundle === void 0 ? void 0 : referencedBundle.bundleBehavior) === 'inline') {
assets.push({
filePath: _path().default.join(__dirname, `/bundles/${referencedBundle.id}.js`),
code: `module.exports = ${JSON.stringify(dependency.id)};`,
dependency,
env: {
sourceType: 'module'
}
});
continue;
}
// Otherwise, try to resolve the dependency to an external bundle group
// and insert a URL to that bundle.
let resolved = bundleGraph.resolveAsyncDependency(dependency, bundle);
if (dependency.specifierType === 'url' && resolved == null) {
// If a URL dependency was not able to be resolved, add a runtime that
// exports the original specifier.
assets.push({
filePath: __filename,
code: `module.exports = ${JSON.stringify(dependency.specifier)}`,
dependency,
env: {
sourceType: 'module'
}
});
continue;
}
if (resolved == null || resolved.type !== 'bundle_group') {
continue;
}
let bundleGroup = resolved.value;
let mainBundle = (0, _nullthrows().default)(bundleGraph.getBundlesInBundleGroup(bundleGroup).find(b => {
let entries = b.getEntryAssets();
return entries.some(e => bundleGroup.entryAssetId === e.id);
}));
// Skip URL runtimes for library builds. This is handled in packaging so that
// the url is inlined and statically analyzable.
if (bundle.env.isLibrary && ((_dependency$meta = dependency.meta) === null || _dependency$meta === void 0 ? void 0 : _dependency$meta.placeholder) != null) {
continue;
}
// URL dependency or not, fall back to including a runtime that exports the url
assets.push(getURLRuntime(dependency, bundle, mainBundle, options));
}
// In development, bundles can be created lazily. This means that the parent bundle may not
// know about all of the sibling bundles of a child when it is written for the first time.
// Therefore, we need to also ensure that the siblings are loaded when the child loads.
if (options.shouldBuildLazily && bundle.env.outputFormat === 'global') {
let referenced = bundleGraph.getReferencedBundles(bundle);
for (let referencedBundle of referenced) {
let loaders = getLoaders(bundle.env);
if (!loaders) {
continue;
}
let loader = loaders[referencedBundle.type];
if (!loader) {
continue;
}
let relativePathExpr = getRelativePathExpr(bundle, referencedBundle, options);
let loaderCode = `require(${JSON.stringify(loader)})( ${getAbsoluteUrlExpr(relativePathExpr, bundle)})`;
assets.push({
filePath: __filename,
code: loaderCode,
isEntry: true,
env: {
sourceType: 'module'
}
});
}
}
if (shouldUseRuntimeManifest(bundle, options) && bundleGraph.getChildBundles(bundle).some(b => b.bundleBehavior !== 'inline') && isNewContext(bundle, bundleGraph)) {
assets.push({
filePath: __filename,
code: getRegisterCode(bundle, bundleGraph),
isEntry: true,
env: {
sourceType: 'module'
},
priority: getManifestBundlePriority(bundleGraph, bundle, config.splitManifestThreshold)
});
}
return assets;
}
});
function getDependencies(bundle) {
let cachedDependencies = bundleDependencies.get(bundle);
if (cachedDependencies) {
return cachedDependencies;
} else {
let asyncDependencies = [];
let otherDependencies = [];
bundle.traverse(node => {
if (node.type !== 'dependency') {
return;
}
let dependency = node.value;
if (dependency.priority === 'lazy' && dependency.specifierType !== 'url') {
asyncDependencies.push(dependency);
} else {
otherDependencies.push(dependency);
}
});
bundleDependencies.set(bundle, {
asyncDependencies,
otherDependencies
});
return {
asyncDependencies,
otherDependencies
};
}
}
function getLoaderRuntime({
bundle,
dependency,
bundleGroup,
bundleGraph,
options
}) {
let loaders = getLoaders(bundle.env);
if (loaders == null) {
return;
}
let externalBundles = bundleGraph.getBundlesInBundleGroup(bundleGroup);
let mainBundle = (0, _nullthrows().default)(externalBundles.find(bundle => {
var _bundle$getMainEntry;
return ((_bundle$getMainEntry = bundle.getMainEntry()) === null || _bundle$getMainEntry === void 0 ? void 0 : _bundle$getMainEntry.id) === bundleGroup.entryAssetId;
}));
// CommonJS is a synchronous module system, so there is no need to load bundles in parallel.
// Importing of the other bundles will be handled by the bundle group entry.
// Do the same thing in library mode for ES modules, as we are building for another bundler
// and the imports for sibling bundles will be in the target bundle.
// Previously we also did this when building lazily, however it seemed to cause issues in some cases.
// The original comment as to why is left here, in case a future traveller is trying to fix that issue:
// > [...] the runtime itself could get deduplicated and only exist in the parent. This causes errors if an
// > old version of the parent without the runtime
// > is already loaded.
if (bundle.env.outputFormat === 'commonjs' || bundle.env.isLibrary) {
externalBundles = [mainBundle];
} else {
// Otherwise, load the bundle group entry after the others.
externalBundles.splice(externalBundles.indexOf(mainBundle), 1);
externalBundles.reverse().push(mainBundle);
}
// Determine if we need to add a dynamic import() polyfill, or if all target browsers support it natively.
let needsDynamicImportPolyfill = !bundle.env.isLibrary && !bundle.env.supports('dynamic-import', true);
let needsEsmLoadPrelude = false;
let loaderModules = [];
for (let to of externalBundles) {
let loader = loaders[to.type];
if (!loader) {
continue;
}
if (to.type === 'js' && to.env.outputFormat === 'esmodule' && !needsDynamicImportPolyfill && shouldUseRuntimeManifest(bundle, options)) {
loaderModules.push(`load(${JSON.stringify(to.publicId)})`);
needsEsmLoadPrelude = true;
continue;
}
let relativePathExpr = getRelativePathExpr(bundle, to, options);
// Use esmodule loader if possible
if (to.type === 'js' && to.env.outputFormat === 'esmodule') {
if (!needsDynamicImportPolyfill) {
loaderModules.push(`__parcel__import__("./" + ${relativePathExpr})`);
continue;
}
loader = (0, _nullthrows().default)(loaders.IMPORT_POLYFILL, `No import() polyfill available for context '${bundle.env.context}'`);
} else if (to.type === 'js' && to.env.outputFormat === 'commonjs') {
loaderModules.push(`Promise.resolve(__parcel__require__("./" + ${relativePathExpr}))`);
continue;
}
let absoluteUrlExpr = shouldUseRuntimeManifest(bundle, options) ? `require('./helpers/bundle-manifest').resolve(${JSON.stringify(to.publicId)})` : getAbsoluteUrlExpr(relativePathExpr, bundle);
let code = `require(${JSON.stringify(loader)})(${absoluteUrlExpr})`;
// In development, clear the require cache when an error occurs so the
// user can try again (e.g. after fixing a build error).
if (options.mode === 'development' && bundle.env.outputFormat === 'global') {
code += '.catch(err => {delete module.bundle.cache[module.id]; throw err;})';
}
loaderModules.push(code);
}
// Similar to the comment above, this also used to be skipped when shouldBuildLazily was true,
// however it caused issues where a bundle group contained multiple bundles.
if (bundle.env.context === 'browser') {
loaderModules.push(...externalBundles
// TODO: Allow css to preload resources as well
.filter(to => to.type === 'js').flatMap(from => {
let {
preload,
prefetch
} = getHintedBundleGroups(bundleGraph, from);
return [...getHintLoaders(bundleGraph, bundle, preload, BROWSER_PRELOAD_LOADER, options), ...getHintLoaders(bundleGraph, bundle, prefetch, BROWSER_PREFETCH_LOADER, options)];
}));
}
if (loaderModules.length === 0) {
return;
}
let loaderCode = loaderModules.join(', ');
if (loaderModules.length > 1) {
loaderCode = `Promise.all([${loaderCode}])`;
} else {
loaderCode = `(${loaderCode})`;
}
if (mainBundle.type === 'js') {
let parcelRequire = bundle.env.shouldScopeHoist ? 'parcelRequire' : 'module.bundle.root';
loaderCode += `.then(() => ${parcelRequire}('${bundleGraph.getAssetPublicId(bundleGraph.getAssetById(bundleGroup.entryAssetId))}'))`;
}
let code = [];
if (needsEsmLoadPrelude) {
code.push(`let load = require('./helpers/browser/esm-js-loader');`);
}
code.push(`module.exports = ${loaderCode};`);
return {
filePath: __filename,
code: code.join('\n'),
dependency,
env: {
sourceType: 'module'
}
};
}
function getHintedBundleGroups(bundleGraph, bundle) {
let preload = [];
let prefetch = [];
let {
asyncDependencies
} = getDependencies(bundle);
for (let dependency of asyncDependencies) {
var _dependency$meta2;
let attributes = (_dependency$meta2 = dependency.meta) === null || _dependency$meta2 === void 0 ? void 0 : _dependency$meta2.importAttributes;
if (typeof attributes === 'object' && attributes != null && (
// $FlowFixMe
attributes.preload || attributes.prefetch)) {
let resolved = bundleGraph.resolveAsyncDependency(dependency, bundle);
if ((resolved === null || resolved === void 0 ? void 0 : resolved.type) === 'bundle_group') {
// === true for flow
if (attributes.preload === true) {
preload.push(resolved.value);
}
if (attributes.prefetch === true) {
prefetch.push(resolved.value);
}
}
}
}
return {
preload,
prefetch
};
}
function getHintLoaders(bundleGraph, from, bundleGroups, loader, options) {
let hintLoaders = [];
for (let bundleGroupToPreload of bundleGroups) {
let bundlesToPreload = bundleGraph.getBundlesInBundleGroup(bundleGroupToPreload);
for (let bundleToPreload of bundlesToPreload) {
let relativePathExpr = getRelativePathExpr(from, bundleToPreload, options);
let priority = TYPE_TO_RESOURCE_PRIORITY[bundleToPreload.type];
hintLoaders.push(`require(${JSON.stringify(loader)})(${getAbsoluteUrlExpr(relativePathExpr, from)}, ${priority ? JSON.stringify(priority) : 'null'}, ${JSON.stringify(bundleToPreload.target.env.outputFormat === 'esmodule')})`);
}
}
return hintLoaders;
}
function isNewContext(bundle, bundleGraph) {
let parents = bundleGraph.getParentBundles(bundle);
let isInEntryBundleGroup = bundleGraph.getBundleGroupsContainingBundle(bundle).some(g => bundleGraph.isEntryBundleGroup(g));
return isInEntryBundleGroup || parents.length === 0 || parents.some(parent => parent.env.context !== bundle.env.context || parent.type !== 'js');
}
function getURLRuntime(dependency, from, to, options) {
let relativePathExpr = getRelativePathExpr(from, to, options);
let code;
if (dependency.meta.webworker === true && !from.env.isLibrary) {
code = `let workerURL = require('./helpers/get-worker-url');\n`;
if (from.env.outputFormat === 'esmodule' && from.env.supports('import-meta-url')) {
code += `let url = new __parcel__URL__(${relativePathExpr});\n`;
code += `module.exports = workerURL(url.toString(), url.origin, ${String(from.env.outputFormat === 'esmodule')});`;
} else {
code += `let bundleURL = require('./helpers/bundle-url');\n`;
code += `let url = bundleURL.getBundleURL('${from.publicId}') + ${relativePathExpr};`;
code += `module.exports = workerURL(url, bundleURL.getOrigin(url), ${String(from.env.outputFormat === 'esmodule')});`;
}
} else {
code = `module.exports = ${getAbsoluteUrlExpr(relativePathExpr, from)};`;
}
return {
filePath: __filename,
code,
dependency,
env: {
sourceType: 'module'
}
};
}
function getRegisterCode(entryBundle, bundleGraph) {
let mappings = [];
bundleGraph.traverseBundles((bundle, _, actions) => {
if (bundle.bundleBehavior === 'inline') {
return;
}
// To make the manifest as small as possible all bundle key/values are
// serialised into a single array e.g. ['id', 'value', 'id2', 'value2'].
// `./helpers/bundle-manifest` accounts for this by iterating index by 2
mappings.push(bundle.publicId, (0, _utils().relativeBundlePath)(entryBundle, (0, _nullthrows().default)(bundle), {
leadingDotSlash: false
}));
if (bundle !== entryBundle && isNewContext(bundle, bundleGraph)) {
for (let referenced of bundleGraph.getReferencedBundles(bundle)) {
mappings.push(referenced.publicId, (0, _utils().relativeBundlePath)(entryBundle, (0, _nullthrows().default)(referenced), {
leadingDotSlash: false
}));
}
// New contexts have their own manifests, so there's no need to continue.
actions.skipChildren();
}
}, entryBundle);
let baseUrl = entryBundle.env.outputFormat === 'esmodule' && entryBundle.env.supports('import-meta-url') ? 'new __parcel__URL__("").toString()' // <-- this isn't ideal. We should use `import.meta.url` directly but it gets replaced currently
: `require('./helpers/bundle-url').getBundleURL('${entryBundle.publicId}')`;
return `require('./helpers/bundle-manifest').register(${baseUrl},JSON.parse(${JSON.stringify(JSON.stringify(mappings))}));`;
}
function getRelativePathExpr(from, to, options) {
let relativePath = (0, _utils().relativeBundlePath)(from, to, {
leadingDotSlash: false
});
let res = JSON.stringify(relativePath);
if (options.hmrOptions) {
res += ' + "?" + Date.now()';
}
return res;
}
function getAbsoluteUrlExpr(relativePathExpr, bundle) {
if (bundle.env.outputFormat === 'esmodule' && bundle.env.supports('import-meta-url') || bundle.env.outputFormat === 'commonjs') {
// This will be compiled to new URL(url, import.meta.url) or new URL(url, 'file:' + __filename).
return `new __parcel__URL__(${relativePathExpr}).toString()`;
} else {
return `require('./helpers/bundle-url').getBundleURL('${bundle.publicId}') + ${relativePathExpr}`;
}
}
function shouldUseRuntimeManifest(bundle, options) {
let env = bundle.env;
return !env.isLibrary && bundle.bundleBehavior !== 'inline' && env.isBrowser() && options.mode === 'production';
}
function getManifestBundlePriority(bundleGraph, bundle, threshold) {
let bundleSize = 0;
bundle.traverseAssets((asset, _, actions) => {
bundleSize += asset.stats.size;
if (bundleSize > threshold) {
actions.stop();
}
});
return bundleSize > threshold ? 'parallel' : 'sync';
}

View File

@@ -0,0 +1,28 @@
"use strict";
var cacheLoader = require('../cacheLoader');
module.exports = cacheLoader(function (bundle) {
return new Promise(function (resolve, reject) {
// Don't insert the same link element twice (e.g. if it was already in the HTML)
var existingLinks = document.getElementsByTagName('link');
if ([].concat(existingLinks).some(function isCurrentBundle(link) {
return link.href === bundle && link.rel.indexOf('stylesheet') > -1;
})) {
resolve();
return;
}
var link = document.createElement('link');
link.rel = 'stylesheet';
link.href = bundle;
link.onerror = function (e) {
link.onerror = link.onload = null;
link.remove();
reject(e);
};
link.onload = function () {
link.onerror = link.onload = null;
resolve();
};
document.getElementsByTagName('head')[0].appendChild(link);
});
});

View File

@@ -0,0 +1,7 @@
"use strict";
function load(id) {
// eslint-disable-next-line no-undef
return __parcel__import__(require('../bundle-manifest').resolve(id));
}
module.exports = load;

View File

@@ -0,0 +1,8 @@
"use strict";
var cacheLoader = require('../cacheLoader');
module.exports = cacheLoader(function (bundle) {
return fetch(bundle).then(function (res) {
return res.text();
});
});

View File

@@ -0,0 +1,32 @@
"use strict";
var cacheLoader = require('../cacheLoader');
module.exports = cacheLoader(function (bundle) {
return new Promise(function (resolve, reject) {
// Add a global function to handle when the script loads.
var globalName = "i".concat(('' + Math.random()).slice(2));
global[globalName] = function (m) {
resolve(m);
cleanup();
};
// Remove script on load or error
var cleanup = function () {
delete global[globalName];
script.onerror = null;
script.remove();
};
// Append an inline script tag into the document head
var script = document.createElement('script');
script.async = true;
script.type = 'module';
script.charset = 'utf-8';
script.textContent = "import * as m from '".concat(bundle, "'; ").concat(globalName, "(m);");
script.onerror = function (e) {
reject(e);
cleanup();
};
document.head.appendChild(script);
});
});

View File

@@ -0,0 +1,35 @@
"use strict";
var cacheLoader = require('../cacheLoader');
module.exports = cacheLoader(function (bundle) {
return new Promise(function (resolve, reject) {
// Don't insert the same script twice (e.g. if it was already in the HTML)
var existingScripts = document.getElementsByTagName('script');
if ([].concat(existingScripts).some(function isCurrentBundle(script) {
return script.src === bundle;
})) {
resolve();
return;
}
var preloadLink = document.createElement('link');
preloadLink.href = bundle;
preloadLink.rel = 'preload';
preloadLink.as = 'script';
document.head.appendChild(preloadLink);
var script = document.createElement('script');
script.async = true;
script.type = 'text/javascript';
script.src = bundle;
script.onerror = function (e) {
var error = new TypeError("Failed to fetch dynamically imported module: ".concat(bundle, ". Error: ").concat(e.message));
script.onerror = script.onload = null;
script.remove();
reject(error);
};
script.onload = function () {
script.onerror = script.onload = null;
resolve();
};
document.getElementsByTagName('head')[0].appendChild(script);
});
});

View File

@@ -0,0 +1,13 @@
"use strict";
var cacheLoader = require('../cacheLoader');
module.exports = cacheLoader(function (bundle, priority) {
var link = document.createElement('link');
link.rel = 'prefetch';
link.href = bundle;
if (priority) {
link.as = priority;
}
document.getElementsByTagName('head')[0].appendChild(link);
return Promise.resolve();
}, 'prefetch');

View File

@@ -0,0 +1,14 @@
"use strict";
var cacheLoader = require('../cacheLoader');
module.exports = cacheLoader(function (bundle, priority, isModule) {
var link = document.createElement('link');
link.charset = 'utf-8';
link.rel = isModule ? 'modulepreload' : 'preload';
link.href = bundle;
if (priority) {
link.as = priority;
}
document.getElementsByTagName('head')[0].appendChild(link);
return Promise.resolve();
}, 'preload');

View File

@@ -0,0 +1,16 @@
"use strict";
var cacheLoader = require('../cacheLoader');
module.exports = cacheLoader(function (bundle) {
return fetch(bundle).then(function (res) {
if (WebAssembly.instantiateStreaming) {
return WebAssembly.instantiateStreaming(res);
} else {
return res.arrayBuffer().then(function (data) {
return WebAssembly.instantiate(data);
});
}
}).then(function (wasmModule) {
return wasmModule.instance.exports;
});
});

View File

@@ -0,0 +1,20 @@
"use strict";
var mapping = new Map();
function register(baseUrl, manifest) {
for (var i = 0; i < manifest.length - 1; i += 2) {
mapping.set(manifest[i], {
baseUrl: baseUrl,
path: manifest[i + 1]
});
}
}
function resolve(id) {
var resolved = mapping.get(id);
if (resolved == null) {
throw new Error('Could not resolve bundle with id ' + id);
}
return new URL(resolved.path, resolved.baseUrl).toString();
}
module.exports.register = register;
module.exports.resolve = resolve;

View File

@@ -0,0 +1,39 @@
"use strict";
var bundleURL = {};
function getBundleURLCached(id) {
var value = bundleURL[id];
if (!value) {
value = getBundleURL();
bundleURL[id] = value;
}
return value;
}
function getBundleURL() {
try {
throw new Error();
} catch (err) {
var matches = ('' + err.stack).match(/(https?|file|ftp|(chrome|moz|safari-web)-extension):\/\/[^)\n]+/g);
if (matches) {
// The first two stack frames will be this function and getBundleURLCached.
// Use the 3rd one, which will be a runtime in the original bundle.
return getBaseURL(matches[2]);
}
}
return '/';
}
function getBaseURL(url) {
return ('' + url).replace(/^((?:https?|file|ftp|(chrome|moz|safari-web)-extension):\/\/.+)\/[^/]+$/, '$1') + '/';
}
// TODO: Replace uses with `new URL(url).origin` when ie11 is no longer supported.
function getOrigin(url) {
var matches = ('' + url).match(/(https?|file|ftp|(chrome|moz|safari-web)-extension):\/\/[^/]+/);
if (!matches) {
throw new Error('Origin not found');
}
return matches[0];
}
exports.getBundleURL = getBundleURLCached;
exports.getBaseURL = getBaseURL;
exports.getOrigin = getOrigin;

View File

@@ -0,0 +1,27 @@
"use strict";
var cachedBundles = {};
var cachedPreloads = {};
var cachedPrefetches = {};
function getCache(type) {
switch (type) {
case 'preload':
return cachedPreloads;
case 'prefetch':
return cachedPrefetches;
default:
return cachedBundles;
}
}
module.exports = function (loader, type) {
return function (bundle) {
var cache = getCache(type);
if (cache[bundle]) {
return cache[bundle];
}
return cache[bundle] = loader.apply(null, arguments).catch(function (e) {
delete cache[bundle];
throw e;
});
};
};

View File

@@ -0,0 +1,15 @@
"use strict";
module.exports = function (workerUrl, origin, isESM) {
if (origin === self.location.origin) {
// If the worker bundle's url is on the same origin as the document,
// use the worker bundle's own url.
return workerUrl;
} else {
// Otherwise, create a blob URL which loads the worker bundle with `importScripts`.
var source = isESM ? 'import ' + JSON.stringify(workerUrl) + ';' : 'importScripts(' + JSON.stringify(workerUrl) + ');';
return URL.createObjectURL(new Blob([source], {
type: 'application/javascript'
}));
}
};

View File

@@ -0,0 +1,6 @@
"use strict";
// loading a CSS style is a no-op in Node.js
module.exports = function () {
return Promise.resolve();
};

View File

@@ -0,0 +1,19 @@
"use strict";
var fs = require('fs');
var cacheLoader = require('../cacheLoader');
module.exports = cacheLoader(function (bundle) {
return new Promise(function (resolve, reject) {
fs.readFile(__dirname + bundle, 'utf8', function (err, data) {
if (err) {
reject(err);
} else {
// wait for the next event loop iteration, so we are sure
// the current module is fully loaded
setImmediate(function () {
resolve(data);
});
}
});
});
});

View File

@@ -0,0 +1,21 @@
"use strict";
var fs = require('fs');
var cacheLoader = require('../cacheLoader');
module.exports = cacheLoader(function (bundle) {
return new Promise(function (resolve, reject) {
fs.readFile(__dirname + bundle, 'utf8', function (err, data) {
if (err) {
reject(err);
} else {
// wait for the next event loop iteration, so we are sure
// the current module is fully loaded
setImmediate(function () {
resolve(data);
});
}
});
}).then(function (code) {
new Function('', code)();
});
});

View File

@@ -0,0 +1,19 @@
"use strict";
var fs = require('fs');
var cacheLoader = require('../cacheLoader');
module.exports = cacheLoader(function (bundle) {
return new Promise(function (resolve, reject) {
fs.readFile(__dirname + bundle, function (err, data) {
if (err) {
reject(err);
} else {
resolve(data.buffer);
}
});
}).then(function (data) {
return WebAssembly.instantiate(data);
}).then(function (wasmModule) {
return wasmModule.instance.exports;
});
});

View File

@@ -0,0 +1,14 @@
"use strict";
/* global __parcel__importScripts__:readonly*/
var cacheLoader = require('../cacheLoader');
module.exports = cacheLoader(function (bundle) {
return new Promise(function (resolve, reject) {
try {
__parcel__importScripts__(bundle);
resolve();
} catch (e) {
reject(e);
}
});
});

View File

@@ -0,0 +1,16 @@
"use strict";
var cacheLoader = require('../cacheLoader');
module.exports = cacheLoader(function (bundle) {
return fetch(bundle).then(function (res) {
if (WebAssembly.instantiateStreaming) {
return WebAssembly.instantiateStreaming(res);
} else {
return res.arrayBuffer().then(function (data) {
return WebAssembly.instantiate(data);
});
}
}).then(function (wasmModule) {
return wasmModule.instance.exports;
});
});

View File

@@ -0,0 +1,29 @@
{
"name": "@parcel/runtime-js",
"version": "2.12.0",
"license": "MIT",
"publishConfig": {
"access": "public"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/parcel"
},
"repository": {
"type": "git",
"url": "https://github.com/parcel-bundler/parcel.git"
},
"main": "lib/JSRuntime.js",
"source": "src/JSRuntime.js",
"engines": {
"node": ">= 12.0.0",
"parcel": "^2.12.0"
},
"dependencies": {
"@parcel/diagnostic": "2.12.0",
"@parcel/plugin": "2.12.0",
"@parcel/utils": "2.12.0",
"nullthrows": "^1.1.1"
},
"gitHead": "2059029ee91e5f03a273b0954d3e629d7375f986"
}

View File

@@ -0,0 +1,724 @@
// @flow strict-local
import type {
BundleGraph,
BundleGroup,
Dependency,
Environment,
PluginOptions,
NamedBundle,
RuntimeAsset,
} from '@parcel/types';
import {Runtime} from '@parcel/plugin';
import {
relativeBundlePath,
validateSchema,
type SchemaEntity,
} from '@parcel/utils';
import {encodeJSONKeyComponent} from '@parcel/diagnostic';
import path from 'path';
import nullthrows from 'nullthrows';
// Used for as="" in preload/prefetch
const TYPE_TO_RESOURCE_PRIORITY = {
css: 'style',
js: 'script',
};
const BROWSER_PRELOAD_LOADER = './helpers/browser/preload-loader';
const BROWSER_PREFETCH_LOADER = './helpers/browser/prefetch-loader';
const LOADERS = {
browser: {
css: './helpers/browser/css-loader',
html: './helpers/browser/html-loader',
js: './helpers/browser/js-loader',
wasm: './helpers/browser/wasm-loader',
IMPORT_POLYFILL: './helpers/browser/import-polyfill',
},
worker: {
js: './helpers/worker/js-loader',
wasm: './helpers/worker/wasm-loader',
IMPORT_POLYFILL: false,
},
node: {
css: './helpers/node/css-loader',
html: './helpers/node/html-loader',
js: './helpers/node/js-loader',
wasm: './helpers/node/wasm-loader',
IMPORT_POLYFILL: null,
},
};
function getLoaders(
ctx: Environment,
): ?{[string]: string, IMPORT_POLYFILL: null | false | string, ...} {
if (ctx.isWorker()) return LOADERS.worker;
if (ctx.isBrowser()) return LOADERS.browser;
if (ctx.isNode()) return LOADERS.node;
return null;
}
// This cache should be invalidated if new dependencies get added to the bundle without the bundle objects changing
// This can happen when we reuse the BundleGraph between subsequent builds
let bundleDependencies = new WeakMap<
NamedBundle,
{|
asyncDependencies: Array<Dependency>,
otherDependencies: Array<Dependency>,
|},
>();
type JSRuntimeConfig = {|
splitManifestThreshold: number,
|};
let defaultConfig: JSRuntimeConfig = {
splitManifestThreshold: 100000,
};
const CONFIG_SCHEMA: SchemaEntity = {
type: 'object',
properties: {
splitManifestThreshold: {
type: 'number',
},
},
additionalProperties: false,
};
export default (new Runtime({
async loadConfig({config, options}): Promise<JSRuntimeConfig> {
let packageKey = '@parcel/runtime-js';
let conf = await config.getConfig<JSRuntimeConfig>([], {
packageKey,
});
if (!conf) {
return defaultConfig;
}
validateSchema.diagnostic(
CONFIG_SCHEMA,
{
data: conf?.contents,
source: await options.inputFS.readFile(conf.filePath, 'utf8'),
filePath: conf.filePath,
prependKey: `/${encodeJSONKeyComponent(packageKey)}`,
},
packageKey,
`Invalid config for ${packageKey}`,
);
return {
...defaultConfig,
...conf?.contents,
};
},
apply({bundle, bundleGraph, options, config}) {
// Dependency ids in code replaced with referenced bundle names
// Loader runtime added for bundle groups that don't have a native loader (e.g. HTML/CSS/Worker - isURL?),
// and which are not loaded by a parent bundle.
// Loaders also added for modules that were moved to a separate bundle because they are a different type
// (e.g. WASM, HTML). These should be preloaded prior to the bundle being executed. Replace the entry asset(s)
// with the preload module.
if (bundle.type !== 'js') {
return;
}
let {asyncDependencies, otherDependencies} = getDependencies(bundle);
let assets = [];
for (let dependency of asyncDependencies) {
let resolved = bundleGraph.resolveAsyncDependency(dependency, bundle);
if (resolved == null) {
continue;
}
if (resolved.type === 'asset') {
if (!bundle.env.shouldScopeHoist) {
// If this bundle already has the asset this dependency references,
// return a simple runtime of `Promise.resolve(internalRequire(assetId))`.
// The linker handles this for scope-hoisting.
assets.push({
filePath: __filename,
code: `module.exports = Promise.resolve(module.bundle.root(${JSON.stringify(
bundleGraph.getAssetPublicId(resolved.value),
)}))`,
dependency,
env: {sourceType: 'module'},
});
}
} else {
// Resolve the dependency to a bundle. If inline, export the dependency id,
// which will be replaced with the contents of that bundle later.
let referencedBundle = bundleGraph.getReferencedBundle(
dependency,
bundle,
);
if (referencedBundle?.bundleBehavior === 'inline') {
assets.push({
filePath: path.join(
__dirname,
`/bundles/${referencedBundle.id}.js`,
),
code: `module.exports = Promise.resolve(${JSON.stringify(
dependency.id,
)});`,
dependency,
env: {sourceType: 'module'},
});
continue;
}
let loaderRuntime = getLoaderRuntime({
bundle,
dependency,
bundleGraph,
bundleGroup: resolved.value,
options,
});
if (loaderRuntime != null) {
assets.push(loaderRuntime);
}
}
}
for (let dependency of otherDependencies) {
// Resolve the dependency to a bundle. If inline, export the dependency id,
// which will be replaced with the contents of that bundle later.
let referencedBundle = bundleGraph.getReferencedBundle(
dependency,
bundle,
);
if (referencedBundle?.bundleBehavior === 'inline') {
assets.push({
filePath: path.join(__dirname, `/bundles/${referencedBundle.id}.js`),
code: `module.exports = ${JSON.stringify(dependency.id)};`,
dependency,
env: {sourceType: 'module'},
});
continue;
}
// Otherwise, try to resolve the dependency to an external bundle group
// and insert a URL to that bundle.
let resolved = bundleGraph.resolveAsyncDependency(dependency, bundle);
if (dependency.specifierType === 'url' && resolved == null) {
// If a URL dependency was not able to be resolved, add a runtime that
// exports the original specifier.
assets.push({
filePath: __filename,
code: `module.exports = ${JSON.stringify(dependency.specifier)}`,
dependency,
env: {sourceType: 'module'},
});
continue;
}
if (resolved == null || resolved.type !== 'bundle_group') {
continue;
}
let bundleGroup = resolved.value;
let mainBundle = nullthrows(
bundleGraph.getBundlesInBundleGroup(bundleGroup).find(b => {
let entries = b.getEntryAssets();
return entries.some(e => bundleGroup.entryAssetId === e.id);
}),
);
// Skip URL runtimes for library builds. This is handled in packaging so that
// the url is inlined and statically analyzable.
if (bundle.env.isLibrary && dependency.meta?.placeholder != null) {
continue;
}
// URL dependency or not, fall back to including a runtime that exports the url
assets.push(getURLRuntime(dependency, bundle, mainBundle, options));
}
// In development, bundles can be created lazily. This means that the parent bundle may not
// know about all of the sibling bundles of a child when it is written for the first time.
// Therefore, we need to also ensure that the siblings are loaded when the child loads.
if (options.shouldBuildLazily && bundle.env.outputFormat === 'global') {
let referenced = bundleGraph.getReferencedBundles(bundle);
for (let referencedBundle of referenced) {
let loaders = getLoaders(bundle.env);
if (!loaders) {
continue;
}
let loader = loaders[referencedBundle.type];
if (!loader) {
continue;
}
let relativePathExpr = getRelativePathExpr(
bundle,
referencedBundle,
options,
);
let loaderCode = `require(${JSON.stringify(
loader,
)})( ${getAbsoluteUrlExpr(relativePathExpr, bundle)})`;
assets.push({
filePath: __filename,
code: loaderCode,
isEntry: true,
env: {sourceType: 'module'},
});
}
}
if (
shouldUseRuntimeManifest(bundle, options) &&
bundleGraph
.getChildBundles(bundle)
.some(b => b.bundleBehavior !== 'inline') &&
isNewContext(bundle, bundleGraph)
) {
assets.push({
filePath: __filename,
code: getRegisterCode(bundle, bundleGraph),
isEntry: true,
env: {sourceType: 'module'},
priority: getManifestBundlePriority(
bundleGraph,
bundle,
config.splitManifestThreshold,
),
});
}
return assets;
},
}): Runtime);
function getDependencies(bundle: NamedBundle): {|
asyncDependencies: Array<Dependency>,
otherDependencies: Array<Dependency>,
|} {
let cachedDependencies = bundleDependencies.get(bundle);
if (cachedDependencies) {
return cachedDependencies;
} else {
let asyncDependencies = [];
let otherDependencies = [];
bundle.traverse(node => {
if (node.type !== 'dependency') {
return;
}
let dependency = node.value;
if (
dependency.priority === 'lazy' &&
dependency.specifierType !== 'url'
) {
asyncDependencies.push(dependency);
} else {
otherDependencies.push(dependency);
}
});
bundleDependencies.set(bundle, {asyncDependencies, otherDependencies});
return {asyncDependencies, otherDependencies};
}
}
function getLoaderRuntime({
bundle,
dependency,
bundleGroup,
bundleGraph,
options,
}: {|
bundle: NamedBundle,
dependency: Dependency,
bundleGroup: BundleGroup,
bundleGraph: BundleGraph<NamedBundle>,
options: PluginOptions,
|}): ?RuntimeAsset {
let loaders = getLoaders(bundle.env);
if (loaders == null) {
return;
}
let externalBundles = bundleGraph.getBundlesInBundleGroup(bundleGroup);
let mainBundle = nullthrows(
externalBundles.find(
bundle => bundle.getMainEntry()?.id === bundleGroup.entryAssetId,
),
);
// CommonJS is a synchronous module system, so there is no need to load bundles in parallel.
// Importing of the other bundles will be handled by the bundle group entry.
// Do the same thing in library mode for ES modules, as we are building for another bundler
// and the imports for sibling bundles will be in the target bundle.
// Previously we also did this when building lazily, however it seemed to cause issues in some cases.
// The original comment as to why is left here, in case a future traveller is trying to fix that issue:
// > [...] the runtime itself could get deduplicated and only exist in the parent. This causes errors if an
// > old version of the parent without the runtime
// > is already loaded.
if (bundle.env.outputFormat === 'commonjs' || bundle.env.isLibrary) {
externalBundles = [mainBundle];
} else {
// Otherwise, load the bundle group entry after the others.
externalBundles.splice(externalBundles.indexOf(mainBundle), 1);
externalBundles.reverse().push(mainBundle);
}
// Determine if we need to add a dynamic import() polyfill, or if all target browsers support it natively.
let needsDynamicImportPolyfill =
!bundle.env.isLibrary && !bundle.env.supports('dynamic-import', true);
let needsEsmLoadPrelude = false;
let loaderModules = [];
for (let to of externalBundles) {
let loader = loaders[to.type];
if (!loader) {
continue;
}
if (
to.type === 'js' &&
to.env.outputFormat === 'esmodule' &&
!needsDynamicImportPolyfill &&
shouldUseRuntimeManifest(bundle, options)
) {
loaderModules.push(`load(${JSON.stringify(to.publicId)})`);
needsEsmLoadPrelude = true;
continue;
}
let relativePathExpr = getRelativePathExpr(bundle, to, options);
// Use esmodule loader if possible
if (to.type === 'js' && to.env.outputFormat === 'esmodule') {
if (!needsDynamicImportPolyfill) {
loaderModules.push(`__parcel__import__("./" + ${relativePathExpr})`);
continue;
}
loader = nullthrows(
loaders.IMPORT_POLYFILL,
`No import() polyfill available for context '${bundle.env.context}'`,
);
} else if (to.type === 'js' && to.env.outputFormat === 'commonjs') {
loaderModules.push(
`Promise.resolve(__parcel__require__("./" + ${relativePathExpr}))`,
);
continue;
}
let absoluteUrlExpr = shouldUseRuntimeManifest(bundle, options)
? `require('./helpers/bundle-manifest').resolve(${JSON.stringify(
to.publicId,
)})`
: getAbsoluteUrlExpr(relativePathExpr, bundle);
let code = `require(${JSON.stringify(loader)})(${absoluteUrlExpr})`;
// In development, clear the require cache when an error occurs so the
// user can try again (e.g. after fixing a build error).
if (
options.mode === 'development' &&
bundle.env.outputFormat === 'global'
) {
code +=
'.catch(err => {delete module.bundle.cache[module.id]; throw err;})';
}
loaderModules.push(code);
}
// Similar to the comment above, this also used to be skipped when shouldBuildLazily was true,
// however it caused issues where a bundle group contained multiple bundles.
if (bundle.env.context === 'browser') {
loaderModules.push(
...externalBundles
// TODO: Allow css to preload resources as well
.filter(to => to.type === 'js')
.flatMap(from => {
let {preload, prefetch} = getHintedBundleGroups(bundleGraph, from);
return [
...getHintLoaders(
bundleGraph,
bundle,
preload,
BROWSER_PRELOAD_LOADER,
options,
),
...getHintLoaders(
bundleGraph,
bundle,
prefetch,
BROWSER_PREFETCH_LOADER,
options,
),
];
}),
);
}
if (loaderModules.length === 0) {
return;
}
let loaderCode = loaderModules.join(', ');
if (loaderModules.length > 1) {
loaderCode = `Promise.all([${loaderCode}])`;
} else {
loaderCode = `(${loaderCode})`;
}
if (mainBundle.type === 'js') {
let parcelRequire = bundle.env.shouldScopeHoist
? 'parcelRequire'
: 'module.bundle.root';
loaderCode += `.then(() => ${parcelRequire}('${bundleGraph.getAssetPublicId(
bundleGraph.getAssetById(bundleGroup.entryAssetId),
)}'))`;
}
let code = [];
if (needsEsmLoadPrelude) {
code.push(`let load = require('./helpers/browser/esm-js-loader');`);
}
code.push(`module.exports = ${loaderCode};`);
return {
filePath: __filename,
code: code.join('\n'),
dependency,
env: {sourceType: 'module'},
};
}
function getHintedBundleGroups(
bundleGraph: BundleGraph<NamedBundle>,
bundle: NamedBundle,
): {|preload: Array<BundleGroup>, prefetch: Array<BundleGroup>|} {
let preload = [];
let prefetch = [];
let {asyncDependencies} = getDependencies(bundle);
for (let dependency of asyncDependencies) {
let attributes = dependency.meta?.importAttributes;
if (
typeof attributes === 'object' &&
attributes != null &&
// $FlowFixMe
(attributes.preload || attributes.prefetch)
) {
let resolved = bundleGraph.resolveAsyncDependency(dependency, bundle);
if (resolved?.type === 'bundle_group') {
// === true for flow
if (attributes.preload === true) {
preload.push(resolved.value);
}
if (attributes.prefetch === true) {
prefetch.push(resolved.value);
}
}
}
}
return {preload, prefetch};
}
function getHintLoaders(
bundleGraph: BundleGraph<NamedBundle>,
from: NamedBundle,
bundleGroups: Array<BundleGroup>,
loader: string,
options: PluginOptions,
): Array<string> {
let hintLoaders = [];
for (let bundleGroupToPreload of bundleGroups) {
let bundlesToPreload =
bundleGraph.getBundlesInBundleGroup(bundleGroupToPreload);
for (let bundleToPreload of bundlesToPreload) {
let relativePathExpr = getRelativePathExpr(
from,
bundleToPreload,
options,
);
let priority = TYPE_TO_RESOURCE_PRIORITY[bundleToPreload.type];
hintLoaders.push(
`require(${JSON.stringify(loader)})(${getAbsoluteUrlExpr(
relativePathExpr,
from,
)}, ${priority ? JSON.stringify(priority) : 'null'}, ${JSON.stringify(
bundleToPreload.target.env.outputFormat === 'esmodule',
)})`,
);
}
}
return hintLoaders;
}
function isNewContext(
bundle: NamedBundle,
bundleGraph: BundleGraph<NamedBundle>,
): boolean {
let parents = bundleGraph.getParentBundles(bundle);
let isInEntryBundleGroup = bundleGraph
.getBundleGroupsContainingBundle(bundle)
.some(g => bundleGraph.isEntryBundleGroup(g));
return (
isInEntryBundleGroup ||
parents.length === 0 ||
parents.some(
parent =>
parent.env.context !== bundle.env.context || parent.type !== 'js',
)
);
}
function getURLRuntime(
dependency: Dependency,
from: NamedBundle,
to: NamedBundle,
options: PluginOptions,
): RuntimeAsset {
let relativePathExpr = getRelativePathExpr(from, to, options);
let code;
if (dependency.meta.webworker === true && !from.env.isLibrary) {
code = `let workerURL = require('./helpers/get-worker-url');\n`;
if (
from.env.outputFormat === 'esmodule' &&
from.env.supports('import-meta-url')
) {
code += `let url = new __parcel__URL__(${relativePathExpr});\n`;
code += `module.exports = workerURL(url.toString(), url.origin, ${String(
from.env.outputFormat === 'esmodule',
)});`;
} else {
code += `let bundleURL = require('./helpers/bundle-url');\n`;
code += `let url = bundleURL.getBundleURL('${from.publicId}') + ${relativePathExpr};`;
code += `module.exports = workerURL(url, bundleURL.getOrigin(url), ${String(
from.env.outputFormat === 'esmodule',
)});`;
}
} else {
code = `module.exports = ${getAbsoluteUrlExpr(relativePathExpr, from)};`;
}
return {
filePath: __filename,
code,
dependency,
env: {sourceType: 'module'},
};
}
function getRegisterCode(
entryBundle: NamedBundle,
bundleGraph: BundleGraph<NamedBundle>,
): string {
let mappings = [];
bundleGraph.traverseBundles((bundle, _, actions) => {
if (bundle.bundleBehavior === 'inline') {
return;
}
// To make the manifest as small as possible all bundle key/values are
// serialised into a single array e.g. ['id', 'value', 'id2', 'value2'].
// `./helpers/bundle-manifest` accounts for this by iterating index by 2
mappings.push(
bundle.publicId,
relativeBundlePath(entryBundle, nullthrows(bundle), {
leadingDotSlash: false,
}),
);
if (bundle !== entryBundle && isNewContext(bundle, bundleGraph)) {
for (let referenced of bundleGraph.getReferencedBundles(bundle)) {
mappings.push(
referenced.publicId,
relativeBundlePath(entryBundle, nullthrows(referenced), {
leadingDotSlash: false,
}),
);
}
// New contexts have their own manifests, so there's no need to continue.
actions.skipChildren();
}
}, entryBundle);
let baseUrl =
entryBundle.env.outputFormat === 'esmodule' &&
entryBundle.env.supports('import-meta-url')
? 'new __parcel__URL__("").toString()' // <-- this isn't ideal. We should use `import.meta.url` directly but it gets replaced currently
: `require('./helpers/bundle-url').getBundleURL('${entryBundle.publicId}')`;
return `require('./helpers/bundle-manifest').register(${baseUrl},JSON.parse(${JSON.stringify(
JSON.stringify(mappings),
)}));`;
}
function getRelativePathExpr(
from: NamedBundle,
to: NamedBundle,
options: PluginOptions,
): string {
let relativePath = relativeBundlePath(from, to, {leadingDotSlash: false});
let res = JSON.stringify(relativePath);
if (options.hmrOptions) {
res += ' + "?" + Date.now()';
}
return res;
}
function getAbsoluteUrlExpr(relativePathExpr: string, bundle: NamedBundle) {
if (
(bundle.env.outputFormat === 'esmodule' &&
bundle.env.supports('import-meta-url')) ||
bundle.env.outputFormat === 'commonjs'
) {
// This will be compiled to new URL(url, import.meta.url) or new URL(url, 'file:' + __filename).
return `new __parcel__URL__(${relativePathExpr}).toString()`;
} else {
return `require('./helpers/bundle-url').getBundleURL('${bundle.publicId}') + ${relativePathExpr}`;
}
}
function shouldUseRuntimeManifest(
bundle: NamedBundle,
options: PluginOptions,
): boolean {
let env = bundle.env;
return (
!env.isLibrary &&
bundle.bundleBehavior !== 'inline' &&
env.isBrowser() &&
options.mode === 'production'
);
}
function getManifestBundlePriority(
bundleGraph: BundleGraph<NamedBundle>,
bundle: NamedBundle,
threshold: number,
): $PropertyType<RuntimeAsset, 'priority'> {
let bundleSize = 0;
bundle.traverseAssets((asset, _, actions) => {
bundleSize += asset.stats.size;
if (bundleSize > threshold) {
actions.stop();
}
});
return bundleSize > threshold ? 'parallel' : 'sync';
}

View File

@@ -0,0 +1,9 @@
{
"presets": [
["@babel/preset-env", {
"targets": {
"ie": 11
}
}]
]
}

View File

@@ -0,0 +1,3 @@
{
"extends": "@parcel/eslint-config-browser"
}

View File

@@ -0,0 +1,32 @@
const cacheLoader = require('../cacheLoader');
module.exports = cacheLoader(function loadCSSBundle(bundle) {
return new Promise(function (resolve, reject) {
// Don't insert the same link element twice (e.g. if it was already in the HTML)
let existingLinks = document.getElementsByTagName('link');
let isCurrentBundle = function (link) {
return link.href === bundle && link.rel.indexOf('stylesheet') > -1;
};
if ([].concat(existingLinks).some(isCurrentBundle)) {
resolve();
return;
}
var link = document.createElement('link');
link.rel = 'stylesheet';
link.href = bundle;
link.onerror = function (e) {
link.onerror = link.onload = null;
link.remove();
reject(e);
};
link.onload = function () {
link.onerror = link.onload = null;
resolve();
};
document.getElementsByTagName('head')[0].appendChild(link);
});
});

View File

@@ -0,0 +1,6 @@
function load(id) {
// eslint-disable-next-line no-undef
return __parcel__import__(require('../bundle-manifest').resolve(id));
}
module.exports = load;

View File

@@ -0,0 +1,7 @@
const cacheLoader = require('../cacheLoader');
module.exports = cacheLoader(function loadHTMLBundle(bundle) {
return fetch(bundle).then(function (res) {
return res.text();
});
});

View File

@@ -0,0 +1,32 @@
const cacheLoader = require('../cacheLoader');
module.exports = cacheLoader(function importModule(bundle) {
return new Promise((resolve, reject) => {
// Add a global function to handle when the script loads.
let globalName = `i${('' + Math.random()).slice(2)}`;
global[globalName] = m => {
resolve(m);
cleanup();
};
// Remove script on load or error
let cleanup = () => {
delete global[globalName];
script.onerror = null;
script.remove();
};
// Append an inline script tag into the document head
let script = document.createElement('script');
script.async = true;
script.type = 'module';
script.charset = 'utf-8';
script.textContent = `import * as m from '${bundle}'; ${globalName}(m);`;
script.onerror = function (e) {
reject(e);
cleanup();
};
document.head.appendChild(script);
});
});

View File

@@ -0,0 +1,42 @@
const cacheLoader = require('../cacheLoader');
module.exports = cacheLoader(function loadJSBundle(bundle) {
return new Promise(function (resolve, reject) {
// Don't insert the same script twice (e.g. if it was already in the HTML)
let existingScripts = document.getElementsByTagName('script');
let isCurrentBundle = function (script) {
return script.src === bundle;
};
if ([].concat(existingScripts).some(isCurrentBundle)) {
resolve();
return;
}
var preloadLink = document.createElement('link');
preloadLink.href = bundle;
preloadLink.rel = 'preload';
preloadLink.as = 'script';
document.head.appendChild(preloadLink);
var script = document.createElement('script');
script.async = true;
script.type = 'text/javascript';
script.src = bundle;
script.onerror = function (e) {
var error = new TypeError(
`Failed to fetch dynamically imported module: ${bundle}. Error: ${e.message}`,
);
script.onerror = script.onload = null;
script.remove();
reject(error);
};
script.onload = function () {
script.onerror = script.onload = null;
resolve();
};
document.getElementsByTagName('head')[0].appendChild(script);
});
});

View File

@@ -0,0 +1,13 @@
const cacheLoader = require('../cacheLoader');
module.exports = cacheLoader(function prefetchJSBundle(bundle, priority) {
var link = document.createElement('link');
link.rel = 'prefetch';
link.href = bundle;
if (priority) {
link.as = priority;
}
document.getElementsByTagName('head')[0].appendChild(link);
return Promise.resolve();
}, 'prefetch');

View File

@@ -0,0 +1,19 @@
const cacheLoader = require('../cacheLoader');
module.exports = cacheLoader(function preloadJSBundle(
bundle,
priority,
isModule,
) {
var link = document.createElement('link');
link.charset = 'utf-8';
link.rel = isModule ? 'modulepreload' : 'preload';
link.href = bundle;
if (priority) {
link.as = priority;
}
document.getElementsByTagName('head')[0].appendChild(link);
return Promise.resolve();
},
'preload');

View File

@@ -0,0 +1,17 @@
const cacheLoader = require('../cacheLoader');
module.exports = cacheLoader(function loadWASMBundle(bundle) {
return fetch(bundle)
.then(function (res) {
if (WebAssembly.instantiateStreaming) {
return WebAssembly.instantiateStreaming(res);
} else {
return res.arrayBuffer().then(function (data) {
return WebAssembly.instantiate(data);
});
}
})
.then(function (wasmModule) {
return wasmModule.instance.exports;
});
});

View File

@@ -0,0 +1,21 @@
var mapping = new Map();
function register(baseUrl, manifest) {
for (var i = 0; i < manifest.length - 1; i += 2) {
mapping.set(manifest[i], {
baseUrl: baseUrl,
path: manifest[i + 1],
});
}
}
function resolve(id) {
var resolved = mapping.get(id);
if (resolved == null) {
throw new Error('Could not resolve bundle with id ' + id);
}
return new URL(resolved.path, resolved.baseUrl).toString();
}
module.exports.register = register;
module.exports.resolve = resolve;

View File

@@ -0,0 +1,51 @@
var bundleURL = {};
function getBundleURLCached(id) {
var value = bundleURL[id];
if (!value) {
value = getBundleURL();
bundleURL[id] = value;
}
return value;
}
function getBundleURL() {
try {
throw new Error();
} catch (err) {
var matches = ('' + err.stack).match(
/(https?|file|ftp|(chrome|moz|safari-web)-extension):\/\/[^)\n]+/g,
);
if (matches) {
// The first two stack frames will be this function and getBundleURLCached.
// Use the 3rd one, which will be a runtime in the original bundle.
return getBaseURL(matches[2]);
}
}
return '/';
}
function getBaseURL(url) {
return (
('' + url).replace(
/^((?:https?|file|ftp|(chrome|moz|safari-web)-extension):\/\/.+)\/[^/]+$/,
'$1',
) + '/'
);
}
// TODO: Replace uses with `new URL(url).origin` when ie11 is no longer supported.
function getOrigin(url) {
let matches = ('' + url).match(
/(https?|file|ftp|(chrome|moz|safari-web)-extension):\/\/[^/]+/,
);
if (!matches) {
throw new Error('Origin not found');
}
return matches[0];
}
exports.getBundleURL = getBundleURLCached;
exports.getBaseURL = getBaseURL;
exports.getOrigin = getOrigin;

View File

@@ -0,0 +1,29 @@
let cachedBundles = {};
let cachedPreloads = {};
let cachedPrefetches = {};
function getCache(type) {
switch (type) {
case 'preload':
return cachedPreloads;
case 'prefetch':
return cachedPrefetches;
default:
return cachedBundles;
}
}
module.exports = function cacheLoader(loader, type) {
return function (bundle) {
let cache = getCache(type);
if (cache[bundle]) {
return cache[bundle];
}
return (cache[bundle] = loader.apply(null, arguments).catch(function (e) {
delete cache[bundle];
throw e;
}));
};
};

View File

@@ -0,0 +1,15 @@
module.exports = function loadWorker(workerUrl, origin, isESM) {
if (origin === self.location.origin) {
// If the worker bundle's url is on the same origin as the document,
// use the worker bundle's own url.
return workerUrl;
} else {
// Otherwise, create a blob URL which loads the worker bundle with `importScripts`.
let source = isESM
? 'import ' + JSON.stringify(workerUrl) + ';'
: 'importScripts(' + JSON.stringify(workerUrl) + ');';
return URL.createObjectURL(
new Blob([source], {type: 'application/javascript'}),
);
}
};

View File

@@ -0,0 +1,4 @@
// loading a CSS style is a no-op in Node.js
module.exports = function loadCSSBundle() {
return Promise.resolve();
};

View File

@@ -0,0 +1,18 @@
const fs = require('fs');
const cacheLoader = require('../cacheLoader');
module.exports = cacheLoader(function loadHTMLBundle(bundle) {
return new Promise(function (resolve, reject) {
fs.readFile(__dirname + bundle, 'utf8', function (err, data) {
if (err) {
reject(err);
} else {
// wait for the next event loop iteration, so we are sure
// the current module is fully loaded
setImmediate(function () {
resolve(data);
});
}
});
});
});

View File

@@ -0,0 +1,20 @@
const fs = require('fs');
const cacheLoader = require('../cacheLoader');
module.exports = cacheLoader(function loadJSBundle(bundle) {
return new Promise(function (resolve, reject) {
fs.readFile(__dirname + bundle, 'utf8', function (err, data) {
if (err) {
reject(err);
} else {
// wait for the next event loop iteration, so we are sure
// the current module is fully loaded
setImmediate(function () {
resolve(data);
});
}
});
}).then(function (code) {
new Function('', code)();
});
});

View File

@@ -0,0 +1,20 @@
const fs = require('fs');
const cacheLoader = require('../cacheLoader');
module.exports = cacheLoader(function loadWASMBundle(bundle) {
return new Promise(function (resolve, reject) {
fs.readFile(__dirname + bundle, function (err, data) {
if (err) {
reject(err);
} else {
resolve(data.buffer);
}
});
})
.then(function (data) {
return WebAssembly.instantiate(data);
})
.then(function (wasmModule) {
return wasmModule.instance.exports;
});
});

View File

@@ -0,0 +1,13 @@
/* global __parcel__importScripts__:readonly*/
const cacheLoader = require('../cacheLoader');
module.exports = cacheLoader(function loadJSBundle(bundle) {
return new Promise(function (resolve, reject) {
try {
__parcel__importScripts__(bundle);
resolve();
} catch (e) {
reject(e);
}
});
});

View File

@@ -0,0 +1,17 @@
const cacheLoader = require('../cacheLoader');
module.exports = cacheLoader(function loadWASMBundle(bundle) {
return fetch(bundle)
.then(function (res) {
if (WebAssembly.instantiateStreaming) {
return WebAssembly.instantiateStreaming(res);
} else {
return res.arrayBuffer().then(function (data) {
return WebAssembly.instantiate(data);
});
}
})
.then(function (wasmModule) {
return wasmModule.instance.exports;
});
});