@jbrowse/core
Version:
JBrowse 2 core libraries used by plugins
132 lines (131 loc) • 4.84 kB
JavaScript
import { addDisposer, getParent, types } from '@jbrowse/mobx-state-tree';
import { reaction } from 'mobx';
import assemblyFactory from "./assembly.js";
import { readConfObject } from "../configuration/index.js";
import { when } from "../util/index.js";
function assemblyManagerFactory(conf, pm) {
return types
.model({
assemblies: types.array(assemblyFactory(conf, pm)),
})
.views(self => ({
get assemblyNameMap() {
const obj = {};
for (const assembly of self.assemblies) {
for (const name of assembly.allAliases) {
obj[name] = assembly;
}
}
return obj;
},
}))
.views(self => ({
getCanonicalAssemblyName(asmName) {
return self.assemblyNameMap[asmName]?.name;
},
getCanonicalAssemblyName2(asmName) {
return self.assemblyNameMap[asmName]?.name || asmName;
},
get(asmName) {
if (asmName) {
const assembly = self.assemblyNameMap[asmName];
if (assembly) {
return assembly;
}
else if (!this.assemblyNamesList.includes(asmName)) {
pm.evaluateExtensionPoint('Core-handleUnrecognizedAssembly', undefined, {
assemblyName: asmName,
session: getParent(self).session,
});
}
}
return undefined;
},
get assemblyNamesList() {
return this.assemblyList.map(asm => asm.name);
},
get assemblyList() {
const { jbrowse: { assemblies }, session: { sessionAssemblies = [], temporaryAssemblies = [] } = {}, } = getParent(self);
return [
...assemblies,
...sessionAssemblies,
...temporaryAssemblies,
];
},
get rpcManager() {
return getParent(self).rpcManager;
},
}))
.views(self => ({
async waitForAssembly(assemblyName) {
if (!assemblyName) {
throw new Error('no assembly name supplied to waitForAssembly');
}
let assembly = self.get(assemblyName);
if (!assembly) {
try {
await when(() => Boolean(self.get(assemblyName)), {
timeout: 10000,
});
assembly = self.get(assemblyName);
}
catch (e) {
}
}
if (!assembly) {
return undefined;
}
await assembly.load();
await when(() => !!(assembly.regions && assembly.refNameAliases) || !!assembly.error);
if (assembly.error) {
throw assembly.error;
}
return assembly;
},
async getRefNameMapForAdapter(adapterConf, assemblyName, opts) {
if (assemblyName) {
const asm = await this.waitForAssembly(assemblyName);
return asm?.getRefNameMapForAdapter(adapterConf, opts);
}
return {};
},
async getReverseRefNameMapForAdapter(adapterConf, assemblyName, opts) {
if (assemblyName) {
const asm = await this.waitForAssembly(assemblyName);
return asm?.getReverseRefNameMapForAdapter(adapterConf, opts);
}
return {};
},
isValidRefName(refName, assemblyName) {
const assembly = self.get(assemblyName);
if (assembly) {
return assembly.isValidRefName(refName);
}
throw new Error(`Failed to look up refName:${refName} on assemblyName:${assemblyName} (assembly does not exist)`);
},
}))
.actions(self => ({
afterAttach() {
addDisposer(self, reaction(() => self.assemblyList, assemblyConfs => {
for (const asm of self.assemblies) {
if (!asm.configuration) {
this.removeAssembly(asm);
}
}
for (const conf of assemblyConfs) {
const name = readConfObject(conf, 'name');
if (!self.assemblies.some(a => a.name === name)) {
this.addAssembly(conf);
}
}
}, { fireImmediately: true, name: 'assemblyManagerAfterAttach' }));
},
removeAssembly(asm) {
self.assemblies.remove(asm);
},
addAssembly(configuration) {
self.assemblies.push({ configuration });
},
}));
}
export default assemblyManagerFactory;