@apollo-annotation/jbrowse-plugin-apollo 0.1.20 → 0.2.0
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 +552 -642
- package/dist/index.esm.js.map +1 -1
- package/dist/jbrowse-plugin-apollo.cjs.development.js +560 -650
- 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 +11294 -1232
- 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 +4 -5
- package/src/ApolloInternetAccount/components/AuthTypeSelector.tsx +4 -2
- package/src/ApolloInternetAccount/configSchema.ts +1 -1
- package/src/ApolloInternetAccount/model.ts +5 -10
- package/src/ApolloRefNameAliasAdapter/ApolloRefNameAliasAdapter.ts +1 -1
- package/src/ApolloSixFrameRenderer/components/ApolloRendering.tsx +4 -5
- package/src/BackendDrivers/DesktopFileDriver.ts +3 -2
- package/src/FeatureDetailsWidget/Attributes.tsx +1 -6
- package/src/FeatureDetailsWidget/NumberTextField.tsx +1 -0
- package/src/FeatureDetailsWidget/StringTextField.tsx +1 -0
- package/src/FeatureDetailsWidget/TranscriptBasic.tsx +131 -382
- package/src/FeatureDetailsWidget/TranscriptSequence.tsx +209 -284
- package/src/FeatureDetailsWidget/model.ts +4 -4
- package/src/LinearApolloDisplay/components/LinearApolloDisplay.tsx +1 -4
- package/src/LinearApolloDisplay/configSchema.ts +5 -14
- package/src/LinearApolloDisplay/glyphs/BoxGlyph.ts +25 -3
- package/src/LinearApolloDisplay/glyphs/GeneGlyph.ts +95 -32
- package/src/LinearApolloDisplay/index.ts +1 -1
- package/src/LinearApolloDisplay/stateModel/base.ts +104 -17
- package/src/LinearApolloDisplay/stateModel/index.ts +1 -1
- package/src/LinearApolloDisplay/stateModel/mouseEvents.ts +1 -1
- package/src/LinearApolloDisplay/stateModel/rendering.ts +1 -1
- package/src/OntologyManager/OntologyStore/fulltext.ts +5 -2
- package/src/OntologyManager/OntologyStore/index.ts +25 -22
- package/src/OntologyManager/OntologyStore/indexeddb-storage.ts +8 -3
- package/src/OntologyManager/index.ts +31 -8
- package/src/SixFrameFeatureDisplay/stateModel.ts +1 -1
- package/src/TabularEditor/HybridGrid/HybridGrid.tsx +1 -0
- package/src/TabularEditor/HybridGrid/NumberCell.tsx +1 -0
- package/src/TabularEditor/model.ts +1 -1
- package/src/components/AddChildFeature.tsx +1 -0
- package/src/components/AddFeature.tsx +1 -1
- package/src/components/AddRefSeqAliases.tsx +1 -0
- package/src/components/CopyFeature.tsx +1 -0
- package/src/components/DeleteAssembly.tsx +1 -0
- package/src/components/DeleteFeature.tsx +1 -0
- package/src/components/LogOut.tsx +2 -1
- package/src/components/ManageChecks.tsx +1 -1
- package/src/components/ManageUsers.tsx +2 -1
- package/src/components/OntologyTermAutocomplete.tsx +7 -9
- package/src/components/OntologyTermMultiSelect.tsx +2 -1
- package/src/components/OpenLocalFile.tsx +3 -1
- package/src/components/ViewChangeLog.tsx +1 -0
- package/src/components/ViewCheckResults.tsx +1 -0
- package/src/config.ts +5 -0
- package/src/extensions/annotationFromPileup.ts +1 -1
- package/src/index.ts +2 -2
- package/src/makeDisplayComponent.tsx +77 -32
- package/src/session/ClientDataStore.ts +1 -1
- package/src/session/session.ts +2 -1
- package/src/LinearApolloDisplay/stateModel/trackHeightMixin.ts +0 -43
|
@@ -2,7 +2,11 @@ import { AnnotationFeature } from '@apollo-annotation/mst'
|
|
|
2
2
|
import { Theme, alpha } from '@mui/material'
|
|
3
3
|
import { MenuItem } from '@jbrowse/core/ui'
|
|
4
4
|
|
|
5
|
-
import {
|
|
5
|
+
import {
|
|
6
|
+
AbstractSessionModel,
|
|
7
|
+
isSessionModelWithWidgets,
|
|
8
|
+
SessionWithWidgets,
|
|
9
|
+
} from '@jbrowse/core/util'
|
|
6
10
|
|
|
7
11
|
import {
|
|
8
12
|
AddChildFeature,
|
|
@@ -175,7 +179,7 @@ function drawTooltip(
|
|
|
175
179
|
if (!position) {
|
|
176
180
|
return
|
|
177
181
|
}
|
|
178
|
-
const { layoutIndex, layoutRow } = position
|
|
182
|
+
const { featureRow, layoutIndex, layoutRow } = position
|
|
179
183
|
const { bpPerPx, displayedRegions, offsetPx } = lgv
|
|
180
184
|
const displayedRegion = displayedRegions[layoutIndex]
|
|
181
185
|
const { refName, reversed } = displayedRegion
|
|
@@ -191,7 +195,7 @@ function drawTooltip(
|
|
|
191
195
|
coord: reversed ? max : min,
|
|
192
196
|
regionNumber: layoutIndex,
|
|
193
197
|
})?.offsetPx ?? 0) - offsetPx
|
|
194
|
-
const top = layoutRow * apolloRowHeight
|
|
198
|
+
const top = (layoutRow + featureRow) * apolloRowHeight
|
|
195
199
|
const widthPx = length / bpPerPx
|
|
196
200
|
|
|
197
201
|
const featureType = `Type: ${feature.type}`
|
|
@@ -385,6 +389,24 @@ function getContextMenuItems(
|
|
|
385
389
|
},
|
|
386
390
|
},
|
|
387
391
|
)
|
|
392
|
+
if (sourceFeature.type === 'mRNA' && isSessionModelWithWidgets(session)) {
|
|
393
|
+
menuItems.push({
|
|
394
|
+
label: 'Edit transcript details',
|
|
395
|
+
onClick: () => {
|
|
396
|
+
const apolloTranscriptWidget = session.addWidget(
|
|
397
|
+
'ApolloTranscriptDetails',
|
|
398
|
+
'apolloTranscriptDetails',
|
|
399
|
+
{
|
|
400
|
+
feature: sourceFeature,
|
|
401
|
+
assembly: currentAssemblyId,
|
|
402
|
+
changeManager,
|
|
403
|
+
refName: region.refName,
|
|
404
|
+
},
|
|
405
|
+
)
|
|
406
|
+
session.showWidget(apolloTranscriptWidget)
|
|
407
|
+
},
|
|
408
|
+
})
|
|
409
|
+
}
|
|
388
410
|
return menuItems
|
|
389
411
|
}
|
|
390
412
|
|
|
@@ -13,35 +13,49 @@ import { Glyph } from './Glyph'
|
|
|
13
13
|
import { boxGlyph } from './BoxGlyph'
|
|
14
14
|
import { LinearApolloDisplayRendering } from '../stateModel/rendering'
|
|
15
15
|
|
|
16
|
-
let
|
|
17
|
-
let
|
|
18
|
-
|
|
16
|
+
let forwardFillLight: CanvasPattern | null = null
|
|
17
|
+
let backwardFillLight: CanvasPattern | null = null
|
|
18
|
+
let forwardFillDark: CanvasPattern | null = null
|
|
19
|
+
let backwardFillDark: CanvasPattern | null = null
|
|
20
|
+
if ('document' in globalThis) {
|
|
19
21
|
for (const direction of ['forward', 'backward']) {
|
|
20
|
-
const
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
?
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
22
|
+
for (const themeMode of ['light', 'dark']) {
|
|
23
|
+
const canvas = document.createElement('canvas')
|
|
24
|
+
const canvasSize = 10
|
|
25
|
+
canvas.width = canvas.height = canvasSize
|
|
26
|
+
const ctx = canvas.getContext('2d')
|
|
27
|
+
if (ctx) {
|
|
28
|
+
const stripeColor1 =
|
|
29
|
+
themeMode === 'light' ? 'rgba(0,0,0,0)' : 'rgba(0,0,0,0.75)'
|
|
30
|
+
const stripeColor2 =
|
|
31
|
+
themeMode === 'light' ? 'rgba(255,255,255,0.25)' : 'rgba(0,0,0,0.50)'
|
|
32
|
+
const gradient =
|
|
33
|
+
direction === 'forward'
|
|
34
|
+
? ctx.createLinearGradient(0, canvasSize, canvasSize, 0)
|
|
35
|
+
: ctx.createLinearGradient(0, 0, canvasSize, canvasSize)
|
|
36
|
+
gradient.addColorStop(0, stripeColor1)
|
|
37
|
+
gradient.addColorStop(0.25, stripeColor1)
|
|
38
|
+
gradient.addColorStop(0.25, stripeColor2)
|
|
39
|
+
gradient.addColorStop(0.5, stripeColor2)
|
|
40
|
+
gradient.addColorStop(0.5, stripeColor1)
|
|
41
|
+
gradient.addColorStop(0.75, stripeColor1)
|
|
42
|
+
gradient.addColorStop(0.75, stripeColor2)
|
|
43
|
+
gradient.addColorStop(1, stripeColor2)
|
|
44
|
+
ctx.fillStyle = gradient
|
|
45
|
+
ctx.fillRect(0, 0, 10, 10)
|
|
46
|
+
if (direction === 'forward') {
|
|
47
|
+
if (themeMode === 'light') {
|
|
48
|
+
forwardFillLight = ctx.createPattern(canvas, 'repeat')
|
|
49
|
+
} else {
|
|
50
|
+
forwardFillDark = ctx.createPattern(canvas, 'repeat')
|
|
51
|
+
}
|
|
52
|
+
} else {
|
|
53
|
+
if (themeMode === 'light') {
|
|
54
|
+
backwardFillLight = ctx.createPattern(canvas, 'repeat')
|
|
55
|
+
} else {
|
|
56
|
+
backwardFillDark = ctx.createPattern(canvas, 'repeat')
|
|
57
|
+
}
|
|
58
|
+
}
|
|
45
59
|
}
|
|
46
60
|
}
|
|
47
61
|
}
|
|
@@ -61,13 +75,34 @@ function draw(
|
|
|
61
75
|
const rowHeight = apolloRowHeight
|
|
62
76
|
const exonHeight = Math.round(0.6 * rowHeight)
|
|
63
77
|
const cdsHeight = Math.round(0.9 * rowHeight)
|
|
64
|
-
const { strand } = feature
|
|
65
|
-
const { children } = feature
|
|
78
|
+
const { children, min, strand } = feature
|
|
66
79
|
if (!children) {
|
|
67
80
|
return
|
|
68
81
|
}
|
|
69
82
|
const { apolloSelectedFeature } = session
|
|
70
83
|
|
|
84
|
+
// Draw background for gene
|
|
85
|
+
const topLevelFeatureMinX =
|
|
86
|
+
(lgv.bpToPx({
|
|
87
|
+
refName,
|
|
88
|
+
coord: min,
|
|
89
|
+
regionNumber: displayedRegionIndex,
|
|
90
|
+
})?.offsetPx ?? 0) - offsetPx
|
|
91
|
+
const topLevelFeatureWidthPx = feature.length / bpPerPx
|
|
92
|
+
const topLevelFeatureStartPx = reversed
|
|
93
|
+
? topLevelFeatureMinX - topLevelFeatureWidthPx
|
|
94
|
+
: topLevelFeatureMinX
|
|
95
|
+
const topLevelFeatureTop = row * rowHeight
|
|
96
|
+
const topLevelFeatureHeight = getRowCount(feature) * rowHeight
|
|
97
|
+
|
|
98
|
+
ctx.fillStyle = alpha(theme?.palette.background.paper ?? '#ffffff', 0.6)
|
|
99
|
+
ctx.fillRect(
|
|
100
|
+
topLevelFeatureStartPx,
|
|
101
|
+
topLevelFeatureTop,
|
|
102
|
+
topLevelFeatureWidthPx,
|
|
103
|
+
topLevelFeatureHeight,
|
|
104
|
+
)
|
|
105
|
+
|
|
71
106
|
// Draw lines on different rows for each mRNA
|
|
72
107
|
let currentRow = 0
|
|
73
108
|
for (const [, mrna] of children) {
|
|
@@ -102,6 +137,10 @@ function draw(
|
|
|
102
137
|
}
|
|
103
138
|
}
|
|
104
139
|
|
|
140
|
+
const forwardFill =
|
|
141
|
+
theme?.palette.mode === 'dark' ? forwardFillDark : forwardFillLight
|
|
142
|
+
const backwardFill =
|
|
143
|
+
theme?.palette.mode === 'dark' ? backwardFillDark : backwardFillLight
|
|
105
144
|
// Draw exon and CDS for each mRNA
|
|
106
145
|
currentRow = 0
|
|
107
146
|
for (const [, child] of children) {
|
|
@@ -289,11 +328,35 @@ function getFeatureFromLayout(
|
|
|
289
328
|
bp: number,
|
|
290
329
|
row: number,
|
|
291
330
|
): AnnotationFeature | undefined {
|
|
292
|
-
const featureInThisRow: AnnotationFeature[] =
|
|
331
|
+
const featureInThisRow: AnnotationFeature[] =
|
|
332
|
+
featuresForRow(feature)[row] || []
|
|
293
333
|
for (const f of featureInThisRow) {
|
|
334
|
+
let featureObj
|
|
294
335
|
if (bp >= f.min && bp <= f.max && f.parent) {
|
|
295
|
-
|
|
336
|
+
featureObj = f
|
|
337
|
+
}
|
|
338
|
+
if (!featureObj) {
|
|
339
|
+
continue
|
|
340
|
+
}
|
|
341
|
+
if (
|
|
342
|
+
featureObj.type === 'CDS' &&
|
|
343
|
+
featureObj.parent &&
|
|
344
|
+
featureObj.parent.type === 'mRNA'
|
|
345
|
+
) {
|
|
346
|
+
const { cdsLocations } = featureObj.parent
|
|
347
|
+
for (const cdsLoc of cdsLocations) {
|
|
348
|
+
for (const loc of cdsLoc) {
|
|
349
|
+
if (bp >= loc.min && bp <= loc.max) {
|
|
350
|
+
return featureObj
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
// If mouse position is in the intron region, return the mRNA
|
|
356
|
+
return featureObj.parent
|
|
296
357
|
}
|
|
358
|
+
// If mouse position is in a feature that is not a CDS, return the feature
|
|
359
|
+
return featureObj
|
|
297
360
|
}
|
|
298
361
|
return feature
|
|
299
362
|
}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export {
|
|
1
|
+
export { configSchema } from './configSchema'
|
|
2
2
|
export { stateModelFactory } from './stateModel'
|
|
@@ -22,29 +22,27 @@ import { addDisposer, getRoot, types } from 'mobx-state-tree'
|
|
|
22
22
|
import { ApolloInternetAccountModel } from '../../ApolloInternetAccount/model'
|
|
23
23
|
import { ApolloSessionModel } from '../../session'
|
|
24
24
|
import { ApolloRootModel } from '../../types'
|
|
25
|
-
|
|
25
|
+
|
|
26
|
+
const minDisplayHeight = 20
|
|
26
27
|
|
|
27
28
|
export function baseModelFactory(
|
|
28
29
|
_pluginManager: PluginManager,
|
|
29
30
|
configSchema: AnyConfigurationSchemaType,
|
|
30
31
|
) {
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
// const LGVPlugin = pluginManager.getPlugin(
|
|
34
|
-
// 'LinearGenomeViewPlugin',
|
|
35
|
-
// ) as LinearGenomeViewPlugin
|
|
36
|
-
// const { TrackHeightMixin } = LGVPlugin.exports
|
|
37
|
-
|
|
38
|
-
return types
|
|
39
|
-
.compose(BaseDisplay, TrackHeightMixin)
|
|
40
|
-
.named('BaseLinearApolloDisplay')
|
|
32
|
+
return BaseDisplay.named('BaseLinearApolloDisplay')
|
|
41
33
|
.props({
|
|
42
34
|
type: types.literal('LinearApolloDisplay'),
|
|
43
35
|
configuration: ConfigurationReference(configSchema),
|
|
36
|
+
graphical: true,
|
|
37
|
+
table: false,
|
|
38
|
+
heightPreConfig: types.maybe(
|
|
39
|
+
types.refinement(
|
|
40
|
+
'displayHeight',
|
|
41
|
+
types.number,
|
|
42
|
+
(n) => n >= minDisplayHeight,
|
|
43
|
+
),
|
|
44
|
+
),
|
|
44
45
|
})
|
|
45
|
-
.volatile((self) => ({
|
|
46
|
-
lgv: getContainingView(self) as unknown as LinearGenomeViewModel,
|
|
47
|
-
}))
|
|
48
46
|
.views((self) => {
|
|
49
47
|
const { configuration, renderProps: superRenderProps } = self
|
|
50
48
|
return {
|
|
@@ -57,6 +55,26 @@ export function baseModelFactory(
|
|
|
57
55
|
},
|
|
58
56
|
}
|
|
59
57
|
})
|
|
58
|
+
.volatile(() => ({
|
|
59
|
+
scrollTop: 0,
|
|
60
|
+
}))
|
|
61
|
+
.views((self) => ({
|
|
62
|
+
get lgv() {
|
|
63
|
+
return getContainingView(self) as unknown as LinearGenomeViewModel
|
|
64
|
+
},
|
|
65
|
+
get height() {
|
|
66
|
+
if (self.heightPreConfig) {
|
|
67
|
+
return self.heightPreConfig
|
|
68
|
+
}
|
|
69
|
+
if (self.graphical && self.table) {
|
|
70
|
+
return 500
|
|
71
|
+
}
|
|
72
|
+
if (self.graphical) {
|
|
73
|
+
return 200
|
|
74
|
+
}
|
|
75
|
+
return 300
|
|
76
|
+
},
|
|
77
|
+
}))
|
|
60
78
|
.views((self) => ({
|
|
61
79
|
get rendererTypeName() {
|
|
62
80
|
return self.configuration.renderer.type
|
|
@@ -119,6 +137,73 @@ export function baseModelFactory(
|
|
|
119
137
|
.apolloSelectedFeature
|
|
120
138
|
},
|
|
121
139
|
}))
|
|
140
|
+
.actions((self) => ({
|
|
141
|
+
setScrollTop(scrollTop: number) {
|
|
142
|
+
self.scrollTop = scrollTop
|
|
143
|
+
},
|
|
144
|
+
setHeight(displayHeight: number) {
|
|
145
|
+
self.heightPreConfig = Math.max(displayHeight, minDisplayHeight)
|
|
146
|
+
return self.height
|
|
147
|
+
},
|
|
148
|
+
resizeHeight(distance: number) {
|
|
149
|
+
const oldHeight = self.height
|
|
150
|
+
const newHeight = this.setHeight(self.height + distance)
|
|
151
|
+
return newHeight - oldHeight
|
|
152
|
+
},
|
|
153
|
+
showGraphicalOnly() {
|
|
154
|
+
self.graphical = true
|
|
155
|
+
self.table = false
|
|
156
|
+
},
|
|
157
|
+
showTableOnly() {
|
|
158
|
+
self.graphical = false
|
|
159
|
+
self.table = true
|
|
160
|
+
},
|
|
161
|
+
showGraphicalAndTable() {
|
|
162
|
+
self.graphical = true
|
|
163
|
+
self.table = true
|
|
164
|
+
},
|
|
165
|
+
}))
|
|
166
|
+
.views((self) => {
|
|
167
|
+
const { trackMenuItems: superTrackMenuItems } = self
|
|
168
|
+
return {
|
|
169
|
+
trackMenuItems() {
|
|
170
|
+
const { graphical, table } = self
|
|
171
|
+
return [
|
|
172
|
+
...superTrackMenuItems(),
|
|
173
|
+
{
|
|
174
|
+
type: 'subMenu',
|
|
175
|
+
label: 'Appearance',
|
|
176
|
+
subMenu: [
|
|
177
|
+
{
|
|
178
|
+
label: 'Show graphical display',
|
|
179
|
+
type: 'radio',
|
|
180
|
+
checked: graphical && !table,
|
|
181
|
+
onClick: () => {
|
|
182
|
+
self.showGraphicalOnly()
|
|
183
|
+
},
|
|
184
|
+
},
|
|
185
|
+
{
|
|
186
|
+
label: 'Show table display',
|
|
187
|
+
type: 'radio',
|
|
188
|
+
checked: table && !graphical,
|
|
189
|
+
onClick: () => {
|
|
190
|
+
self.showTableOnly()
|
|
191
|
+
},
|
|
192
|
+
},
|
|
193
|
+
{
|
|
194
|
+
label: 'Show both graphical and table display',
|
|
195
|
+
type: 'radio',
|
|
196
|
+
checked: table && graphical,
|
|
197
|
+
onClick: () => {
|
|
198
|
+
self.showGraphicalAndTable()
|
|
199
|
+
},
|
|
200
|
+
},
|
|
201
|
+
],
|
|
202
|
+
},
|
|
203
|
+
]
|
|
204
|
+
},
|
|
205
|
+
}
|
|
206
|
+
})
|
|
122
207
|
.actions((self) => ({
|
|
123
208
|
setSelectedFeature(feature?: AnnotationFeature) {
|
|
124
209
|
;(
|
|
@@ -136,9 +221,11 @@ export function baseModelFactory(
|
|
|
136
221
|
void (
|
|
137
222
|
self.session as unknown as ApolloSessionModel
|
|
138
223
|
).apolloDataStore.loadFeatures(self.regions)
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
224
|
+
if (self.lgv.bpPerPx <= 3) {
|
|
225
|
+
void (
|
|
226
|
+
self.session as unknown as ApolloSessionModel
|
|
227
|
+
).apolloDataStore.loadRefSeq(self.regions)
|
|
228
|
+
}
|
|
142
229
|
},
|
|
143
230
|
{ name: 'LinearApolloDisplayLoadFeatures', delay: 1000 },
|
|
144
231
|
),
|
|
@@ -19,6 +19,6 @@ export function stateModelFactory(
|
|
|
19
19
|
export type LinearApolloDisplayStateModel = ReturnType<typeof stateModelFactory>
|
|
20
20
|
// eslint disable because of
|
|
21
21
|
// https://mobx-state-tree.js.org/tips/typescript#using-a-mst-type-at-design-time
|
|
22
|
-
// eslint-disable-next-line @typescript-eslint/no-empty-
|
|
22
|
+
// eslint-disable-next-line @typescript-eslint/no-empty-object-type
|
|
23
23
|
export interface LinearApolloDisplay
|
|
24
24
|
extends Instance<LinearApolloDisplayStateModel> {}
|
|
@@ -499,6 +499,6 @@ export type LinearApolloDisplayMouseEventsModel = ReturnType<
|
|
|
499
499
|
>
|
|
500
500
|
// eslint disable because of
|
|
501
501
|
// https://mobx-state-tree.js.org/tips/typescript#using-a-mst-type-at-design-time
|
|
502
|
-
// eslint-disable-next-line @typescript-eslint/no-empty-
|
|
502
|
+
// eslint-disable-next-line @typescript-eslint/no-empty-object-type
|
|
503
503
|
export interface LinearApolloDisplayMouseEvents
|
|
504
504
|
extends Instance<LinearApolloDisplayMouseEventsModel> {}
|
|
@@ -445,6 +445,6 @@ export type LinearApolloDisplayRenderingModel = ReturnType<
|
|
|
445
445
|
>
|
|
446
446
|
// eslint disable because of
|
|
447
447
|
// https://mobx-state-tree.js.org/tips/typescript#using-a-mst-type-at-design-time
|
|
448
|
-
// eslint-disable-next-line @typescript-eslint/no-empty-
|
|
448
|
+
// eslint-disable-next-line @typescript-eslint/no-empty-object-type
|
|
449
449
|
export interface LinearApolloDisplayRendering
|
|
450
450
|
extends Instance<LinearApolloDisplayRenderingModel> {}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
/* eslint-disable @typescript-eslint/no-unsafe-return */
|
|
3
3
|
// jsonpath triggers this rule for some reason. import { query } from 'jsonpath' does not work
|
|
4
4
|
|
|
5
|
-
import { checkAbortSignal } from '@jbrowse/core/util'
|
|
5
|
+
import { checkAbortSignal } from '@jbrowse/core/util/aborting'
|
|
6
6
|
import jsonpath from 'jsonpath'
|
|
7
7
|
|
|
8
8
|
import { stopwords } from './fulltext-stopwords'
|
|
@@ -170,7 +170,10 @@ export function elaborateMatch(
|
|
|
170
170
|
const sortedWordIndexes = [...queryWordIndexes].sort()
|
|
171
171
|
const matchedQueryWords = sortedWordIndexes.map((i) => queryWords[i])
|
|
172
172
|
const queryWordRegexps = matchedQueryWords.map((queryWord) => {
|
|
173
|
-
const escaped = queryWord.replaceAll(
|
|
173
|
+
const escaped = queryWord.replaceAll(
|
|
174
|
+
/[$()*+./?[\\\]^{|}-]/g,
|
|
175
|
+
String.raw`\$&`,
|
|
176
|
+
)
|
|
174
177
|
return new RegExp(`\\b${escaped}`, 'gi')
|
|
175
178
|
})
|
|
176
179
|
// const needle = matchedQueryWords.join(' ')
|
|
@@ -5,9 +5,15 @@ import {
|
|
|
5
5
|
BlobLocation,
|
|
6
6
|
LocalPathLocation,
|
|
7
7
|
UriLocation,
|
|
8
|
+
isLocalPathLocation,
|
|
8
9
|
isUriLocation,
|
|
9
10
|
} from '@jbrowse/core/util'
|
|
10
|
-
import {
|
|
11
|
+
import {
|
|
12
|
+
deleteDB,
|
|
13
|
+
IDBPTransaction,
|
|
14
|
+
IndexNames,
|
|
15
|
+
StoreNames,
|
|
16
|
+
} from 'idb/with-async-ittr'
|
|
11
17
|
|
|
12
18
|
import { textSearch } from './fulltext'
|
|
13
19
|
import { OntologyDB, OntologyDBEdge, isDeprecated } from './indexeddb-schema'
|
|
@@ -38,15 +44,6 @@ export type Transaction<
|
|
|
38
44
|
/** the format of the loading data source */
|
|
39
45
|
type SourceType = 'obo-graph-json' | 'obo' | 'owl'
|
|
40
46
|
|
|
41
|
-
/**
|
|
42
|
-
* @deprecated use the one from jbrowse core when it is published
|
|
43
|
-
**/
|
|
44
|
-
function isLocalPathLocation(location: unknown): location is LocalPathLocation {
|
|
45
|
-
return (
|
|
46
|
-
typeof location === 'object' && location !== null && 'localPath' in location
|
|
47
|
-
)
|
|
48
|
-
}
|
|
49
|
-
|
|
50
47
|
async function arrayFromAsync<T>(iter: AsyncIterable<T>) {
|
|
51
48
|
const a = []
|
|
52
49
|
for await (const i of iter) {
|
|
@@ -176,18 +173,24 @@ export default class OntologyStore {
|
|
|
176
173
|
return db
|
|
177
174
|
}
|
|
178
175
|
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
176
|
+
try {
|
|
177
|
+
const { sourceLocation, sourceType } = this
|
|
178
|
+
if (sourceType === 'obo-graph-json') {
|
|
179
|
+
await this.loadOboGraphJson(db)
|
|
180
|
+
} else {
|
|
181
|
+
throw new Error(
|
|
182
|
+
`ontology source file ${JSON.stringify(
|
|
183
|
+
sourceLocation,
|
|
184
|
+
)} has type ${sourceType}, which is not yet supported`,
|
|
185
|
+
)
|
|
186
|
+
}
|
|
189
187
|
|
|
190
|
-
|
|
188
|
+
return db
|
|
189
|
+
} catch (error) {
|
|
190
|
+
db.close()
|
|
191
|
+
await deleteDB(this.dbName)
|
|
192
|
+
throw error
|
|
193
|
+
}
|
|
191
194
|
}
|
|
192
195
|
|
|
193
196
|
async termCount(tx?: Transaction<['nodes']>) {
|
|
@@ -497,7 +500,7 @@ export default class OntologyStore {
|
|
|
497
500
|
|
|
498
501
|
// fetch the full nodes and filter out deprecated ones
|
|
499
502
|
const terms: OntologyClass[] = []
|
|
500
|
-
for
|
|
503
|
+
for (const termId of termIds) {
|
|
501
504
|
const node = await myTx.objectStore('nodes').get(termId)
|
|
502
505
|
if (node && isOntologyClass(node) && !isDeprecated(node)) {
|
|
503
506
|
terms.push(node)
|
|
@@ -84,9 +84,14 @@ export async function loadOboGraphJson(this: OntologyStore, db: Database) {
|
|
|
84
84
|
// TODO: using file streaming along with an event-based json parser
|
|
85
85
|
// instead of JSON.parse and .readFile could probably make this faster
|
|
86
86
|
// and less memory intensive
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
87
|
+
let oboGraph: GraphDocument
|
|
88
|
+
try {
|
|
89
|
+
oboGraph = JSON.parse(
|
|
90
|
+
await openLocation(this.sourceLocation).readFile('utf8'),
|
|
91
|
+
) as GraphDocument
|
|
92
|
+
} catch {
|
|
93
|
+
throw new Error('Error in loading ontology')
|
|
94
|
+
}
|
|
90
95
|
|
|
91
96
|
const parseTime = Date.now()
|
|
92
97
|
|
|
@@ -1,15 +1,26 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
AnyConfigurationModel,
|
|
3
|
+
ConfigurationSchema,
|
|
4
|
+
readConfObject,
|
|
5
|
+
} from '@jbrowse/core/configuration'
|
|
2
6
|
import {
|
|
3
7
|
BlobLocation,
|
|
4
8
|
LocalPathLocation,
|
|
5
9
|
UriLocation,
|
|
6
10
|
} from '@jbrowse/core/util/types/mst'
|
|
7
11
|
import { autorun } from 'mobx'
|
|
8
|
-
import {
|
|
9
|
-
|
|
12
|
+
import {
|
|
13
|
+
Instance,
|
|
14
|
+
addDisposer,
|
|
15
|
+
getRoot,
|
|
16
|
+
getSnapshot,
|
|
17
|
+
types,
|
|
18
|
+
} from 'mobx-state-tree'
|
|
10
19
|
import OntologyStore, { OntologyStoreOptions } from './OntologyStore'
|
|
11
20
|
import { OntologyDBNode } from './OntologyStore/indexeddb-schema'
|
|
12
21
|
import { applyPrefixes, expandPrefixes } from './OntologyStore/prefixes'
|
|
22
|
+
import ApolloPluginConfigurationSchema from '../config'
|
|
23
|
+
import { ApolloRootModel } from '../types'
|
|
13
24
|
|
|
14
25
|
export { isDeprecated } from './OntologyStore/indexeddb-schema'
|
|
15
26
|
|
|
@@ -55,15 +66,27 @@ export const OntologyManagerType = types
|
|
|
55
66
|
'SO:': 'http://purl.obolibrary.org/obo/SO_',
|
|
56
67
|
}),
|
|
57
68
|
})
|
|
69
|
+
.views((self) => ({
|
|
70
|
+
get featureTypeOntologyName(): string {
|
|
71
|
+
const jbConfig = getRoot<ApolloRootModel>(self).jbrowse
|
|
72
|
+
.configuration as AnyConfigurationModel
|
|
73
|
+
const pluginConfiguration = jbConfig.ApolloPlugin as Instance<
|
|
74
|
+
typeof ApolloPluginConfigurationSchema
|
|
75
|
+
>
|
|
76
|
+
const featureTypeOntologyName = readConfObject(
|
|
77
|
+
pluginConfiguration,
|
|
78
|
+
'featureTypeOntologyName',
|
|
79
|
+
) as string
|
|
80
|
+
return featureTypeOntologyName
|
|
81
|
+
},
|
|
82
|
+
}))
|
|
58
83
|
.views((self) => ({
|
|
59
84
|
/**
|
|
60
85
|
* gets the OntologyRecord for the ontology we should be
|
|
61
86
|
* using for feature types (e.g. SO or maybe biotypes)
|
|
62
87
|
**/
|
|
63
88
|
get featureTypeOntology() {
|
|
64
|
-
|
|
65
|
-
// we should be using. currently hardcoded to use SO.
|
|
66
|
-
return this.findOntology('Sequence Ontology')
|
|
89
|
+
return this.findOntology(self.featureTypeOntologyName)
|
|
67
90
|
},
|
|
68
91
|
|
|
69
92
|
findOntology(name: string, version?: string) {
|
|
@@ -157,9 +180,9 @@ export const OntologyRecordConfiguration = ConfigurationSchema(
|
|
|
157
180
|
|
|
158
181
|
// eslint disables because of
|
|
159
182
|
// https://mobx-state-tree.js.org/tips/typescript#using-a-mst-type-at-design-time
|
|
160
|
-
// eslint-disable-next-line @typescript-eslint/no-empty-
|
|
183
|
+
// eslint-disable-next-line @typescript-eslint/no-empty-object-type
|
|
161
184
|
export interface OntologyManager extends Instance<typeof OntologyManagerType> {}
|
|
162
|
-
// eslint-disable-next-line @typescript-eslint/no-empty-
|
|
185
|
+
// eslint-disable-next-line @typescript-eslint/no-empty-object-type
|
|
163
186
|
export interface OntologyRecord extends Instance<typeof OntologyRecordType> {}
|
|
164
187
|
|
|
165
188
|
export type OntologyTerm = OntologyDBNode
|
|
@@ -425,6 +425,6 @@ export type SixFrameFeatureDisplayStateModel = ReturnType<
|
|
|
425
425
|
>
|
|
426
426
|
// eslint disable because of
|
|
427
427
|
// https://mobx-state-tree.js.org/tips/typescript#using-a-mst-type-at-design-time
|
|
428
|
-
// eslint-disable-next-line @typescript-eslint/no-empty-
|
|
428
|
+
// eslint-disable-next-line @typescript-eslint/no-empty-object-type
|
|
429
429
|
export interface SixFrameFeatureDisplay
|
|
430
430
|
extends Instance<SixFrameFeatureDisplayStateModel> {}
|
|
@@ -41,6 +41,6 @@ export const TabularEditorStateModelType = types
|
|
|
41
41
|
|
|
42
42
|
// eslint disable because of
|
|
43
43
|
// https://mobx-state-tree.js.org/tips/typescript#using-a-mst-type-at-design-time
|
|
44
|
-
// eslint-disable-next-line @typescript-eslint/no-empty-
|
|
44
|
+
// eslint-disable-next-line @typescript-eslint/no-empty-object-type
|
|
45
45
|
export interface TabularEditorStateModel
|
|
46
46
|
extends Instance<typeof TabularEditorStateModelType> {}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/unbound-method */
|
|
1
2
|
/* eslint-disable @typescript-eslint/no-unnecessary-condition */
|
|
2
3
|
/* eslint-disable @typescript-eslint/no-misused-promises */
|
|
3
4
|
import { AddFeatureChange } from '@apollo-annotation/shared'
|
|
@@ -101,7 +102,6 @@ export function AddFeature({
|
|
|
101
102
|
break
|
|
102
103
|
}
|
|
103
104
|
default: {
|
|
104
|
-
// eslint-disable-next-line unicorn/no-useless-undefined
|
|
105
105
|
setStrand(undefined)
|
|
106
106
|
}
|
|
107
107
|
}
|