@jbrowse/core
Version:
JBrowse 2 core libraries used by plugins
175 lines (174 loc) • 6.5 kB
JavaScript
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.isUMDPluginDefinition = isUMDPluginDefinition;
exports.isESMPluginDefinition = isESMPluginDefinition;
exports.isCJSPluginDefinition = isCJSPluginDefinition;
exports.pluginDescriptionString = pluginDescriptionString;
exports.pluginUrl = pluginUrl;
const load_script_1 = __importDefault(require("load-script"));
const Plugin_1 = __importDefault(require("./Plugin"));
const ReExports_1 = __importDefault(require("./ReExports"));
const util_1 = require("./util");
function isUMDPluginDefinition(def) {
return ((def.umdUrl !== undefined ||
def.url !== undefined ||
def.umdLoc !== undefined) &&
def.name !== undefined);
}
function isESMPluginDefinition(def) {
return (def.esmUrl !== undefined ||
def.esmLoc !== undefined);
}
function promisifiedLoadScript(src) {
return new Promise((resolve, reject) => {
(0, load_script_1.default)(src, (err, script) => {
if (err) {
reject(err);
}
else {
resolve(script.src);
}
});
});
}
async function loadScript(scriptUrl) {
if (!isInWebWorker()) {
return promisifiedLoadScript(scriptUrl);
}
if (globalThis.importScripts) {
await globalThis.importScripts(scriptUrl);
return;
}
throw new Error('cannot figure out how to load external JS scripts in this environment');
}
function isCJSPluginDefinition(def) {
return def.cjsUrl !== undefined;
}
function pluginDescriptionString(d) {
if (isUMDPluginDefinition(d)) {
return `UMD plugin ${d.name}`;
}
else if (isESMPluginDefinition(d)) {
return `ESM plugin ${d.esmUrl ||
d.esmLoc.uri}`;
}
else if (isCJSPluginDefinition(d)) {
return `CJS plugin ${d.cjsUrl}`;
}
else {
return 'unknown plugin';
}
}
function pluginUrl(d) {
var _a, _b, _c, _d, _e, _f;
if (isUMDPluginDefinition(d)) {
return (_c = (_a = d.url) !== null && _a !== void 0 ? _a : (_b = d.umdLoc) === null || _b === void 0 ? void 0 : _b.uri) !== null && _c !== void 0 ? _c : d.umdUrl;
}
else if (isESMPluginDefinition(d)) {
return (_e = (_d = d.esmUrl) !== null && _d !== void 0 ? _d : d.esmUri) !== null && _e !== void 0 ? _e : (_f = d.esmLoc) === null || _f === void 0 ? void 0 : _f.uri;
}
else if (isCJSPluginDefinition(d)) {
return d.cjsUrl || d.cjsLoc.uri;
}
else {
return 'unknown url';
}
}
function isInWebWorker() {
return Boolean('WorkerGlobalScope' in globalThis);
}
class PluginLoader {
constructor(defs = [], args) {
this.definitions = [];
this.fetchESM = args === null || args === void 0 ? void 0 : args.fetchESM;
this.fetchCJS = args === null || args === void 0 ? void 0 : args.fetchCJS;
this.definitions = JSON.parse(JSON.stringify(defs));
}
async loadCJSPlugin(def, baseUri) {
const parsedUrl = new URL(def.cjsUrl, baseUri);
if (parsedUrl.protocol !== 'http:' && parsedUrl.protocol !== 'https:') {
throw new Error(`Cannot load plugins using protocol "${parsedUrl.protocol}"`);
}
if (!this.fetchCJS) {
throw new Error('No fetchCJS callback provided');
}
return this.fetchCJS(parsedUrl.href);
}
async loadESMPlugin(def, baseUri) {
const parsedUrl = 'esmUrl' in def
? new URL(def.esmUrl, baseUri)
: new URL(def.esmLoc.uri, def.esmLoc.baseUri);
if (parsedUrl.protocol !== 'http:' && parsedUrl.protocol !== 'https:') {
throw new Error(`cannot load plugins using protocol "${parsedUrl.protocol}"`);
}
if (!this.fetchESM) {
throw new Error('No ESM fetcher installed');
}
const plugin = await this.fetchESM(parsedUrl.href);
if (!plugin) {
throw new Error(`Could not load ESM plugin: ${parsedUrl}`);
}
return plugin;
}
async loadUMDPlugin(def, baseUri) {
const parsedUrl = 'url' in def
? new URL(def.url, baseUri)
: 'umdUrl' in def
? new URL(def.umdUrl, baseUri)
: new URL(def.umdLoc.uri, def.umdLoc.baseUri);
if (parsedUrl.protocol !== 'http:' && parsedUrl.protocol !== 'https:') {
throw new Error(`cannot load plugins using protocol "${parsedUrl.protocol}"`);
}
const moduleName = def.name;
const umdName = `JBrowsePlugin${moduleName}`;
if (typeof jest === 'undefined') {
await loadScript(parsedUrl.href);
}
else {
globalThis[umdName] = { default: Plugin_1.default };
}
const plugin = globalThis[umdName];
if (!plugin) {
throw new Error(`Failed to load UMD bundle for ${moduleName}, ${umdName} is undefined`);
}
return plugin;
}
async loadPlugin(def, baseUri) {
let plugin;
if (util_1.isElectron && isCJSPluginDefinition(def)) {
plugin = await this.loadCJSPlugin(def, baseUri);
}
else if (isESMPluginDefinition(def)) {
plugin = await this.loadESMPlugin(def, baseUri);
}
else if (isUMDPluginDefinition(def)) {
plugin = await this.loadUMDPlugin(def, baseUri);
}
else if (!util_1.isElectron && isCJSPluginDefinition(def)) {
throw new Error(`CommonJS plugin found, but not in a NodeJS environment: ${JSON.stringify(def)}`);
}
else {
throw new Error(`Could not determine plugin type: ${JSON.stringify(def)}`);
}
if (!plugin.default) {
throw new Error(`${pluginDescriptionString(def)} does not have a default export, cannot load`);
}
return plugin.default;
}
installGlobalReExports(target) {
target.JBrowseExports = Object.fromEntries(Object.entries(ReExports_1.default).map(([moduleName, module]) => {
return [moduleName, module];
}));
return this;
}
async load(baseUri) {
return Promise.all(this.definitions.map(async (definition) => ({
plugin: await this.loadPlugin(definition, baseUri),
definition,
})));
}
}
exports.default = PluginLoader;
;