@apollo-annotation/jbrowse-plugin-apollo 0.3.8 → 0.3.9
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/index.esm.js +10932 -10932
- package/dist/index.esm.js.map +1 -1
- package/dist/jbrowse-plugin-apollo.cjs.development.js +10845 -10846
- package/dist/jbrowse-plugin-apollo.cjs.development.js.map +1 -1
- package/dist/jbrowse-plugin-apollo.cjs.production.min.js +1 -1
- package/dist/jbrowse-plugin-apollo.cjs.production.min.js.map +1 -1
- package/dist/jbrowse-plugin-apollo.umd.development.js +18619 -21342
- package/dist/jbrowse-plugin-apollo.umd.development.js.map +1 -1
- package/dist/jbrowse-plugin-apollo.umd.production.min.js +1 -1
- package/dist/jbrowse-plugin-apollo.umd.production.min.js.map +1 -1
- package/package.json +7 -7
- package/src/ApolloInternetAccount/model.ts +81 -63
- package/src/ApolloRefNameAliasAdapter/ApolloRefNameAliasAdapter.ts +4 -4
- package/src/ApolloSequenceAdapter/ApolloSequenceAdapter.ts +9 -7
- package/src/BackendDrivers/CollaborationServerDriver.ts +49 -18
- package/src/BackendDrivers/DesktopFileDriver.ts +2 -2
- package/src/ChangeManager.ts +3 -1
- package/src/FeatureDetailsWidget/BasicInformation.tsx +6 -4
- package/src/FeatureDetailsWidget/NumberTextField.tsx +5 -2
- package/src/FeatureDetailsWidget/TranscriptWidgetEditLocation.tsx +39 -203
- package/src/LinearApolloDisplay/components/CheckResultWarnings.tsx +92 -0
- package/src/LinearApolloDisplay/components/LinearApolloDisplay.tsx +6 -102
- package/src/LinearApolloDisplay/glyphs/GeneGlyph.ts +31 -230
- package/src/LinearApolloDisplay/glyphs/util.ts +19 -0
- package/src/LinearApolloReferenceSequenceDisplay/drawSequenceOverlay.ts +181 -0
- package/src/LinearApolloReferenceSequenceDisplay/drawSequenceTrack.ts +218 -0
- package/src/LinearApolloReferenceSequenceDisplay/stateModel/rendering.ts +62 -386
- package/src/LinearApolloSixFrameDisplay/components/LinearApolloSixFrameDisplay.tsx +6 -0
- package/src/LinearApolloSixFrameDisplay/glyphs/GeneGlyph.ts +122 -70
- package/src/components/AddAssembly.tsx +33 -37
- package/src/components/AddFeature.tsx +21 -18
- package/src/components/AddRefSeqAliases.tsx +56 -42
- package/src/components/CopyFeature.tsx +1 -1
- package/src/components/CreateApolloAnnotation.tsx +22 -10
- package/src/components/DeleteAssembly.tsx +2 -9
- package/src/components/DownloadGFF3.tsx +2 -2
- package/src/components/ManageChecks.tsx +2 -9
- package/src/components/ManageUsers.tsx +23 -22
- package/src/components/OntologyTermAutocomplete.tsx +1 -8
- package/src/components/ViewChangeLog.tsx +25 -50
- package/src/components/ViewCheckResults.tsx +1 -7
- package/src/config.ts +3 -3
- package/src/index.ts +17 -16
- package/src/makeDisplayComponent.tsx +9 -13
- package/src/session/ClientDataStore.ts +32 -14
- package/src/session/session.ts +19 -27
- package/src/util/glyphUtils.ts +178 -1
- package/src/util/loadAssemblyIntoClient.ts +3 -2
package/src/session/session.ts
CHANGED
|
@@ -165,20 +165,16 @@ export function extendSession(
|
|
|
165
165
|
const lgv = view as unknown as LinearGenomeViewModel
|
|
166
166
|
if (lgv.initialized) {
|
|
167
167
|
const { dynamicBlocks } = lgv
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
assembly.backendDriverType === 'CollaborationServerDriver'
|
|
177
|
-
) {
|
|
178
|
-
locations.push({ assemblyName, refName, start, end })
|
|
179
|
-
}
|
|
168
|
+
for (const block of dynamicBlocks.contentBlocks) {
|
|
169
|
+
const { assemblyName, end, refName, start } = block
|
|
170
|
+
const assembly = self.apolloDataStore.assemblies.get(assemblyName)
|
|
171
|
+
if (
|
|
172
|
+
assembly &&
|
|
173
|
+
assembly.backendDriverType === 'CollaborationServerDriver'
|
|
174
|
+
) {
|
|
175
|
+
locations.push({ assemblyName, refName, start, end })
|
|
180
176
|
}
|
|
181
|
-
}
|
|
177
|
+
}
|
|
182
178
|
}
|
|
183
179
|
}
|
|
184
180
|
if (locations.length === 0) {
|
|
@@ -235,21 +231,17 @@ export function extendSession(
|
|
|
235
231
|
const lgv = view as unknown as LinearGenomeViewModel
|
|
236
232
|
if (lgv.initialized) {
|
|
237
233
|
const { dynamicBlocks } = lgv
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
'CollaborationServerDriver'
|
|
248
|
-
) {
|
|
249
|
-
locations.push({ assemblyName, refName, start, end })
|
|
250
|
-
}
|
|
234
|
+
for (const block of dynamicBlocks.contentBlocks) {
|
|
235
|
+
const { assemblyName, end, refName, start } = block
|
|
236
|
+
const assembly =
|
|
237
|
+
self.apolloDataStore.assemblies.get(assemblyName)
|
|
238
|
+
if (
|
|
239
|
+
assembly &&
|
|
240
|
+
assembly.backendDriverType === 'CollaborationServerDriver'
|
|
241
|
+
) {
|
|
242
|
+
locations.push({ assemblyName, refName, start, end })
|
|
251
243
|
}
|
|
252
|
-
}
|
|
244
|
+
}
|
|
253
245
|
}
|
|
254
246
|
}
|
|
255
247
|
if (locations.length === 0) {
|
package/src/util/glyphUtils.ts
CHANGED
|
@@ -2,16 +2,193 @@ import {
|
|
|
2
2
|
type AnnotationFeature,
|
|
3
3
|
type TranscriptPartCoding,
|
|
4
4
|
} from '@apollo-annotation/mst'
|
|
5
|
+
import { type BaseDisplayModel } from '@jbrowse/core/pluggableElementTypes'
|
|
5
6
|
import { type MenuItem } from '@jbrowse/core/ui'
|
|
6
|
-
import {
|
|
7
|
+
import {
|
|
8
|
+
type AbstractSessionModel,
|
|
9
|
+
getContainingView,
|
|
10
|
+
} from '@jbrowse/core/util'
|
|
7
11
|
import { type LinearGenomeViewModel } from '@jbrowse/plugin-linear-genome-view'
|
|
12
|
+
import SkipNextRoundedIcon from '@mui/icons-material/SkipNextRounded'
|
|
13
|
+
import SkipPreviousRoundedIcon from '@mui/icons-material/SkipPreviousRounded'
|
|
8
14
|
|
|
9
15
|
import { type LinearApolloDisplayMouseEvents } from '../LinearApolloDisplay/stateModel/mouseEvents'
|
|
10
16
|
import { type LinearApolloSixFrameDisplayMouseEvents } from '../LinearApolloSixFrameDisplay/stateModel/mouseEvents'
|
|
11
17
|
import { AddChildFeature, CopyFeature, DeleteFeature } from '../components'
|
|
18
|
+
import { type ApolloSessionModel } from '../session'
|
|
19
|
+
|
|
20
|
+
import { type MousePositionWithFeature } from '.'
|
|
12
21
|
|
|
13
22
|
type NavLocation = Parameters<LinearGenomeViewModel['navTo']>[0]
|
|
14
23
|
|
|
24
|
+
export function selectFeatureAndOpenWidget(
|
|
25
|
+
stateModel:
|
|
26
|
+
| LinearApolloDisplayMouseEvents
|
|
27
|
+
| LinearApolloSixFrameDisplayMouseEvents,
|
|
28
|
+
feature: AnnotationFeature,
|
|
29
|
+
) {
|
|
30
|
+
if (stateModel.apolloDragging) {
|
|
31
|
+
return
|
|
32
|
+
}
|
|
33
|
+
stateModel.setSelectedFeature(feature)
|
|
34
|
+
const { session } = stateModel
|
|
35
|
+
const { apolloDataStore } = session
|
|
36
|
+
const { featureTypeOntology } = apolloDataStore.ontologyManager
|
|
37
|
+
if (!featureTypeOntology) {
|
|
38
|
+
throw new Error('featureTypeOntology is undefined')
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
let containsCDSOrExon = false
|
|
42
|
+
for (const [, child] of feature.children ?? []) {
|
|
43
|
+
if (
|
|
44
|
+
featureTypeOntology.isTypeOf(child.type, 'CDS') ||
|
|
45
|
+
featureTypeOntology.isTypeOf(child.type, 'exon')
|
|
46
|
+
) {
|
|
47
|
+
containsCDSOrExon = true
|
|
48
|
+
break
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
if (
|
|
52
|
+
(featureTypeOntology.isTypeOf(feature.type, 'transcript') ||
|
|
53
|
+
featureTypeOntology.isTypeOf(feature.type, 'pseudogenic_transcript')) &&
|
|
54
|
+
containsCDSOrExon
|
|
55
|
+
) {
|
|
56
|
+
stateModel.showFeatureDetailsWidget(feature, [
|
|
57
|
+
'ApolloTranscriptDetails',
|
|
58
|
+
'apolloTranscriptDetails',
|
|
59
|
+
])
|
|
60
|
+
} else {
|
|
61
|
+
stateModel.showFeatureDetailsWidget(feature)
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export function isTranscriptFeature(
|
|
66
|
+
feature: AnnotationFeature,
|
|
67
|
+
session: ApolloSessionModel,
|
|
68
|
+
): boolean {
|
|
69
|
+
const { featureTypeOntology } = session.apolloDataStore.ontologyManager
|
|
70
|
+
if (!featureTypeOntology) {
|
|
71
|
+
throw new Error('featureTypeOntology is undefined')
|
|
72
|
+
}
|
|
73
|
+
return (
|
|
74
|
+
featureTypeOntology.isTypeOf(feature.type, 'transcript') ||
|
|
75
|
+
featureTypeOntology.isTypeOf(feature.type, 'pseudogenic_transcript')
|
|
76
|
+
)
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
export function isExonFeature(
|
|
80
|
+
feature: AnnotationFeature,
|
|
81
|
+
session: ApolloSessionModel,
|
|
82
|
+
): boolean {
|
|
83
|
+
const { featureTypeOntology } = session.apolloDataStore.ontologyManager
|
|
84
|
+
if (!featureTypeOntology) {
|
|
85
|
+
throw new Error('featureTypeOntology is undefined')
|
|
86
|
+
}
|
|
87
|
+
return featureTypeOntology.isTypeOf(feature.type, 'exon')
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
export function isCDSFeature(
|
|
91
|
+
feature: AnnotationFeature,
|
|
92
|
+
session: ApolloSessionModel,
|
|
93
|
+
): boolean {
|
|
94
|
+
const { featureTypeOntology } = session.apolloDataStore.ontologyManager
|
|
95
|
+
if (!featureTypeOntology) {
|
|
96
|
+
throw new Error('featureTypeOntology is undefined')
|
|
97
|
+
}
|
|
98
|
+
return featureTypeOntology.isTypeOf(feature.type, 'CDS')
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
export interface AdjacentExons {
|
|
102
|
+
upstream: AnnotationFeature | undefined
|
|
103
|
+
downstream: AnnotationFeature | undefined
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
export function getAdjacentExons(
|
|
107
|
+
currentExon: AnnotationFeature,
|
|
108
|
+
display:
|
|
109
|
+
| LinearApolloDisplayMouseEvents
|
|
110
|
+
| LinearApolloSixFrameDisplayMouseEvents,
|
|
111
|
+
mousePosition: MousePositionWithFeature,
|
|
112
|
+
session: ApolloSessionModel,
|
|
113
|
+
): AdjacentExons {
|
|
114
|
+
const lgv = getContainingView(
|
|
115
|
+
display as BaseDisplayModel,
|
|
116
|
+
) as unknown as LinearGenomeViewModel
|
|
117
|
+
|
|
118
|
+
// Genomic coords of current view
|
|
119
|
+
const viewGenomicLeft = mousePosition.bp - lgv.bpPerPx * mousePosition.x
|
|
120
|
+
const viewGenomicRight = viewGenomicLeft + lgv.coarseTotalBp
|
|
121
|
+
if (!currentExon.parent) {
|
|
122
|
+
return { upstream: undefined, downstream: undefined }
|
|
123
|
+
}
|
|
124
|
+
const transcript = currentExon.parent
|
|
125
|
+
if (!transcript.children) {
|
|
126
|
+
throw new Error(`Error getting children of ${transcript._id}`)
|
|
127
|
+
}
|
|
128
|
+
const { featureTypeOntology } = session.apolloDataStore.ontologyManager
|
|
129
|
+
if (!featureTypeOntology) {
|
|
130
|
+
throw new Error('featureTypeOntology is undefined')
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
let exons = []
|
|
134
|
+
for (const [, child] of transcript.children) {
|
|
135
|
+
if (featureTypeOntology.isTypeOf(child.type, 'exon')) {
|
|
136
|
+
exons.push(child)
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
const adjacentExons: AdjacentExons = {
|
|
140
|
+
upstream: undefined,
|
|
141
|
+
downstream: undefined,
|
|
142
|
+
}
|
|
143
|
+
exons = exons.sort((a, b) => (a.min < b.min ? -1 : 1))
|
|
144
|
+
for (const exon of exons) {
|
|
145
|
+
if (exon.min > viewGenomicRight) {
|
|
146
|
+
adjacentExons.downstream = exon
|
|
147
|
+
break
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
exons = exons.sort((a, b) => (a.min > b.min ? -1 : 1))
|
|
151
|
+
for (const exon of exons) {
|
|
152
|
+
if (exon.max < viewGenomicLeft) {
|
|
153
|
+
adjacentExons.upstream = exon
|
|
154
|
+
break
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
if (transcript.strand === -1) {
|
|
158
|
+
const newUpstream = adjacentExons.downstream
|
|
159
|
+
adjacentExons.downstream = adjacentExons.upstream
|
|
160
|
+
adjacentExons.upstream = newUpstream
|
|
161
|
+
}
|
|
162
|
+
return adjacentExons
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
export function getStreamIcon(
|
|
166
|
+
strand: 1 | -1 | undefined,
|
|
167
|
+
isUpstream: boolean,
|
|
168
|
+
isFlipped: boolean | undefined,
|
|
169
|
+
) {
|
|
170
|
+
// This is the icon you would use for strand=1, downstream, straight
|
|
171
|
+
// (non-flipped) view
|
|
172
|
+
let icon = SkipNextRoundedIcon
|
|
173
|
+
|
|
174
|
+
if (strand === -1) {
|
|
175
|
+
icon = SkipPreviousRoundedIcon
|
|
176
|
+
}
|
|
177
|
+
if (isUpstream) {
|
|
178
|
+
icon =
|
|
179
|
+
icon === SkipPreviousRoundedIcon
|
|
180
|
+
? SkipNextRoundedIcon
|
|
181
|
+
: SkipPreviousRoundedIcon
|
|
182
|
+
}
|
|
183
|
+
if (isFlipped) {
|
|
184
|
+
icon =
|
|
185
|
+
icon === SkipPreviousRoundedIcon
|
|
186
|
+
? SkipNextRoundedIcon
|
|
187
|
+
: SkipPreviousRoundedIcon
|
|
188
|
+
}
|
|
189
|
+
return icon
|
|
190
|
+
}
|
|
191
|
+
|
|
15
192
|
export function getMinAndMaxPx(
|
|
16
193
|
feature: AnnotationFeature | TranscriptPartCoding,
|
|
17
194
|
refName: string,
|
|
@@ -4,10 +4,11 @@ import {
|
|
|
4
4
|
type CheckResultSnapshot,
|
|
5
5
|
} from '@apollo-annotation/mst'
|
|
6
6
|
import { gff3ToAnnotationFeature } from '@apollo-annotation/shared'
|
|
7
|
-
import
|
|
7
|
+
import {
|
|
8
8
|
type GFF3Comment,
|
|
9
9
|
type GFF3Feature,
|
|
10
10
|
type GFF3Sequence,
|
|
11
|
+
parseStringSync,
|
|
11
12
|
} from '@gmod/gff'
|
|
12
13
|
import { getSnapshot } from 'mobx-state-tree'
|
|
13
14
|
|
|
@@ -17,7 +18,7 @@ export async function loadAssemblyIntoClient(
|
|
|
17
18
|
apolloDataStore: ClientDataStore,
|
|
18
19
|
) {
|
|
19
20
|
const featuresAndSequences: (GFF3Feature | GFF3Sequence | GFF3Comment)[] =
|
|
20
|
-
|
|
21
|
+
parseStringSync(gff3FileText, {
|
|
21
22
|
parseSequences: true,
|
|
22
23
|
parseComments: true,
|
|
23
24
|
parseDirectives: false,
|