UNPKG

@jbrowse/core

Version:

JBrowse 2 core libraries used by plugins

132 lines (131 loc) 4.84 kB
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;