@jbrowse/core
Version:
JBrowse 2 core libraries used by plugins
97 lines (96 loc) • 3.9 kB
JavaScript
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,
};
});
}