@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
package/package.json
CHANGED
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@apollo-annotation/jbrowse-plugin-apollo",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.20",
|
|
4
4
|
"description": "Apollo plugin for JBrowse 2",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"jbrowse",
|
|
7
|
+
"jbrowse2"
|
|
8
|
+
],
|
|
5
9
|
"repository": {
|
|
6
10
|
"type": "git",
|
|
7
11
|
"url": "https://github.com/GMOD/Apollo3.git",
|
|
8
12
|
"directory": "packages/jbrowse-plugin-apollo"
|
|
9
13
|
},
|
|
10
|
-
"author": "JBrowse Team",
|
|
11
14
|
"license": "Apache-2.0",
|
|
12
|
-
"
|
|
13
|
-
"jbrowse",
|
|
14
|
-
"jbrowse2"
|
|
15
|
-
],
|
|
15
|
+
"author": "JBrowse Team",
|
|
16
16
|
"main": "dist/index.js",
|
|
17
17
|
"module": "dist/index.esm.js",
|
|
18
18
|
"typings": "dist/index.d.ts",
|
|
@@ -20,13 +20,6 @@
|
|
|
20
20
|
"dist",
|
|
21
21
|
"src"
|
|
22
22
|
],
|
|
23
|
-
"config": {
|
|
24
|
-
"jbrowse": {
|
|
25
|
-
"plugin": {
|
|
26
|
-
"name": "Apollo"
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
},
|
|
30
23
|
"scripts": {
|
|
31
24
|
"setup": "rimraf .jbrowse && jbrowse create .jbrowse",
|
|
32
25
|
"clean": "rimraf dist",
|
|
@@ -47,13 +40,17 @@
|
|
|
47
40
|
"prepack": "yarn build",
|
|
48
41
|
"postversion": "git push --follow-tags"
|
|
49
42
|
},
|
|
50
|
-
"
|
|
51
|
-
"
|
|
43
|
+
"config": {
|
|
44
|
+
"jbrowse": {
|
|
45
|
+
"plugin": {
|
|
46
|
+
"name": "Apollo"
|
|
47
|
+
}
|
|
48
|
+
}
|
|
52
49
|
},
|
|
53
50
|
"dependencies": {
|
|
54
|
-
"@apollo-annotation/common": "^0.1.
|
|
55
|
-
"@apollo-annotation/mst": "^0.1.
|
|
56
|
-
"@apollo-annotation/shared": "^0.1.
|
|
51
|
+
"@apollo-annotation/common": "^0.1.20",
|
|
52
|
+
"@apollo-annotation/mst": "^0.1.20",
|
|
53
|
+
"@apollo-annotation/shared": "^0.1.20",
|
|
57
54
|
"@emotion/react": "^11.10.6",
|
|
58
55
|
"@emotion/styled": "^11.10.6",
|
|
59
56
|
"@gmod/gff": "1.2.0",
|
|
@@ -74,21 +71,9 @@
|
|
|
74
71
|
"socket.io-client": "^4.5.4",
|
|
75
72
|
"tslib": "^2.3.1"
|
|
76
73
|
},
|
|
77
|
-
"peerDependencies": {
|
|
78
|
-
"@jbrowse/core": "^2.7.0",
|
|
79
|
-
"@mui/material": "^5.11.14",
|
|
80
|
-
"mobx": "^6.6.1",
|
|
81
|
-
"mobx-react": "^7.2.1",
|
|
82
|
-
"mobx-state-tree": "^5.1.7",
|
|
83
|
-
"prop-types": "^15.8.1",
|
|
84
|
-
"react": "^18.2.0",
|
|
85
|
-
"react-dom": "^18.2.0",
|
|
86
|
-
"rxjs": "^7.4.0",
|
|
87
|
-
"tss-react": "^4.6.1"
|
|
88
|
-
},
|
|
89
74
|
"devDependencies": {
|
|
90
75
|
"@jbrowse/cli": "^2.6.2",
|
|
91
|
-
"@jbrowse/core": "^2.
|
|
76
|
+
"@jbrowse/core": "^2.13.1",
|
|
92
77
|
"@jbrowse/development-tools": "^2.1.1",
|
|
93
78
|
"@jest/globals": "^29.0.3",
|
|
94
79
|
"@mui/material": "^5.11.14",
|
|
@@ -97,7 +82,7 @@
|
|
|
97
82
|
"@types/file-saver": "^2",
|
|
98
83
|
"@types/node": "^18.14.2",
|
|
99
84
|
"@types/prop-types": "^15",
|
|
100
|
-
"@types/react": "^
|
|
85
|
+
"@types/react": "^18.3.4",
|
|
101
86
|
"@types/react-dom": "^18",
|
|
102
87
|
"cypress": "12.17.3",
|
|
103
88
|
"cypress-mongodb": "^6.2.0",
|
|
@@ -121,9 +106,24 @@
|
|
|
121
106
|
"ts-jest": "^29.1.1",
|
|
122
107
|
"ts-node": "^10.3.0",
|
|
123
108
|
"tss-react": "^4.6.1",
|
|
124
|
-
"typescript": "^5.
|
|
109
|
+
"typescript": "^5.5.3"
|
|
110
|
+
},
|
|
111
|
+
"peerDependencies": {
|
|
112
|
+
"@jbrowse/core": "^2.13.1",
|
|
113
|
+
"@mui/material": "^5.11.14",
|
|
114
|
+
"mobx": "^6.6.1",
|
|
115
|
+
"mobx-react": "^7.2.1",
|
|
116
|
+
"mobx-state-tree": "^5.1.7",
|
|
117
|
+
"prop-types": "^15.8.1",
|
|
118
|
+
"react": "^18.2.0",
|
|
119
|
+
"react-dom": "^18.2.0",
|
|
120
|
+
"rxjs": "^7.4.0",
|
|
121
|
+
"tss-react": "^4.6.1"
|
|
125
122
|
},
|
|
126
123
|
"publishConfig": {
|
|
127
124
|
"access": "public"
|
|
125
|
+
},
|
|
126
|
+
"jbrowse-plugin": {
|
|
127
|
+
"name": "Apollo"
|
|
128
128
|
}
|
|
129
129
|
}
|
|
@@ -2,6 +2,7 @@ import { AbstractMenuManager, AbstractSessionModel } from '@jbrowse/core/util'
|
|
|
2
2
|
|
|
3
3
|
import {
|
|
4
4
|
AddAssembly,
|
|
5
|
+
AddRefSeqAliases,
|
|
5
6
|
DeleteAssembly,
|
|
6
7
|
ImportFeatures,
|
|
7
8
|
ManageUsers,
|
|
@@ -60,6 +61,23 @@ export function addMenuItems(rootModel: AbstractMenuManager) {
|
|
|
60
61
|
)
|
|
61
62
|
},
|
|
62
63
|
})
|
|
64
|
+
rootModel.appendToMenu('Apollo', {
|
|
65
|
+
label: 'Add reference sequence aliases',
|
|
66
|
+
onClick: (session: ApolloSessionModel) => {
|
|
67
|
+
;(session as unknown as AbstractSessionModel).queueDialog(
|
|
68
|
+
(doneCallback) => [
|
|
69
|
+
AddRefSeqAliases,
|
|
70
|
+
{
|
|
71
|
+
session,
|
|
72
|
+
handleClose: () => {
|
|
73
|
+
doneCallback()
|
|
74
|
+
},
|
|
75
|
+
changeManager: session.apolloDataStore.changeManager,
|
|
76
|
+
},
|
|
77
|
+
],
|
|
78
|
+
)
|
|
79
|
+
},
|
|
80
|
+
})
|
|
63
81
|
rootModel.appendToMenu('Apollo', {
|
|
64
82
|
label: 'Manage Users',
|
|
65
83
|
onClick: (session: ApolloSessionModel) => {
|
|
@@ -21,6 +21,9 @@ const ApolloConfigSchema = ConfigurationSchema(
|
|
|
21
21
|
|
|
22
22
|
export type ApolloInternetAccountConfigModel = typeof ApolloConfigSchema
|
|
23
23
|
|
|
24
|
-
|
|
25
|
-
|
|
24
|
+
// eslint disable because of
|
|
25
|
+
// https://mobx-state-tree.js.org/tips/typescript#using-a-mst-type-at-design-time
|
|
26
|
+
// eslint-disable-next-line @typescript-eslint/no-empty-interface
|
|
27
|
+
export interface ApolloInternetAccountConfig
|
|
28
|
+
extends Instance<ApolloInternetAccountConfigModel> {}
|
|
26
29
|
export default ApolloConfigSchema
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
/* eslint-disable @typescript-eslint/no-unused-vars */
|
|
2
1
|
/* eslint-disable @typescript-eslint/no-unsafe-return */
|
|
3
2
|
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
|
|
4
3
|
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
|
|
@@ -27,7 +26,7 @@ import { autorun } from 'mobx'
|
|
|
27
26
|
import { Instance, flow, getRoot, types } from 'mobx-state-tree'
|
|
28
27
|
import { io } from 'socket.io-client'
|
|
29
28
|
|
|
30
|
-
import {
|
|
29
|
+
import { Collaborator } from '../session'
|
|
31
30
|
import { ApolloRootModel } from '../types'
|
|
32
31
|
import { createFetchErrorMessage } from '../util'
|
|
33
32
|
import { addMenuItems } from './addMenuItems'
|
|
@@ -36,7 +35,7 @@ import { ApolloInternetAccountConfigModel } from './configSchema'
|
|
|
36
35
|
|
|
37
36
|
type AuthType = 'google' | 'microsoft' | 'guest'
|
|
38
37
|
|
|
39
|
-
type Role = 'admin' | 'user' | 'readOnly'
|
|
38
|
+
type Role = 'admin' | 'user' | 'readOnly' | 'none'
|
|
40
39
|
|
|
41
40
|
const inWebWorker = typeof sessionStorage === 'undefined'
|
|
42
41
|
|
|
@@ -439,6 +438,13 @@ const stateModelFactory = (configSchema: ApolloInternetAccountConfigModel) => {
|
|
|
439
438
|
if (inWebWorker) {
|
|
440
439
|
return
|
|
441
440
|
}
|
|
441
|
+
const { session } = getRoot<ApolloRootModel>(self)
|
|
442
|
+
// This can be undefined if there is no session loaded, e.g. on
|
|
443
|
+
// the start screen
|
|
444
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
445
|
+
if (!session) {
|
|
446
|
+
return
|
|
447
|
+
}
|
|
442
448
|
if (self.role) {
|
|
443
449
|
await self.initialize(self.role)
|
|
444
450
|
reaction.dispose()
|
|
@@ -454,5 +460,8 @@ export default stateModelFactory
|
|
|
454
460
|
export type ApolloInternetAccountStateModel = ReturnType<
|
|
455
461
|
typeof stateModelFactory
|
|
456
462
|
>
|
|
457
|
-
|
|
458
|
-
|
|
463
|
+
// eslint disable because of
|
|
464
|
+
// https://mobx-state-tree.js.org/tips/typescript#using-a-mst-type-at-design-time
|
|
465
|
+
// eslint-disable-next-line @typescript-eslint/no-empty-interface
|
|
466
|
+
export interface ApolloInternetAccountModel
|
|
467
|
+
extends Instance<ApolloInternetAccountStateModel> {}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { RefNameAliases } from './../BackendDrivers/BackendDriver'
|
|
2
|
+
import {
|
|
3
|
+
BaseRefNameAliasAdapter,
|
|
4
|
+
BaseAdapter,
|
|
5
|
+
} from '@jbrowse/core/data_adapters/BaseAdapter'
|
|
6
|
+
import { readConfObject } from '@jbrowse/core/configuration'
|
|
7
|
+
import { ApolloSessionModel } from '../session'
|
|
8
|
+
import { BackendDriver } from '../BackendDrivers'
|
|
9
|
+
import { nanoid } from 'nanoid'
|
|
10
|
+
import RpcServer from 'librpc-web-mod/dist/server'
|
|
11
|
+
|
|
12
|
+
declare global {
|
|
13
|
+
const rpcServer: RpcServer
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
interface ApolloRefNameAliasMessage {
|
|
17
|
+
apollo: true
|
|
18
|
+
messageId: string
|
|
19
|
+
refNameAliases: RefNameAliases[]
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function isApolloRefNameAliasMessage(
|
|
23
|
+
data?: unknown,
|
|
24
|
+
): data is ApolloRefNameAliasMessage {
|
|
25
|
+
return (
|
|
26
|
+
typeof data === 'object' &&
|
|
27
|
+
data !== null &&
|
|
28
|
+
'apollo' in data &&
|
|
29
|
+
data.apollo === true &&
|
|
30
|
+
'refNameAliases' in data
|
|
31
|
+
)
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const isInWebWorker = typeof sessionStorage === 'undefined'
|
|
35
|
+
|
|
36
|
+
export default class RefNameAliasAdapter
|
|
37
|
+
extends BaseAdapter
|
|
38
|
+
implements BaseRefNameAliasAdapter
|
|
39
|
+
{
|
|
40
|
+
private refNameAliases: RefNameAliases[] | undefined
|
|
41
|
+
|
|
42
|
+
async getRefNameAliases() {
|
|
43
|
+
const assemblyId = readConfObject(this.config, 'assemblyId') as string
|
|
44
|
+
if (!isInWebWorker) {
|
|
45
|
+
const dataStore = (
|
|
46
|
+
this.pluginManager?.rootModel?.session as ApolloSessionModel | undefined
|
|
47
|
+
)?.apolloDataStore
|
|
48
|
+
if (!dataStore) {
|
|
49
|
+
throw new Error('No Apollo data store found')
|
|
50
|
+
}
|
|
51
|
+
const backendDriver = dataStore.getBackendDriver(
|
|
52
|
+
assemblyId,
|
|
53
|
+
) as BackendDriver
|
|
54
|
+
const refNameAliases = await backendDriver.getRefNameAliases(assemblyId)
|
|
55
|
+
return refNameAliases
|
|
56
|
+
}
|
|
57
|
+
const refNameAliases = await new Promise(
|
|
58
|
+
(
|
|
59
|
+
resolve: (refNameAliases: RefNameAliases[]) => void,
|
|
60
|
+
reject: (reason: Error) => void,
|
|
61
|
+
) => {
|
|
62
|
+
const timeoutId = setTimeout(() => {
|
|
63
|
+
reject(new Error('timeout'))
|
|
64
|
+
}, 20_000)
|
|
65
|
+
const messageId = nanoid()
|
|
66
|
+
const messageListener = (event: MessageEvent) => {
|
|
67
|
+
const data = event.data as ApolloRefNameAliasMessage
|
|
68
|
+
if (!isApolloRefNameAliasMessage(data)) {
|
|
69
|
+
return
|
|
70
|
+
}
|
|
71
|
+
if (data.messageId !== messageId) {
|
|
72
|
+
return
|
|
73
|
+
}
|
|
74
|
+
clearTimeout(timeoutId)
|
|
75
|
+
removeEventListener('message', messageListener)
|
|
76
|
+
resolve(data.refNameAliases)
|
|
77
|
+
}
|
|
78
|
+
addEventListener('message', messageListener)
|
|
79
|
+
rpcServer.emit('apollo', {
|
|
80
|
+
apollo: true,
|
|
81
|
+
method: 'getRefNameAliases',
|
|
82
|
+
assembly: assemblyId,
|
|
83
|
+
messageId,
|
|
84
|
+
})
|
|
85
|
+
},
|
|
86
|
+
)
|
|
87
|
+
this.refNameAliases = refNameAliases
|
|
88
|
+
return refNameAliases
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
async freeResources() {
|
|
92
|
+
// no resources to free
|
|
93
|
+
}
|
|
94
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import AdapterType from '@jbrowse/core/pluggableElementTypes/AdapterType'
|
|
2
|
+
import PluginManager from '@jbrowse/core/PluginManager'
|
|
3
|
+
|
|
4
|
+
import configSchema from './configSchema'
|
|
5
|
+
import ApolloRefNameAliasAdapter from './ApolloRefNameAliasAdapter'
|
|
6
|
+
|
|
7
|
+
export function installApolloRefNameAliasAdapter(pluginManager: PluginManager) {
|
|
8
|
+
pluginManager.addAdapterType(
|
|
9
|
+
() =>
|
|
10
|
+
new AdapterType({
|
|
11
|
+
name: 'ApolloRefNameAliasAdapter',
|
|
12
|
+
configSchema,
|
|
13
|
+
adapterMetadata: {
|
|
14
|
+
category: undefined,
|
|
15
|
+
hiddenFromGUI: true,
|
|
16
|
+
description: undefined,
|
|
17
|
+
},
|
|
18
|
+
AdapterClass: ApolloRefNameAliasAdapter,
|
|
19
|
+
}),
|
|
20
|
+
)
|
|
21
|
+
}
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
/* eslint-disable @typescript-eslint/no-unsafe-argument */
|
|
6
6
|
/* eslint-disable @typescript-eslint/no-unnecessary-condition */
|
|
7
7
|
/* eslint-disable @typescript-eslint/no-misused-promises */
|
|
8
|
-
import {
|
|
8
|
+
import { AnnotationFeature } from '@apollo-annotation/mst'
|
|
9
9
|
import {
|
|
10
10
|
LocationEndChange,
|
|
11
11
|
LocationStartChange,
|
|
@@ -76,7 +76,7 @@ function selectColor(number: number) {
|
|
|
76
76
|
function ApolloRendering(props: ApolloRenderingProps) {
|
|
77
77
|
const [contextCoord, setContextCoord] = useState<Coord>()
|
|
78
78
|
const [contextMenuFeature, setContextMenuFeature] =
|
|
79
|
-
useState<
|
|
79
|
+
useState<AnnotationFeature>()
|
|
80
80
|
|
|
81
81
|
const canvasRef = useRef<HTMLCanvasElement>(null)
|
|
82
82
|
const overlayCanvasRef = useRef<HTMLCanvasElement>(null)
|
|
@@ -86,7 +86,7 @@ function ApolloRendering(props: ApolloRenderingProps) {
|
|
|
86
86
|
// const [overEdge, setOverEdge] = useState<'start' | 'end'>()
|
|
87
87
|
const [dragging, setDragging] = useState<{
|
|
88
88
|
edge: 'start' | 'end'
|
|
89
|
-
feature:
|
|
89
|
+
feature: AnnotationFeature
|
|
90
90
|
row: number
|
|
91
91
|
bp: number
|
|
92
92
|
px: number
|
|
@@ -187,9 +187,9 @@ function ApolloRendering(props: ApolloRenderingProps) {
|
|
|
187
187
|
for (const [row, featureInfos] of featureLayout) {
|
|
188
188
|
for (const [parentID, feature] of featureInfos) {
|
|
189
189
|
const start = region.reversed
|
|
190
|
-
? region.end - feature.
|
|
191
|
-
: feature.
|
|
192
|
-
const end = feature.
|
|
190
|
+
? region.end - feature.max
|
|
191
|
+
: feature.min - region.start - 1
|
|
192
|
+
const end = feature.max - region.start - 1
|
|
193
193
|
const startPx = start / bpPerPx
|
|
194
194
|
const endPx = end / bpPerPx
|
|
195
195
|
const width = end - start
|
|
@@ -463,7 +463,7 @@ function ApolloRendering(props: ApolloRenderingProps) {
|
|
|
463
463
|
// // eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
464
464
|
// const [parentID, feat] =
|
|
465
465
|
// layoutRow.find((f) => bp >= f[1].min && bp <= f[1].max) || []
|
|
466
|
-
// let feature:
|
|
466
|
+
// let feature: AnnotationFeature | undefined = feat
|
|
467
467
|
// if (feature) {
|
|
468
468
|
// const topRow = row
|
|
469
469
|
// const startPx = (feature.start - region.start) / bpPerPx
|
|
@@ -473,7 +473,7 @@ function ApolloRendering(props: ApolloRenderingProps) {
|
|
|
473
473
|
// y - topRow * height,
|
|
474
474
|
// bpPerPx,
|
|
475
475
|
// height,
|
|
476
|
-
// ) as
|
|
476
|
+
// ) as AnnotationFeature
|
|
477
477
|
// }
|
|
478
478
|
// if (feature) {
|
|
479
479
|
// // TODO: check reversed
|
|
@@ -526,7 +526,7 @@ function ApolloRendering(props: ApolloRenderingProps) {
|
|
|
526
526
|
let change: LocationEndChange | LocationStartChange
|
|
527
527
|
if (edge === 'end') {
|
|
528
528
|
const featureId = feature._id
|
|
529
|
-
const oldEnd = feature.
|
|
529
|
+
const oldEnd = feature.max
|
|
530
530
|
const newEnd = Math.round(bp)
|
|
531
531
|
change = new LocationEndChange({
|
|
532
532
|
typeName: 'LocationEndChange',
|
|
@@ -538,7 +538,7 @@ function ApolloRendering(props: ApolloRenderingProps) {
|
|
|
538
538
|
})
|
|
539
539
|
} else {
|
|
540
540
|
const featureId = feature._id
|
|
541
|
-
const oldStart = feature.
|
|
541
|
+
const oldStart = feature.min
|
|
542
542
|
const newStart = Math.round(bp)
|
|
543
543
|
change = new LocationStartChange({
|
|
544
544
|
typeName: 'LocationStartChange',
|
|
@@ -1,8 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
|
|
3
|
-
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
|
|
4
|
-
/* eslint-disable @typescript-eslint/no-unsafe-call */
|
|
5
|
-
/* eslint-disable @typescript-eslint/no-unsafe-argument */
|
|
1
|
+
import { AnnotationFeatureSnapshot } from '@apollo-annotation/mst'
|
|
6
2
|
import { readConfObject } from '@jbrowse/core/configuration'
|
|
7
3
|
import {
|
|
8
4
|
BaseAdapter,
|
|
@@ -10,58 +6,65 @@ import {
|
|
|
10
6
|
BaseTextSearchArgs,
|
|
11
7
|
} from '@jbrowse/core/data_adapters/BaseAdapter'
|
|
12
8
|
import BaseResult from '@jbrowse/core/TextSearch/BaseResults'
|
|
9
|
+
import { AbstractSessionModel, UriLocation } from '@jbrowse/core/util'
|
|
10
|
+
import { ApolloSessionModel } from '../session'
|
|
11
|
+
import { Assembly } from '@jbrowse/core/assemblyManager/assembly'
|
|
13
12
|
|
|
14
13
|
export class ApolloTextSearchAdapter
|
|
15
14
|
extends BaseAdapter
|
|
16
15
|
implements BaseTextSearchAdapter
|
|
17
16
|
{
|
|
18
17
|
get baseURL() {
|
|
19
|
-
return readConfObject(this.config, 'baseURL').uri
|
|
18
|
+
return (readConfObject(this.config, 'baseURL') as UriLocation).uri
|
|
20
19
|
}
|
|
21
20
|
|
|
22
21
|
get trackId() {
|
|
23
|
-
return readConfObject(this.config, 'trackId')
|
|
22
|
+
return readConfObject(this.config, 'trackId') as string
|
|
24
23
|
}
|
|
25
24
|
|
|
26
25
|
get assemblyNames() {
|
|
27
|
-
return readConfObject(this.config, 'assemblyNames')
|
|
26
|
+
return readConfObject(this.config, 'assemblyNames') as string[]
|
|
28
27
|
}
|
|
29
28
|
|
|
30
29
|
mapBaseResult(
|
|
31
|
-
features:
|
|
32
|
-
|
|
33
|
-
start: number
|
|
34
|
-
end: number
|
|
35
|
-
}[],
|
|
30
|
+
features: AnnotationFeatureSnapshot[],
|
|
31
|
+
assembly: Assembly,
|
|
36
32
|
query: string,
|
|
37
33
|
) {
|
|
38
|
-
return features.map(
|
|
39
|
-
(feature)
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
}),
|
|
47
|
-
)
|
|
34
|
+
return features.map((feature) => {
|
|
35
|
+
const refName = assembly.getCanonicalRefName(feature.refSeq)
|
|
36
|
+
return new BaseResult({
|
|
37
|
+
label: query,
|
|
38
|
+
trackId: this.trackId,
|
|
39
|
+
locString: `${refName}:${feature.min + 1}..${feature.max}`,
|
|
40
|
+
})
|
|
41
|
+
})
|
|
48
42
|
}
|
|
49
43
|
|
|
50
44
|
async searchIndex(args: BaseTextSearchArgs): Promise<BaseResult[]> {
|
|
51
|
-
const
|
|
45
|
+
const query = args.queryString
|
|
46
|
+
const results: BaseResult[] = []
|
|
47
|
+
const session = this.pluginManager?.rootModel?.session as
|
|
48
|
+
| ApolloSessionModel
|
|
49
|
+
| undefined
|
|
50
|
+
if (!session) {
|
|
51
|
+
return results
|
|
52
|
+
}
|
|
53
|
+
const { apolloDataStore } = session
|
|
54
|
+
const { assemblyManager } = session as unknown as AbstractSessionModel
|
|
52
55
|
for (const assemblyName of this.assemblyNames) {
|
|
53
|
-
|
|
54
|
-
const
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
56
|
+
const backendDriver = apolloDataStore.getBackendDriver(assemblyName)
|
|
57
|
+
const assembly = assemblyManager.get(assemblyName)
|
|
58
|
+
if (!(backendDriver && assembly)) {
|
|
59
|
+
continue
|
|
60
|
+
}
|
|
61
|
+
const features = await backendDriver.searchFeatures(args.queryString, [
|
|
58
62
|
assemblyName,
|
|
59
63
|
])
|
|
60
|
-
results.push(...
|
|
64
|
+
results.push(...this.mapBaseResult(features, assembly, query))
|
|
61
65
|
}
|
|
62
66
|
|
|
63
|
-
|
|
64
|
-
return this.mapBaseResult(results, query)
|
|
67
|
+
return results
|
|
65
68
|
}
|
|
66
69
|
|
|
67
70
|
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
|
@@ -9,6 +9,12 @@ import { Region } from '@jbrowse/core/util'
|
|
|
9
9
|
|
|
10
10
|
import { SubmitOpts } from '../ChangeManager'
|
|
11
11
|
|
|
12
|
+
export interface RefNameAliases {
|
|
13
|
+
refName: string
|
|
14
|
+
aliases: string[]
|
|
15
|
+
uniqueId: string
|
|
16
|
+
}
|
|
17
|
+
|
|
12
18
|
export abstract class BackendDriver {
|
|
13
19
|
constructor(protected clientStore: ClientDataStore) {}
|
|
14
20
|
|
|
@@ -22,6 +28,8 @@ export abstract class BackendDriver {
|
|
|
22
28
|
|
|
23
29
|
abstract getAssemblies(internetAccountConfigId?: string): Assembly[]
|
|
24
30
|
|
|
31
|
+
abstract getRefNameAliases(assemblyName: string): Promise<RefNameAliases[]>
|
|
32
|
+
|
|
25
33
|
abstract submitChange(
|
|
26
34
|
change: Change,
|
|
27
35
|
opts: SubmitOpts,
|
|
@@ -18,7 +18,16 @@ import { Socket } from 'socket.io-client'
|
|
|
18
18
|
|
|
19
19
|
import { ChangeManager, SubmitOpts } from '../ChangeManager'
|
|
20
20
|
import { createFetchErrorMessage } from '../util'
|
|
21
|
-
import { BackendDriver } from './BackendDriver'
|
|
21
|
+
import { BackendDriver, RefNameAliases } from './BackendDriver'
|
|
22
|
+
|
|
23
|
+
export interface ApolloRefSeqResponse {
|
|
24
|
+
_id: string
|
|
25
|
+
name: string
|
|
26
|
+
description?: string
|
|
27
|
+
aliases: string[]
|
|
28
|
+
length: string
|
|
29
|
+
assembly: string
|
|
30
|
+
}
|
|
22
31
|
|
|
23
32
|
export interface ApolloInternetAccount extends BaseInternetAccountModel {
|
|
24
33
|
baseURL: string
|
|
@@ -235,6 +244,45 @@ export class CollaborationServerDriver extends BackendDriver {
|
|
|
235
244
|
return seq
|
|
236
245
|
}
|
|
237
246
|
|
|
247
|
+
async getRefNameAliases(assemblyName: string): Promise<RefNameAliases[]> {
|
|
248
|
+
const { assemblyManager } = getSession(this.clientStore)
|
|
249
|
+
const assembly = assemblyManager.get(assemblyName)
|
|
250
|
+
if (!assembly) {
|
|
251
|
+
throw new Error(`Could not find assembly with name "${assemblyName}"`)
|
|
252
|
+
}
|
|
253
|
+
const internetAccount = this.clientStore.getInternetAccount(
|
|
254
|
+
assemblyName,
|
|
255
|
+
) as ApolloInternetAccount
|
|
256
|
+
const { baseURL } = internetAccount
|
|
257
|
+
const url = new URL('refSeqs', baseURL)
|
|
258
|
+
const searchParams = new URLSearchParams({ assembly: assemblyName })
|
|
259
|
+
url.search = searchParams.toString()
|
|
260
|
+
const uri = url.toString()
|
|
261
|
+
|
|
262
|
+
const response = await this.fetch(internetAccount, uri)
|
|
263
|
+
if (!response.ok) {
|
|
264
|
+
let errorMessage
|
|
265
|
+
try {
|
|
266
|
+
errorMessage = await response.text()
|
|
267
|
+
} catch {
|
|
268
|
+
errorMessage = ''
|
|
269
|
+
}
|
|
270
|
+
throw new Error(
|
|
271
|
+
`getRefNameAliases failed: ${response.status} (${response.statusText})${
|
|
272
|
+
errorMessage ? ` (${errorMessage})` : ''
|
|
273
|
+
}`,
|
|
274
|
+
)
|
|
275
|
+
}
|
|
276
|
+
const refSeqs = (await response.json()) as ApolloRefSeqResponse[]
|
|
277
|
+
return refSeqs.map((refSeq) => {
|
|
278
|
+
return {
|
|
279
|
+
refName: refSeq.name,
|
|
280
|
+
aliases: [refSeq._id, ...refSeq.aliases],
|
|
281
|
+
uniqueId: `alias-${refSeq._id}`,
|
|
282
|
+
}
|
|
283
|
+
}) as RefNameAliases[]
|
|
284
|
+
}
|
|
285
|
+
|
|
238
286
|
async getRegions(assemblyName: string): Promise<Region[]> {
|
|
239
287
|
const { assemblyManager } = getSession(this.clientStore)
|
|
240
288
|
const assembly = assemblyManager.get(assemblyName)
|
|
@@ -19,7 +19,7 @@ import { Region, getSession } from '@jbrowse/core/util'
|
|
|
19
19
|
import { getSnapshot } from 'mobx-state-tree'
|
|
20
20
|
|
|
21
21
|
import { checkFeatures, loadAssemblyIntoClient } from '../util'
|
|
22
|
-
import { BackendDriver } from './BackendDriver'
|
|
22
|
+
import { BackendDriver, RefNameAliases } from './BackendDriver'
|
|
23
23
|
|
|
24
24
|
export class DesktopFileDriver extends BackendDriver {
|
|
25
25
|
async loadAssembly(assemblyName: string) {
|
|
@@ -45,6 +45,19 @@ export class DesktopFileDriver extends BackendDriver {
|
|
|
45
45
|
return assembly
|
|
46
46
|
}
|
|
47
47
|
|
|
48
|
+
async getRefNameAliases(assemblyName: string): Promise<RefNameAliases[]> {
|
|
49
|
+
const assembly = await this.getAssembly(assemblyName)
|
|
50
|
+
const refNameAliases: RefNameAliases[] = []
|
|
51
|
+
for (const [, refSeq] of assembly.refSeqs) {
|
|
52
|
+
refNameAliases.push({
|
|
53
|
+
refName: refSeq.name,
|
|
54
|
+
aliases: [refSeq._id],
|
|
55
|
+
uniqueId: `alias-${refSeq._id}`,
|
|
56
|
+
})
|
|
57
|
+
}
|
|
58
|
+
return refNameAliases
|
|
59
|
+
}
|
|
60
|
+
|
|
48
61
|
async getFeatures(
|
|
49
62
|
region: Region,
|
|
50
63
|
): Promise<[AnnotationFeatureSnapshot[], CheckResultSnapshot[]]> {
|
|
@@ -9,7 +9,7 @@ import { getConf } from '@jbrowse/core/configuration'
|
|
|
9
9
|
import { Region, getSession } from '@jbrowse/core/util'
|
|
10
10
|
|
|
11
11
|
import { SubmitOpts } from '../ChangeManager'
|
|
12
|
-
import { BackendDriver } from './BackendDriver'
|
|
12
|
+
import { BackendDriver, RefNameAliases } from './BackendDriver'
|
|
13
13
|
|
|
14
14
|
export class InMemoryFileDriver extends BackendDriver {
|
|
15
15
|
async getFeatures(): Promise<
|
|
@@ -32,6 +32,22 @@ export class InMemoryFileDriver extends BackendDriver {
|
|
|
32
32
|
return { seq, refSeq: refName }
|
|
33
33
|
}
|
|
34
34
|
|
|
35
|
+
async getRefNameAliases(assemblyName: string): Promise<RefNameAliases[]> {
|
|
36
|
+
const assembly = this.clientStore.assemblies.get(assemblyName)
|
|
37
|
+
const refNameAliases: RefNameAliases[] = []
|
|
38
|
+
if (!assembly) {
|
|
39
|
+
return refNameAliases
|
|
40
|
+
}
|
|
41
|
+
for (const [, refSeq] of assembly.refSeqs) {
|
|
42
|
+
refNameAliases.push({
|
|
43
|
+
refName: refSeq.name,
|
|
44
|
+
aliases: [refSeq._id],
|
|
45
|
+
uniqueId: `alias-${refSeq._id}`,
|
|
46
|
+
})
|
|
47
|
+
}
|
|
48
|
+
return refNameAliases
|
|
49
|
+
}
|
|
50
|
+
|
|
35
51
|
async getRegions(assemblyName: string): Promise<Region[]> {
|
|
36
52
|
const assembly = this.clientStore.assemblies.get(assemblyName)
|
|
37
53
|
if (!assembly) {
|