@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.
Files changed (48) hide show
  1. package/dist/index.esm.js +10932 -10932
  2. package/dist/index.esm.js.map +1 -1
  3. package/dist/jbrowse-plugin-apollo.cjs.development.js +10845 -10846
  4. package/dist/jbrowse-plugin-apollo.cjs.development.js.map +1 -1
  5. package/dist/jbrowse-plugin-apollo.cjs.production.min.js +1 -1
  6. package/dist/jbrowse-plugin-apollo.cjs.production.min.js.map +1 -1
  7. package/dist/jbrowse-plugin-apollo.umd.development.js +18619 -21342
  8. package/dist/jbrowse-plugin-apollo.umd.development.js.map +1 -1
  9. package/dist/jbrowse-plugin-apollo.umd.production.min.js +1 -1
  10. package/dist/jbrowse-plugin-apollo.umd.production.min.js.map +1 -1
  11. package/package.json +7 -7
  12. package/src/ApolloInternetAccount/model.ts +81 -63
  13. package/src/ApolloRefNameAliasAdapter/ApolloRefNameAliasAdapter.ts +4 -4
  14. package/src/ApolloSequenceAdapter/ApolloSequenceAdapter.ts +9 -7
  15. package/src/BackendDrivers/CollaborationServerDriver.ts +49 -18
  16. package/src/BackendDrivers/DesktopFileDriver.ts +2 -2
  17. package/src/ChangeManager.ts +3 -1
  18. package/src/FeatureDetailsWidget/BasicInformation.tsx +6 -4
  19. package/src/FeatureDetailsWidget/NumberTextField.tsx +5 -2
  20. package/src/FeatureDetailsWidget/TranscriptWidgetEditLocation.tsx +39 -203
  21. package/src/LinearApolloDisplay/components/CheckResultWarnings.tsx +92 -0
  22. package/src/LinearApolloDisplay/components/LinearApolloDisplay.tsx +6 -102
  23. package/src/LinearApolloDisplay/glyphs/GeneGlyph.ts +31 -230
  24. package/src/LinearApolloDisplay/glyphs/util.ts +19 -0
  25. package/src/LinearApolloReferenceSequenceDisplay/drawSequenceOverlay.ts +181 -0
  26. package/src/LinearApolloReferenceSequenceDisplay/drawSequenceTrack.ts +218 -0
  27. package/src/LinearApolloReferenceSequenceDisplay/stateModel/rendering.ts +62 -386
  28. package/src/LinearApolloSixFrameDisplay/components/LinearApolloSixFrameDisplay.tsx +6 -0
  29. package/src/LinearApolloSixFrameDisplay/glyphs/GeneGlyph.ts +122 -70
  30. package/src/components/AddAssembly.tsx +33 -37
  31. package/src/components/AddFeature.tsx +21 -18
  32. package/src/components/AddRefSeqAliases.tsx +56 -42
  33. package/src/components/CopyFeature.tsx +1 -1
  34. package/src/components/CreateApolloAnnotation.tsx +22 -10
  35. package/src/components/DeleteAssembly.tsx +2 -9
  36. package/src/components/DownloadGFF3.tsx +2 -2
  37. package/src/components/ManageChecks.tsx +2 -9
  38. package/src/components/ManageUsers.tsx +23 -22
  39. package/src/components/OntologyTermAutocomplete.tsx +1 -8
  40. package/src/components/ViewChangeLog.tsx +25 -50
  41. package/src/components/ViewCheckResults.tsx +1 -7
  42. package/src/config.ts +3 -3
  43. package/src/index.ts +17 -16
  44. package/src/makeDisplayComponent.tsx +9 -13
  45. package/src/session/ClientDataStore.ts +32 -14
  46. package/src/session/session.ts +19 -27
  47. package/src/util/glyphUtils.ts +178 -1
  48. package/src/util/loadAssemblyIntoClient.ts +3 -2
@@ -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
- // eslint-disable-next-line unicorn/no-array-for-each
169
- dynamicBlocks.forEach((block) => {
170
- if (block.regionNumber !== undefined) {
171
- const { assemblyName, end, refName, start } = block
172
- const assembly =
173
- self.apolloDataStore.assemblies.get(assemblyName)
174
- if (
175
- assembly &&
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
- // eslint-disable-next-line unicorn/no-array-for-each
239
- dynamicBlocks.forEach((block) => {
240
- if (block.regionNumber !== undefined) {
241
- const { assemblyName, end, refName, start } = block
242
- const assembly =
243
- self.apolloDataStore.assemblies.get(assemblyName)
244
- if (
245
- assembly &&
246
- assembly.backendDriverType ===
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) {
@@ -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 { type AbstractSessionModel } from '@jbrowse/core/util'
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 gff, {
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
- gff.parseStringSync(gff3FileText, {
21
+ parseStringSync(gff3FileText, {
21
22
  parseSequences: true,
22
23
  parseComments: true,
23
24
  parseDirectives: false,