jbrowse-plugin-protein3d 0.5.0 → 0.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/LaunchProteinViewExtensionPoint/index.js +2 -1
- package/dist/ProteinView/model.d.ts +30 -0
- package/dist/ProteinView/structureModel.d.ts +18 -0
- package/dist/ProteinView/structureModel.js +35 -7
- package/dist/ProteinView/useProteinView.js +9 -1
- package/dist/jbrowse-plugin-protein3d.umd.production.min.js +11 -11
- package/dist/jbrowse-plugin-protein3d.umd.production.min.js.map +3 -3
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +1 -1
- package/src/LaunchProteinViewExtensionPoint/index.ts +6 -0
- package/src/ProteinView/structureModel.ts +38 -8
- package/src/ProteinView/useProteinView.ts +9 -0
- package/src/version.ts +1 -1
|
@@ -7,7 +7,7 @@ export default function LaunchProteinViewExtensionPointF(pluginManager) {
|
|
|
7
7
|
// handlers and ignores the return value. Casting away the signature
|
|
8
8
|
// mismatch rather than fabricating a fake return.
|
|
9
9
|
// @ts-expect-error
|
|
10
|
-
async ({ session, url, uniprotId, transcriptId, userProvidedTranscriptSequence, feature, connectedViewId, connectedView, alignmentAlgorithm, displayName, height, showControls, showHighlight, zoomToBaseLevel, sideBySide, }) => {
|
|
10
|
+
async ({ session, url, uniprotId, transcriptId, userProvidedTranscriptSequence, feature, connectedViewId, connectedView, alignmentAlgorithm, displayName, height, showControls, showHighlight, zoomToBaseLevel, sideBySide, initialSelection, }) => {
|
|
11
11
|
// Short-URL form: `uniprotId` + `transcriptId` + `connectedView` (no
|
|
12
12
|
// explicit `url`/`feature`/sequence). Derive the structure URL, the
|
|
13
13
|
// transcript feature, and the translated sequence from the connected
|
|
@@ -67,6 +67,7 @@ export default function LaunchProteinViewExtensionPointF(pluginManager) {
|
|
|
67
67
|
'',
|
|
68
68
|
feature: resolved?.feature ?? feature,
|
|
69
69
|
connectedViewId: resolvedConnectedViewId,
|
|
70
|
+
initialSelection,
|
|
70
71
|
},
|
|
71
72
|
],
|
|
72
73
|
});
|
|
@@ -29,6 +29,16 @@ declare function stateModelFactory(): import("@jbrowse/mobx-state-tree").IModelT
|
|
|
29
29
|
pairwiseAlignment: import("@jbrowse/mobx-state-tree").IType<import("../mappings").PairwiseAlignment | undefined, import("../mappings").PairwiseAlignment | undefined, import("../mappings").PairwiseAlignment | undefined>;
|
|
30
30
|
feature: import("@jbrowse/mobx-state-tree").IType<import("@jbrowse/core/util").SimpleFeatureSerialized | undefined, import("@jbrowse/core/util").SimpleFeatureSerialized | undefined, import("@jbrowse/core/util").SimpleFeatureSerialized | undefined>;
|
|
31
31
|
userProvidedTranscriptSequence: import("@jbrowse/mobx-state-tree").ISimpleType<string>;
|
|
32
|
+
initialSelection: import("@jbrowse/mobx-state-tree").IType<{
|
|
33
|
+
start: number;
|
|
34
|
+
end: number;
|
|
35
|
+
} | undefined, {
|
|
36
|
+
start: number;
|
|
37
|
+
end: number;
|
|
38
|
+
} | undefined, {
|
|
39
|
+
start: number;
|
|
40
|
+
end: number;
|
|
41
|
+
} | undefined>;
|
|
32
42
|
}, {
|
|
33
43
|
clickedStructureRange: {
|
|
34
44
|
start: number;
|
|
@@ -767,6 +777,16 @@ declare function stateModelFactory(): import("@jbrowse/mobx-state-tree").IModelT
|
|
|
767
777
|
pairwiseAlignment: import("@jbrowse/mobx-state-tree").IType<import("../mappings").PairwiseAlignment | undefined, import("../mappings").PairwiseAlignment | undefined, import("../mappings").PairwiseAlignment | undefined>;
|
|
768
778
|
feature: import("@jbrowse/mobx-state-tree").IType<import("@jbrowse/core/util").SimpleFeatureSerialized | undefined, import("@jbrowse/core/util").SimpleFeatureSerialized | undefined, import("@jbrowse/core/util").SimpleFeatureSerialized | undefined>;
|
|
769
779
|
userProvidedTranscriptSequence: import("@jbrowse/mobx-state-tree").ISimpleType<string>;
|
|
780
|
+
initialSelection: import("@jbrowse/mobx-state-tree").IType<{
|
|
781
|
+
start: number;
|
|
782
|
+
end: number;
|
|
783
|
+
} | undefined, {
|
|
784
|
+
start: number;
|
|
785
|
+
end: number;
|
|
786
|
+
} | undefined, {
|
|
787
|
+
start: number;
|
|
788
|
+
end: number;
|
|
789
|
+
} | undefined>;
|
|
770
790
|
}> & {
|
|
771
791
|
clickedStructureRange: {
|
|
772
792
|
start: number;
|
|
@@ -1384,6 +1404,16 @@ declare function stateModelFactory(): import("@jbrowse/mobx-state-tree").IModelT
|
|
|
1384
1404
|
pairwiseAlignment: import("@jbrowse/mobx-state-tree").IType<import("../mappings").PairwiseAlignment | undefined, import("../mappings").PairwiseAlignment | undefined, import("../mappings").PairwiseAlignment | undefined>;
|
|
1385
1405
|
feature: import("@jbrowse/mobx-state-tree").IType<import("@jbrowse/core/util").SimpleFeatureSerialized | undefined, import("@jbrowse/core/util").SimpleFeatureSerialized | undefined, import("@jbrowse/core/util").SimpleFeatureSerialized | undefined>;
|
|
1386
1406
|
userProvidedTranscriptSequence: import("@jbrowse/mobx-state-tree").ISimpleType<string>;
|
|
1407
|
+
initialSelection: import("@jbrowse/mobx-state-tree").IType<{
|
|
1408
|
+
start: number;
|
|
1409
|
+
end: number;
|
|
1410
|
+
} | undefined, {
|
|
1411
|
+
start: number;
|
|
1412
|
+
end: number;
|
|
1413
|
+
} | undefined, {
|
|
1414
|
+
start: number;
|
|
1415
|
+
end: number;
|
|
1416
|
+
} | undefined>;
|
|
1387
1417
|
}, {
|
|
1388
1418
|
clickedStructureRange: {
|
|
1389
1419
|
start: number;
|
|
@@ -48,6 +48,24 @@ declare const Structure: import("@jbrowse/mobx-state-tree").IModelType<{
|
|
|
48
48
|
* #property
|
|
49
49
|
*/
|
|
50
50
|
userProvidedTranscriptSequence: import("@jbrowse/mobx-state-tree").ISimpleType<string>;
|
|
51
|
+
/**
|
|
52
|
+
* #property
|
|
53
|
+
* Declarative seed for the persistent domain selection: a 0-based,
|
|
54
|
+
* half-open structure-residue range `{ start, end }` lit on load exactly as
|
|
55
|
+
* if the user had clicked that domain — magenta in the 3D structure, a band
|
|
56
|
+
* on the connected genome view, and the range in the alignment. Lets a
|
|
57
|
+
* session spec open with a domain pre-highlighted, with no click.
|
|
58
|
+
*/
|
|
59
|
+
initialSelection: import("@jbrowse/mobx-state-tree").IType<{
|
|
60
|
+
start: number;
|
|
61
|
+
end: number;
|
|
62
|
+
} | undefined, {
|
|
63
|
+
start: number;
|
|
64
|
+
end: number;
|
|
65
|
+
} | undefined, {
|
|
66
|
+
start: number;
|
|
67
|
+
end: number;
|
|
68
|
+
} | undefined>;
|
|
51
69
|
}, {
|
|
52
70
|
/**
|
|
53
71
|
* #volatile
|
|
@@ -41,6 +41,15 @@ const Structure = types
|
|
|
41
41
|
* #property
|
|
42
42
|
*/
|
|
43
43
|
userProvidedTranscriptSequence: types.string,
|
|
44
|
+
/**
|
|
45
|
+
* #property
|
|
46
|
+
* Declarative seed for the persistent domain selection: a 0-based,
|
|
47
|
+
* half-open structure-residue range `{ start, end }` lit on load exactly as
|
|
48
|
+
* if the user had clicked that domain — magenta in the 3D structure, a band
|
|
49
|
+
* on the connected genome view, and the range in the alignment. Lets a
|
|
50
|
+
* session spec open with a domain pre-highlighted, with no click.
|
|
51
|
+
*/
|
|
52
|
+
initialSelection: types.frozen(),
|
|
44
53
|
})
|
|
45
54
|
.volatile(() => ({
|
|
46
55
|
/**
|
|
@@ -562,6 +571,16 @@ const Structure = types
|
|
|
562
571
|
}))
|
|
563
572
|
.actions(self => ({
|
|
564
573
|
afterAttach() {
|
|
574
|
+
// Seed the persistent selection from a declarative `initialSelection`, so
|
|
575
|
+
// a session spec can open with a domain pre-lit. clickedStructureRange is
|
|
576
|
+
// the single source of truth the 3D/genome/alignment highlights derive
|
|
577
|
+
// from; the genome-band and alignment getters recompute reactively once
|
|
578
|
+
// the connected view + mapping resolve, and the molstar select autorun
|
|
579
|
+
// below lights it once the structure loads. A later user click overwrites
|
|
580
|
+
// it normally.
|
|
581
|
+
if (self.initialSelection) {
|
|
582
|
+
self.setClickedStructureRange(self.initialSelection);
|
|
583
|
+
}
|
|
565
584
|
// Re-subscribe to a molstar click/hover behavior whenever the plugin
|
|
566
585
|
// becomes available; the subscription is disposed with the model.
|
|
567
586
|
const addInteractionListener = (kind, onUpdate) => {
|
|
@@ -641,8 +660,15 @@ const Structure = types
|
|
|
641
660
|
addInteractionListener('hover', info => {
|
|
642
661
|
self.setHoveredPosition(info);
|
|
643
662
|
});
|
|
663
|
+
// Drive the molstar 'select' channel (the persistent magenta selection)
|
|
664
|
+
// reactively from a single source of truth: a clicked/declarative domain
|
|
665
|
+
// range takes priority, else the whole alignment-covered set when
|
|
666
|
+
// showHighlight is on, else nothing. Centralizing it here (rather than
|
|
667
|
+
// only applying the clicked range imperatively from the feature bar) lets
|
|
668
|
+
// a declarative `initialSelection` seed light the 3D structure the same
|
|
669
|
+
// way a click does, with no race against this autorun.
|
|
644
670
|
addDisposer(self, autorun(async () => {
|
|
645
|
-
const { showHighlight, structureSeqToTranscriptSeqPosition, molstarPluginContext, molstarStructure, } = self;
|
|
671
|
+
const { showHighlight, clickedStructureRange, structureSeqToTranscriptSeqPosition, molstarPluginContext, molstarStructure, } = self;
|
|
646
672
|
if (molstarStructure &&
|
|
647
673
|
molstarPluginContext &&
|
|
648
674
|
structureSeqToTranscriptSeqPosition) {
|
|
@@ -650,12 +676,14 @@ const Structure = types
|
|
|
650
676
|
structure: molstarStructure,
|
|
651
677
|
plugin: molstarPluginContext,
|
|
652
678
|
channel: 'select',
|
|
653
|
-
spec:
|
|
654
|
-
? {
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
679
|
+
spec: clickedStructureRange
|
|
680
|
+
? { kind: 'range', ...clickedStructureRange }
|
|
681
|
+
: showHighlight
|
|
682
|
+
? {
|
|
683
|
+
kind: 'list',
|
|
684
|
+
residues: Object.keys(structureSeqToTranscriptSeqPosition).map(coord => +coord),
|
|
685
|
+
}
|
|
686
|
+
: undefined,
|
|
659
687
|
});
|
|
660
688
|
}
|
|
661
689
|
}));
|
|
@@ -17,7 +17,7 @@ export default function useProteinView({ showControls, model, }) {
|
|
|
17
17
|
if (!parentRef.current) {
|
|
18
18
|
return;
|
|
19
19
|
}
|
|
20
|
-
const { GeometryExport, MAQualityAssessment, PluginConfig, PluginSpec, DefaultPluginUISpec, createPluginUI, renderReact18, } = await loadMolstar();
|
|
20
|
+
const { Color, GeometryExport, MAQualityAssessment, PluginConfig, PluginSpec, DefaultPluginUISpec, createPluginUI, renderReact18, } = await loadMolstar();
|
|
21
21
|
const host = document.createElement('div');
|
|
22
22
|
parentRef.current.append(host);
|
|
23
23
|
state.host = host;
|
|
@@ -44,6 +44,14 @@ export default function useProteinView({ showControls, model, }) {
|
|
|
44
44
|
},
|
|
45
45
|
});
|
|
46
46
|
await created.initialized;
|
|
47
|
+
// Make the persistent selection marking clearly visible (a domain
|
|
48
|
+
// click, or a declarative initialSelection): molstar's default select
|
|
49
|
+
// color is a subtle teal that blends into a green/pLDDT cartoon, so a
|
|
50
|
+
// highlighted domain reads as no highlight at all. Magenta contrasts
|
|
51
|
+
// against every built-in color scheme.
|
|
52
|
+
created.canvas3d?.setProps({
|
|
53
|
+
renderer: { selectColor: Color(0xff00ff) },
|
|
54
|
+
});
|
|
47
55
|
if (state.cancelled) {
|
|
48
56
|
created.dispose();
|
|
49
57
|
host.remove();
|