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,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;
});
});