@apollo-annotation/jbrowse-plugin-apollo 0.1.18 → 0.1.20
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 +3189 -3575
- package/dist/index.esm.js.map +1 -1
- package/dist/jbrowse-plugin-apollo.cjs.development.js +3185 -3570
- 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 +14884 -15905
- 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 +33 -33
- package/src/ApolloInternetAccount/addMenuItems.ts +18 -0
- package/src/ApolloInternetAccount/components/AuthTypeSelector.tsx +1 -0
- package/src/ApolloInternetAccount/configSchema.ts +5 -2
- package/src/ApolloInternetAccount/model.ts +14 -5
- package/src/ApolloRefNameAliasAdapter/ApolloRefNameAliasAdapter.ts +94 -0
- package/src/ApolloRefNameAliasAdapter/configSchema.ts +12 -0
- package/src/ApolloRefNameAliasAdapter/index.ts +21 -0
- package/src/ApolloSequenceAdapter/ApolloSequenceAdapter.ts +1 -0
- package/src/ApolloSixFrameRenderer/components/ApolloRendering.tsx +10 -10
- package/src/ApolloTextSearchAdapter/ApolloTextSearchAdapter.ts +35 -32
- package/src/BackendDrivers/BackendDriver.ts +8 -0
- package/src/BackendDrivers/CollaborationServerDriver.ts +49 -1
- package/src/BackendDrivers/DesktopFileDriver.ts +14 -1
- package/src/BackendDrivers/InMemoryFileDriver.ts +17 -1
- package/src/ChangeManager.ts +1 -1
- package/src/FeatureDetailsWidget/ApolloFeatureDetailsWidget.tsx +5 -25
- package/src/FeatureDetailsWidget/ApolloTranscriptDetailsWidget.tsx +82 -0
- package/src/FeatureDetailsWidget/Attributes.tsx +11 -3
- package/src/FeatureDetailsWidget/BasicInformation.tsx +38 -30
- package/src/FeatureDetailsWidget/Sequence.tsx +7 -7
- package/src/FeatureDetailsWidget/TranscriptBasic.tsx +446 -0
- package/src/FeatureDetailsWidget/TranscriptSequence.tsx +365 -0
- package/src/FeatureDetailsWidget/index.ts +2 -0
- package/src/FeatureDetailsWidget/model.ts +77 -9
- package/src/LinearApolloDisplay/components/LinearApolloDisplay.tsx +0 -2
- package/src/LinearApolloDisplay/glyphs/BoxGlyph.ts +453 -380
- package/src/LinearApolloDisplay/glyphs/GeneGlyph.ts +520 -0
- package/src/LinearApolloDisplay/glyphs/GenericChildGlyph.ts +138 -134
- package/src/LinearApolloDisplay/glyphs/Glyph.ts +38 -370
- package/src/LinearApolloDisplay/glyphs/index.ts +1 -2
- package/src/LinearApolloDisplay/stateModel/base.ts +3 -6
- package/src/LinearApolloDisplay/stateModel/getGlyph.ts +30 -30
- package/src/LinearApolloDisplay/stateModel/index.ts +5 -1
- package/src/LinearApolloDisplay/stateModel/layouts.ts +32 -24
- package/src/LinearApolloDisplay/stateModel/mouseEvents.ts +206 -217
- package/src/LinearApolloDisplay/stateModel/rendering.ts +43 -67
- package/src/OntologyManager/OntologyStore/fulltext.ts +1 -1
- package/src/OntologyManager/OntologyStore/index.ts +2 -1
- package/src/OntologyManager/index.ts +6 -2
- package/src/OntologyManager/util.ts +2 -2
- package/src/SixFrameFeatureDisplay/stateModel.ts +15 -10
- package/src/TabularEditor/HybridGrid/ChangeHandling.ts +21 -46
- package/src/TabularEditor/HybridGrid/Feature.tsx +31 -82
- package/src/TabularEditor/HybridGrid/FeatureAttributes.tsx +3 -2
- package/src/TabularEditor/HybridGrid/HybridGrid.tsx +2 -3
- package/src/TabularEditor/HybridGrid/NumberCell.tsx +1 -0
- package/src/TabularEditor/HybridGrid/featureContextMenuItems.ts +46 -5
- package/src/TabularEditor/model.ts +5 -3
- package/src/components/AddAssembly.tsx +15 -9
- package/src/components/AddChildFeature.tsx +7 -73
- package/src/components/AddFeature.tsx +2 -57
- package/src/components/AddRefSeqAliases.tsx +285 -0
- package/src/components/CopyFeature.tsx +16 -33
- package/src/components/DeleteFeature.tsx +4 -6
- package/src/components/ImportFeatures.tsx +6 -3
- package/src/components/LogOut.tsx +105 -0
- package/src/components/ManageChecks.tsx +1 -0
- package/src/components/ManageUsers.tsx +21 -1
- package/src/components/ModifyFeatureAttribute.tsx +2 -2
- package/src/components/OntologyTermAutocomplete.tsx +0 -2
- package/src/components/OntologyTermMultiSelect.tsx +1 -0
- package/src/components/OpenLocalFile.tsx +6 -5
- package/src/components/ViewChangeLog.tsx +1 -0
- package/src/components/ViewCheckResults.tsx +1 -0
- package/src/components/index.ts +4 -0
- package/src/extensions/annotationFromPileup.ts +10 -16
- package/src/index.ts +57 -3
- package/src/session/ClientDataStore.ts +49 -46
- package/src/session/session.ts +186 -114
- package/src/util/loadAssemblyIntoClient.ts +4 -210
- package/src/FeatureDetailsWidget/RelatedFeature.tsx +0 -97
- package/src/LinearApolloDisplay/glyphs/CanonicalGeneGlyph.ts +0 -1204
- package/src/LinearApolloDisplay/glyphs/ImplicitExonGeneGlyph.ts +0 -716
- package/src/LinearApolloDisplay/stateModel/glyphs.ts +0 -47
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
|
|
2
2
|
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
|
|
3
|
-
/* eslint-disable @typescript-eslint/no-unsafe-call */
|
|
4
3
|
/* eslint-disable @typescript-eslint/no-unnecessary-condition */
|
|
5
4
|
/* eslint-disable @typescript-eslint/no-unsafe-argument */
|
|
6
5
|
import { ClientDataStore as ClientDataStoreType } from '@apollo-annotation/common'
|
|
7
6
|
import {
|
|
8
|
-
|
|
7
|
+
AnnotationFeatureModel,
|
|
9
8
|
AnnotationFeatureSnapshot,
|
|
10
9
|
ApolloAssembly,
|
|
10
|
+
ApolloAssemblySnapshot,
|
|
11
11
|
ApolloRefSeq,
|
|
12
|
+
BackendDriverType,
|
|
12
13
|
CheckResult,
|
|
13
14
|
CheckResultSnapshot,
|
|
14
15
|
} from '@apollo-annotation/mst'
|
|
@@ -18,7 +19,7 @@ import { Region, getSession, isElectron } from '@jbrowse/core/util'
|
|
|
18
19
|
import { LocalPathLocation, UriLocation } from '@jbrowse/core/util/types/mst'
|
|
19
20
|
import {
|
|
20
21
|
Instance,
|
|
21
|
-
|
|
22
|
+
addDisposer,
|
|
22
23
|
flow,
|
|
23
24
|
getParentOfType,
|
|
24
25
|
getRoot,
|
|
@@ -40,11 +41,12 @@ import {
|
|
|
40
41
|
TextIndexFieldDefinition,
|
|
41
42
|
} from '../OntologyManager'
|
|
42
43
|
import { ApolloRootModel } from '../types'
|
|
44
|
+
import { autorun } from 'mobx'
|
|
43
45
|
|
|
44
46
|
export function clientDataStoreFactory(
|
|
45
|
-
AnnotationFeatureExtended: typeof
|
|
47
|
+
AnnotationFeatureExtended: typeof AnnotationFeatureModel,
|
|
46
48
|
) {
|
|
47
|
-
|
|
49
|
+
return types
|
|
48
50
|
.model('ClientDataStore', {
|
|
49
51
|
typeName: types.optional(types.literal('Client'), 'Client'),
|
|
50
52
|
assemblies: types.map(ApolloAssembly),
|
|
@@ -68,8 +70,15 @@ export function clientDataStoreFactory(
|
|
|
68
70
|
},
|
|
69
71
|
}))
|
|
70
72
|
.actions((self) => ({
|
|
71
|
-
addAssembly(assemblyId: string) {
|
|
72
|
-
|
|
73
|
+
addAssembly(assemblyId: string, backendDriverType?: BackendDriverType) {
|
|
74
|
+
const assemblySnapshot: ApolloAssemblySnapshot = {
|
|
75
|
+
_id: assemblyId,
|
|
76
|
+
refSeqs: {},
|
|
77
|
+
}
|
|
78
|
+
if (backendDriverType) {
|
|
79
|
+
assemblySnapshot.backendDriverType = backendDriverType
|
|
80
|
+
}
|
|
81
|
+
return self.assemblies.put(assemblySnapshot)
|
|
73
82
|
},
|
|
74
83
|
addFeature(assemblyId: string, feature: AnnotationFeatureSnapshot) {
|
|
75
84
|
const assembly = self.assemblies.get(assemblyId)
|
|
@@ -131,36 +140,39 @@ export function clientDataStoreFactory(
|
|
|
131
140
|
}))
|
|
132
141
|
.actions((self) => ({
|
|
133
142
|
afterCreate() {
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
143
|
+
addDisposer(
|
|
144
|
+
self,
|
|
145
|
+
autorun(() => {
|
|
146
|
+
// Merge in the ontologies from our plugin configuration.
|
|
147
|
+
// Ontologies of a given name that are already in the session
|
|
148
|
+
// take precedence over the ontologies in the configuration.
|
|
149
|
+
const { ontologyManager, pluginConfiguration } = self
|
|
150
|
+
const configuredOntologies =
|
|
151
|
+
pluginConfiguration.ontologies as ConfigurationModel<
|
|
152
|
+
typeof OntologyRecordConfiguration
|
|
153
|
+
>[]
|
|
154
|
+
for (const ont of configuredOntologies || []) {
|
|
155
|
+
const [name, version, source, indexFields] = [
|
|
156
|
+
readConfObject(ont, 'name') as string,
|
|
157
|
+
readConfObject(ont, 'version') as string,
|
|
158
|
+
readConfObject(ont, 'source') as
|
|
159
|
+
| Instance<typeof LocalPathLocation>
|
|
160
|
+
| Instance<typeof UriLocation>,
|
|
161
|
+
readConfObject(
|
|
162
|
+
ont,
|
|
163
|
+
'textIndexFields',
|
|
164
|
+
) as TextIndexFieldDefinition[],
|
|
165
|
+
]
|
|
166
|
+
if (!ontologyManager.findOntology(name)) {
|
|
167
|
+
ontologyManager.addOntology(name, version, source, {
|
|
168
|
+
textIndexing: { indexFields },
|
|
169
|
+
})
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
// TODO: add in any configured ontology prefixes that we don't already
|
|
173
|
+
// have in the session (or hardcoded in the model)
|
|
174
|
+
}),
|
|
175
|
+
)
|
|
164
176
|
},
|
|
165
177
|
}))
|
|
166
178
|
.views((self) => ({
|
|
@@ -275,13 +287,4 @@ export function clientDataStoreFactory(
|
|
|
275
287
|
}
|
|
276
288
|
}),
|
|
277
289
|
}))
|
|
278
|
-
|
|
279
|
-
// assembly and feature data isn't actually reloaded on reload unless we delete it from the snap
|
|
280
|
-
return types.snapshotProcessor(clientStoreType, {
|
|
281
|
-
postProcessor(snap: SnapshotOut<typeof clientStoreType>) {
|
|
282
|
-
snap.assemblies = {}
|
|
283
|
-
snap.checkResults = {}
|
|
284
|
-
return snap
|
|
285
|
-
},
|
|
286
|
-
})
|
|
287
290
|
}
|
package/src/session/session.ts
CHANGED
|
@@ -1,21 +1,36 @@
|
|
|
1
|
-
/* eslint-disable @typescript-eslint/no-
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-unsafe-return */
|
|
2
2
|
/* eslint-disable @typescript-eslint/no-unnecessary-condition */
|
|
3
3
|
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
|
|
4
|
-
/* eslint-disable @typescript-eslint/no-unsafe-argument */
|
|
5
4
|
import { ClientDataStore as ClientDataStoreType } from '@apollo-annotation/common'
|
|
6
|
-
import {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
import {
|
|
5
|
+
import {
|
|
6
|
+
AnnotationFeature,
|
|
7
|
+
AnnotationFeatureModel,
|
|
8
|
+
} from '@apollo-annotation/mst'
|
|
9
|
+
import {
|
|
10
|
+
filterJBrowseConfig,
|
|
11
|
+
ImportJBrowseConfigChange,
|
|
12
|
+
JBrowseConfig,
|
|
13
|
+
UserLocation,
|
|
14
|
+
} from '@apollo-annotation/shared'
|
|
15
|
+
import { readConfObject, getConf } from '@jbrowse/core/configuration'
|
|
16
|
+
import { BaseTrackConfig } from '@jbrowse/core/pluggableElementTypes'
|
|
11
17
|
import PluginManager from '@jbrowse/core/PluginManager'
|
|
12
18
|
import {
|
|
13
19
|
AbstractSessionModel,
|
|
14
20
|
SessionWithConfigEditing,
|
|
15
21
|
} from '@jbrowse/core/util'
|
|
16
22
|
import { LinearGenomeViewModel } from '@jbrowse/plugin-linear-genome-view'
|
|
23
|
+
import SaveIcon from '@mui/icons-material/Save'
|
|
17
24
|
import { autorun, observable } from 'mobx'
|
|
18
|
-
import {
|
|
25
|
+
import {
|
|
26
|
+
Instance,
|
|
27
|
+
SnapshotOut,
|
|
28
|
+
applySnapshot,
|
|
29
|
+
flow,
|
|
30
|
+
getRoot,
|
|
31
|
+
getSnapshot,
|
|
32
|
+
types,
|
|
33
|
+
} from 'mobx-state-tree'
|
|
19
34
|
|
|
20
35
|
import { ApolloInternetAccountModel } from '../ApolloInternetAccount/model'
|
|
21
36
|
import { ApolloJobModel } from '../ApolloJobModel'
|
|
@@ -23,27 +38,12 @@ import { ChangeManager } from '../ChangeManager'
|
|
|
23
38
|
import { ApolloRootModel } from '../types'
|
|
24
39
|
import { createFetchErrorMessage } from '../util'
|
|
25
40
|
import { clientDataStoreFactory } from './ClientDataStore'
|
|
41
|
+
import { AssemblyModel } from '@jbrowse/core/assemblyManager/assembly'
|
|
26
42
|
|
|
27
43
|
export interface ApolloSession extends AbstractSessionModel {
|
|
28
44
|
apolloDataStore: ClientDataStoreType & { changeManager: ChangeManager }
|
|
29
|
-
apolloSelectedFeature?:
|
|
30
|
-
apolloSetSelectedFeature(feature?:
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
interface ApolloAssemblyResponse {
|
|
34
|
-
_id: string
|
|
35
|
-
name: string
|
|
36
|
-
displayName?: string
|
|
37
|
-
description?: string
|
|
38
|
-
aliases?: string[]
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
export interface ApolloRefSeqResponse {
|
|
42
|
-
_id: string
|
|
43
|
-
name: string
|
|
44
|
-
description?: string
|
|
45
|
-
length: string
|
|
46
|
-
assembly: string
|
|
45
|
+
apolloSelectedFeature?: AnnotationFeature
|
|
46
|
+
apolloSetSelectedFeature(feature?: AnnotationFeature): void
|
|
47
47
|
}
|
|
48
48
|
|
|
49
49
|
export interface Collaborator {
|
|
@@ -60,10 +60,10 @@ export function extendSession(
|
|
|
60
60
|
const { signal } = aborter
|
|
61
61
|
const AnnotationFeatureExtended = pluginManager.evaluateExtensionPoint(
|
|
62
62
|
'Apollo-extendAnnotationFeature',
|
|
63
|
-
|
|
64
|
-
) as typeof
|
|
63
|
+
AnnotationFeatureModel,
|
|
64
|
+
) as typeof AnnotationFeatureModel
|
|
65
65
|
const ClientDataStore = clientDataStoreFactory(AnnotationFeatureExtended)
|
|
66
|
-
|
|
66
|
+
const sm = sessionModel
|
|
67
67
|
.props({
|
|
68
68
|
apolloDataStore: types.optional(ClientDataStore, { typeName: 'Client' }),
|
|
69
69
|
apolloSelectedFeature: types.safeReference(AnnotationFeatureExtended),
|
|
@@ -93,7 +93,8 @@ export function extendSession(
|
|
|
93
93
|
}
|
|
94
94
|
})
|
|
95
95
|
.actions((self) => ({
|
|
96
|
-
apolloSetSelectedFeature(feature?:
|
|
96
|
+
apolloSetSelectedFeature(feature?: AnnotationFeature) {
|
|
97
|
+
// @ts-expect-error Not sure why TS thinks these MST types don't match
|
|
97
98
|
self.apolloSelectedFeature = feature
|
|
98
99
|
},
|
|
99
100
|
addApolloTrackConfig(assembly: AssemblyModel, baseURL?: string) {
|
|
@@ -186,7 +187,15 @@ export function extendSession(
|
|
|
186
187
|
}))
|
|
187
188
|
.actions((self) => ({
|
|
188
189
|
afterCreate: flow(function* afterCreate() {
|
|
189
|
-
|
|
190
|
+
// When the initial config.json loads, it doesn't include the Apollo
|
|
191
|
+
// tracks, which would result in a potentially invalid session snapshot
|
|
192
|
+
// if any tracks are open. Here we copy the session snapshot, apply an
|
|
193
|
+
// empty session snapshot, and then restore the original session
|
|
194
|
+
// snapshot after the updated config.json loads.
|
|
195
|
+
const sessionSnapshot = getSnapshot(self)
|
|
196
|
+
const { id, name } = sessionSnapshot
|
|
197
|
+
applySnapshot(self, { name, id })
|
|
198
|
+
const { internetAccounts, jbrowse } = getRoot<ApolloRootModel>(self)
|
|
190
199
|
autorun(
|
|
191
200
|
() => {
|
|
192
201
|
// broadcastLocations() // **** This is not working and therefore we need to duplicate broadcastLocations() -method code here because autorun() does not observe changes otherwise
|
|
@@ -248,8 +257,8 @@ export function extendSession(
|
|
|
248
257
|
continue
|
|
249
258
|
}
|
|
250
259
|
|
|
251
|
-
const { baseURL
|
|
252
|
-
const uri = new URL('
|
|
260
|
+
const { baseURL } = internetAccount
|
|
261
|
+
const uri = new URL('jbrowse/config.json', baseURL).href
|
|
253
262
|
const fetch = internetAccount.getFetcher({
|
|
254
263
|
locationType: 'UriLocation',
|
|
255
264
|
uri,
|
|
@@ -259,7 +268,6 @@ export function extendSession(
|
|
|
259
268
|
response = yield fetch(uri, { signal })
|
|
260
269
|
} catch (error) {
|
|
261
270
|
console.error(error)
|
|
262
|
-
// setError(e instanceof Error ? e : new Error(String(e)))
|
|
263
271
|
continue
|
|
264
272
|
}
|
|
265
273
|
if (!response.ok) {
|
|
@@ -270,96 +278,160 @@ export function extendSession(
|
|
|
270
278
|
console.error(errorMessage)
|
|
271
279
|
continue
|
|
272
280
|
}
|
|
273
|
-
let
|
|
281
|
+
let jbrowseConfig
|
|
274
282
|
try {
|
|
275
|
-
|
|
276
|
-
(yield response.json()) as ApolloAssemblyResponse[]
|
|
283
|
+
jbrowseConfig = yield response.json()
|
|
277
284
|
} catch (error) {
|
|
278
285
|
console.error(error)
|
|
279
286
|
continue
|
|
280
287
|
}
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
self as unknown as AbstractSessionModel & {
|
|
284
|
-
// eslint-disable-next-line @typescript-eslint/ban-types
|
|
285
|
-
addSessionAssembly: Function
|
|
286
|
-
}
|
|
287
|
-
const selectedAssembly = assemblyManager.get(assembly.name)
|
|
288
|
-
if (selectedAssembly) {
|
|
289
|
-
// @ts-expect-error MST type coercion problem?
|
|
290
|
-
self.addApolloTrackConfig(selectedAssembly, baseURL)
|
|
291
|
-
continue
|
|
292
|
-
}
|
|
293
|
-
const url = new URL('refSeqs', baseURL)
|
|
294
|
-
const searchParams = new URLSearchParams({ assembly: assembly._id })
|
|
295
|
-
url.search = searchParams.toString()
|
|
296
|
-
const uri2 = url.toString()
|
|
297
|
-
const fetch2 = internetAccount.getFetcher({
|
|
298
|
-
locationType: 'UriLocation',
|
|
299
|
-
uri: uri2,
|
|
300
|
-
})
|
|
301
|
-
const response2 = (yield fetch2(uri2, {
|
|
302
|
-
signal,
|
|
303
|
-
})) as unknown as Response
|
|
304
|
-
if (!response2.ok) {
|
|
305
|
-
let errorMessage
|
|
306
|
-
try {
|
|
307
|
-
errorMessage = yield response2.text()
|
|
308
|
-
} catch {
|
|
309
|
-
errorMessage = ''
|
|
310
|
-
}
|
|
311
|
-
throw new Error(
|
|
312
|
-
`Failed to fetch fasta info — ${response2.status} (${
|
|
313
|
-
response2.statusText
|
|
314
|
-
})${errorMessage ? ` (${errorMessage})` : ''}`,
|
|
315
|
-
)
|
|
316
|
-
}
|
|
317
|
-
const f = (yield response2.json()) as ApolloRefSeqResponse[]
|
|
318
|
-
const ids: Record<string, string> = {}
|
|
319
|
-
const refNameAliasesFeatures = f.map((contig) => {
|
|
320
|
-
ids[contig.name] = contig._id
|
|
321
|
-
return {
|
|
322
|
-
refName: contig.name,
|
|
323
|
-
aliases: [contig._id],
|
|
324
|
-
uniqueId: `alias-${contig._id}`,
|
|
325
|
-
}
|
|
326
|
-
})
|
|
327
|
-
const assemblyConfig = {
|
|
328
|
-
name: assembly._id,
|
|
329
|
-
aliases: [assembly.name, ...(assembly.aliases ?? [])],
|
|
330
|
-
displayName: assembly.displayName ?? assembly.name,
|
|
331
|
-
sequence: {
|
|
332
|
-
trackId: `sequenceConfigId-${assembly.name}`,
|
|
333
|
-
type: 'ReferenceSequenceTrack',
|
|
334
|
-
adapter: {
|
|
335
|
-
type: 'ApolloSequenceAdapter',
|
|
336
|
-
assemblyId: assembly._id,
|
|
337
|
-
baseURL: { uri: baseURL, locationType: 'UriLocation' },
|
|
338
|
-
},
|
|
339
|
-
metadata: {
|
|
340
|
-
apollo: true,
|
|
341
|
-
internetAccountConfigId: configuration.internetAccountId,
|
|
342
|
-
ids,
|
|
343
|
-
},
|
|
344
|
-
},
|
|
345
|
-
refNameAliases: {
|
|
346
|
-
adapter: {
|
|
347
|
-
type: 'FromConfigAdapter',
|
|
348
|
-
features: refNameAliasesFeatures,
|
|
349
|
-
},
|
|
350
|
-
},
|
|
351
|
-
}
|
|
352
|
-
;(addSessionAssembly || addAssembly)(assemblyConfig)
|
|
353
|
-
const a = yield assemblyManager.waitForAssembly(assemblyConfig.name)
|
|
354
|
-
self.addApolloTrackConfig(a, baseURL)
|
|
355
|
-
}
|
|
288
|
+
applySnapshot(jbrowse, jbrowseConfig)
|
|
289
|
+
applySnapshot(self, sessionSnapshot)
|
|
356
290
|
}
|
|
357
291
|
}),
|
|
358
292
|
beforeDestroy() {
|
|
359
|
-
aborter.abort()
|
|
293
|
+
aborter.abort('destroying session model')
|
|
360
294
|
},
|
|
361
295
|
}))
|
|
296
|
+
|
|
297
|
+
.views((self) => {
|
|
298
|
+
const superTrackActionMenuItems = (
|
|
299
|
+
self as unknown as AbstractSessionModel
|
|
300
|
+
).getTrackActionMenuItems
|
|
301
|
+
return {
|
|
302
|
+
getTrackActionMenuItems(conf: BaseTrackConfig) {
|
|
303
|
+
if (
|
|
304
|
+
conf.type === 'ApolloTrack' ||
|
|
305
|
+
conf.type === 'ReferenceSequenceTrack'
|
|
306
|
+
) {
|
|
307
|
+
return superTrackActionMenuItems?.(conf)
|
|
308
|
+
}
|
|
309
|
+
const trackId = readConfObject(conf, 'trackId') as string
|
|
310
|
+
const sessionTrackIdentifier = '-sessionTrack'
|
|
311
|
+
const isSessionTrack = trackId.endsWith(sessionTrackIdentifier)
|
|
312
|
+
return isSessionTrack
|
|
313
|
+
? [
|
|
314
|
+
...(superTrackActionMenuItems?.(conf) ?? []),
|
|
315
|
+
{
|
|
316
|
+
label: 'Save track to Apollo',
|
|
317
|
+
onClick: async () => {
|
|
318
|
+
const { internetAccounts, jbrowse } =
|
|
319
|
+
getRoot<ApolloRootModel>(self)
|
|
320
|
+
const currentConfig = getSnapshot<JBrowseConfig>(jbrowse)
|
|
321
|
+
let filteredConfig: JBrowseConfig | undefined
|
|
322
|
+
filteredConfig = filterJBrowseConfig(currentConfig)
|
|
323
|
+
if (Object.keys(filteredConfig).length === 0) {
|
|
324
|
+
filteredConfig = undefined
|
|
325
|
+
}
|
|
326
|
+
const trackConfigSnapshot = getSnapshot(conf) as {
|
|
327
|
+
trackId: string
|
|
328
|
+
type: string
|
|
329
|
+
}
|
|
330
|
+
const newTrackId = trackId.slice(
|
|
331
|
+
0,
|
|
332
|
+
trackId.length - sessionTrackIdentifier.length,
|
|
333
|
+
)
|
|
334
|
+
const newTrackConfigSnapshot = {
|
|
335
|
+
...trackConfigSnapshot,
|
|
336
|
+
trackId: newTrackId,
|
|
337
|
+
}
|
|
338
|
+
for (const internetAccount of internetAccounts as ApolloInternetAccountModel[]) {
|
|
339
|
+
if (internetAccount.type !== 'ApolloInternetAccount') {
|
|
340
|
+
continue
|
|
341
|
+
}
|
|
342
|
+
const change = new ImportJBrowseConfigChange({
|
|
343
|
+
typeName: 'ImportJBrowseConfigChange',
|
|
344
|
+
oldJBrowseConfig: filteredConfig,
|
|
345
|
+
newJBrowseConfig: {
|
|
346
|
+
...filteredConfig,
|
|
347
|
+
tracks: filteredConfig?.tracks && [
|
|
348
|
+
...filteredConfig.tracks,
|
|
349
|
+
newTrackConfigSnapshot,
|
|
350
|
+
],
|
|
351
|
+
},
|
|
352
|
+
})
|
|
353
|
+
const { internetAccountId } = internetAccount
|
|
354
|
+
await self.apolloDataStore.changeManager.submit(change, {
|
|
355
|
+
internetAccountId,
|
|
356
|
+
})
|
|
357
|
+
const { notify } = self as unknown as AbstractSessionModel
|
|
358
|
+
notify('Track added', 'success')
|
|
359
|
+
}
|
|
360
|
+
// @ts-expect-error This method is missing in the JB types
|
|
361
|
+
self.deleteTrackConf(conf)
|
|
362
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-call
|
|
363
|
+
jbrowse.addTrackConf(newTrackConfigSnapshot)
|
|
364
|
+
},
|
|
365
|
+
icon: SaveIcon,
|
|
366
|
+
},
|
|
367
|
+
]
|
|
368
|
+
: [
|
|
369
|
+
...(superTrackActionMenuItems?.(conf) ?? []),
|
|
370
|
+
{
|
|
371
|
+
label: 'Remove track from Apollo',
|
|
372
|
+
onClick: async () => {
|
|
373
|
+
const { internetAccounts, jbrowse } =
|
|
374
|
+
getRoot<ApolloRootModel>(self)
|
|
375
|
+
const currentConfig = getSnapshot<JBrowseConfig>(jbrowse)
|
|
376
|
+
let filteredConfig: JBrowseConfig | undefined
|
|
377
|
+
filteredConfig = filterJBrowseConfig(currentConfig)
|
|
378
|
+
if (Object.keys(filteredConfig).length === 0) {
|
|
379
|
+
filteredConfig = undefined
|
|
380
|
+
}
|
|
381
|
+
const filteredTracks = filteredConfig?.tracks?.filter(
|
|
382
|
+
(t) => t.trackId !== trackId,
|
|
383
|
+
)
|
|
384
|
+
for (const internetAccount of internetAccounts as ApolloInternetAccountModel[]) {
|
|
385
|
+
if (internetAccount.type !== 'ApolloInternetAccount') {
|
|
386
|
+
continue
|
|
387
|
+
}
|
|
388
|
+
const change = new ImportJBrowseConfigChange({
|
|
389
|
+
typeName: 'ImportJBrowseConfigChange',
|
|
390
|
+
oldJBrowseConfig: filteredConfig,
|
|
391
|
+
newJBrowseConfig: {
|
|
392
|
+
...filteredConfig,
|
|
393
|
+
tracks: filteredTracks,
|
|
394
|
+
},
|
|
395
|
+
})
|
|
396
|
+
const { internetAccountId } = internetAccount
|
|
397
|
+
await self.apolloDataStore.changeManager.submit(change, {
|
|
398
|
+
internetAccountId,
|
|
399
|
+
})
|
|
400
|
+
const { notify } = self as unknown as AbstractSessionModel
|
|
401
|
+
notify('Track removed', 'success')
|
|
402
|
+
}
|
|
403
|
+
// @ts-expect-error This method is missing in the JB types
|
|
404
|
+
self.deleteTrackConf(conf)
|
|
405
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-call
|
|
406
|
+
jbrowse.deleteTrackConf(conf)
|
|
407
|
+
},
|
|
408
|
+
icon: SaveIcon,
|
|
409
|
+
},
|
|
410
|
+
]
|
|
411
|
+
},
|
|
412
|
+
}
|
|
413
|
+
})
|
|
414
|
+
return types.snapshotProcessor(sm, {
|
|
415
|
+
postProcessor(snap: SnapshotOut<typeof sm>) {
|
|
416
|
+
snap.apolloSelectedFeature = undefined
|
|
417
|
+
const assemblies = Object.fromEntries(
|
|
418
|
+
Object.entries(snap.apolloDataStore.assemblies).filter(
|
|
419
|
+
([, assembly]) => assembly.backendDriverType === 'InMemoryFileDriver',
|
|
420
|
+
),
|
|
421
|
+
)
|
|
422
|
+
snap.apolloDataStore = {
|
|
423
|
+
typeName: 'Client',
|
|
424
|
+
assemblies,
|
|
425
|
+
checkResults: {},
|
|
426
|
+
}
|
|
427
|
+
return snap
|
|
428
|
+
},
|
|
429
|
+
})
|
|
362
430
|
}
|
|
363
431
|
|
|
364
432
|
export type ApolloSessionStateModel = ReturnType<typeof extendSession>
|
|
365
|
-
|
|
433
|
+
// @ts-expect-error Snapshots seem to mess up types here
|
|
434
|
+
// eslint disable because of
|
|
435
|
+
// https://mobx-state-tree.js.org/tips/typescript#using-a-mst-type-at-design-time
|
|
436
|
+
// eslint-disable-next-line @typescript-eslint/no-empty-interface
|
|
437
|
+
export interface ApolloSessionModel extends Instance<ApolloSessionStateModel> {}
|