UNPKG

@jbrowse/core

Version:

JBrowse 2 core libraries used by plugins

97 lines (96 loc) 3.9 kB
import { addDisposer, types } from '@jbrowse/mobx-state-tree'; import { autorun } from 'mobx'; import { getConf } from "../configuration/index.js"; import { getSession } from "../util/index.js"; import { SequenceFeatureDetailsF } from "./SequenceFeatureDetails/model.js"; import { formatSubfeatures } from "./util.js"; import { ElementId } from "../util/types/mst.js"; export function stateModelFactory(pluginManager) { return types .model('BaseFeatureWidget', { id: ElementId, type: types.literal('BaseFeatureWidget'), featureData: types.frozen(), formattedFields: types.frozen(), unformattedFeatureData: types.frozen(), view: types.safeReference(pluginManager.pluggableMstType('view', 'stateModel')), track: types.safeReference(pluginManager.pluggableMstType('track', 'stateModel')), trackId: types.maybe(types.string), trackType: types.maybe(types.string), maxDepth: types.maybe(types.number), sequenceFeatureDetails: types.optional(SequenceFeatureDetailsF(), {}), descriptions: types.frozen(), }) .volatile(() => ({ error: undefined, })) .actions(self => ({ setFeatureData(featureData) { self.unformattedFeatureData = featureData; }, clearFeatureData() { self.featureData = undefined; }, setFormattedData(feat) { self.featureData = feat; }, setExtra(type, trackId, maxDepth) { self.trackId = trackId; self.trackType = type; self.maxDepth = maxDepth; }, setError(e) { self.error = e; }, })) .actions(self => ({ afterCreate() { addDisposer(self, autorun(function featureWidgetAutorun() { try { const { unformattedFeatureData, track } = self; const session = getSession(self); if (track) { self.setExtra(track.type, track.configuration.trackId, getConf(track, ['formatDetails', 'maxDepth'])); } if (unformattedFeatureData) { const feature = structuredClone(unformattedFeatureData); const combine = (arg2, feature) => ({ ...getConf(session, ['formatDetails', arg2], { feature }), ...getConf(track, ['formatDetails', arg2], { feature }), }); if (track) { feature.__jbrowsefmt = combine('feature', feature); formatSubfeatures(feature, getConf(track, ['formatDetails', 'depth']), sub => { sub.__jbrowsefmt = combine('subfeatures', sub); }); } self.setFormattedData(feature); } } catch (e) { console.error(e); self.setError(e); } }, { name: 'FeatureWidget' })); }, })) .preProcessSnapshot(snap => { const { featureData, finalizedFeatureData, ...rest } = snap; return { unformattedFeatureData: featureData, featureData: finalizedFeatureData, ...rest, }; }) .postProcessSnapshot(snap => { const { unformattedFeatureData, featureData, ...rest } = snap; const s2 = JSON.stringify(featureData, (_, v) => v === undefined ? null : v); const featureTooLargeToBeSerialized = !s2 || s2.length > 2_000_000; return { finalizedFeatureData: featureTooLargeToBeSerialized ? undefined : JSON.parse(s2), ...rest, }; }); }