@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.
Files changed (85) hide show
  1. package/dist/index.esm.js +3189 -3575
  2. package/dist/index.esm.js.map +1 -1
  3. package/dist/jbrowse-plugin-apollo.cjs.development.js +3185 -3570
  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 +14884 -15905
  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 +33 -33
  12. package/src/ApolloInternetAccount/addMenuItems.ts +18 -0
  13. package/src/ApolloInternetAccount/components/AuthTypeSelector.tsx +1 -0
  14. package/src/ApolloInternetAccount/configSchema.ts +5 -2
  15. package/src/ApolloInternetAccount/model.ts +14 -5
  16. package/src/ApolloRefNameAliasAdapter/ApolloRefNameAliasAdapter.ts +94 -0
  17. package/src/ApolloRefNameAliasAdapter/configSchema.ts +12 -0
  18. package/src/ApolloRefNameAliasAdapter/index.ts +21 -0
  19. package/src/ApolloSequenceAdapter/ApolloSequenceAdapter.ts +1 -0
  20. package/src/ApolloSixFrameRenderer/components/ApolloRendering.tsx +10 -10
  21. package/src/ApolloTextSearchAdapter/ApolloTextSearchAdapter.ts +35 -32
  22. package/src/BackendDrivers/BackendDriver.ts +8 -0
  23. package/src/BackendDrivers/CollaborationServerDriver.ts +49 -1
  24. package/src/BackendDrivers/DesktopFileDriver.ts +14 -1
  25. package/src/BackendDrivers/InMemoryFileDriver.ts +17 -1
  26. package/src/ChangeManager.ts +1 -1
  27. package/src/FeatureDetailsWidget/ApolloFeatureDetailsWidget.tsx +5 -25
  28. package/src/FeatureDetailsWidget/ApolloTranscriptDetailsWidget.tsx +82 -0
  29. package/src/FeatureDetailsWidget/Attributes.tsx +11 -3
  30. package/src/FeatureDetailsWidget/BasicInformation.tsx +38 -30
  31. package/src/FeatureDetailsWidget/Sequence.tsx +7 -7
  32. package/src/FeatureDetailsWidget/TranscriptBasic.tsx +446 -0
  33. package/src/FeatureDetailsWidget/TranscriptSequence.tsx +365 -0
  34. package/src/FeatureDetailsWidget/index.ts +2 -0
  35. package/src/FeatureDetailsWidget/model.ts +77 -9
  36. package/src/LinearApolloDisplay/components/LinearApolloDisplay.tsx +0 -2
  37. package/src/LinearApolloDisplay/glyphs/BoxGlyph.ts +453 -380
  38. package/src/LinearApolloDisplay/glyphs/GeneGlyph.ts +520 -0
  39. package/src/LinearApolloDisplay/glyphs/GenericChildGlyph.ts +138 -134
  40. package/src/LinearApolloDisplay/glyphs/Glyph.ts +38 -370
  41. package/src/LinearApolloDisplay/glyphs/index.ts +1 -2
  42. package/src/LinearApolloDisplay/stateModel/base.ts +3 -6
  43. package/src/LinearApolloDisplay/stateModel/getGlyph.ts +30 -30
  44. package/src/LinearApolloDisplay/stateModel/index.ts +5 -1
  45. package/src/LinearApolloDisplay/stateModel/layouts.ts +32 -24
  46. package/src/LinearApolloDisplay/stateModel/mouseEvents.ts +206 -217
  47. package/src/LinearApolloDisplay/stateModel/rendering.ts +43 -67
  48. package/src/OntologyManager/OntologyStore/fulltext.ts +1 -1
  49. package/src/OntologyManager/OntologyStore/index.ts +2 -1
  50. package/src/OntologyManager/index.ts +6 -2
  51. package/src/OntologyManager/util.ts +2 -2
  52. package/src/SixFrameFeatureDisplay/stateModel.ts +15 -10
  53. package/src/TabularEditor/HybridGrid/ChangeHandling.ts +21 -46
  54. package/src/TabularEditor/HybridGrid/Feature.tsx +31 -82
  55. package/src/TabularEditor/HybridGrid/FeatureAttributes.tsx +3 -2
  56. package/src/TabularEditor/HybridGrid/HybridGrid.tsx +2 -3
  57. package/src/TabularEditor/HybridGrid/NumberCell.tsx +1 -0
  58. package/src/TabularEditor/HybridGrid/featureContextMenuItems.ts +46 -5
  59. package/src/TabularEditor/model.ts +5 -3
  60. package/src/components/AddAssembly.tsx +15 -9
  61. package/src/components/AddChildFeature.tsx +7 -73
  62. package/src/components/AddFeature.tsx +2 -57
  63. package/src/components/AddRefSeqAliases.tsx +285 -0
  64. package/src/components/CopyFeature.tsx +16 -33
  65. package/src/components/DeleteFeature.tsx +4 -6
  66. package/src/components/ImportFeatures.tsx +6 -3
  67. package/src/components/LogOut.tsx +105 -0
  68. package/src/components/ManageChecks.tsx +1 -0
  69. package/src/components/ManageUsers.tsx +21 -1
  70. package/src/components/ModifyFeatureAttribute.tsx +2 -2
  71. package/src/components/OntologyTermAutocomplete.tsx +0 -2
  72. package/src/components/OntologyTermMultiSelect.tsx +1 -0
  73. package/src/components/OpenLocalFile.tsx +6 -5
  74. package/src/components/ViewChangeLog.tsx +1 -0
  75. package/src/components/ViewCheckResults.tsx +1 -0
  76. package/src/components/index.ts +4 -0
  77. package/src/extensions/annotationFromPileup.ts +10 -16
  78. package/src/index.ts +57 -3
  79. package/src/session/ClientDataStore.ts +49 -46
  80. package/src/session/session.ts +186 -114
  81. package/src/util/loadAssemblyIntoClient.ts +4 -210
  82. package/src/FeatureDetailsWidget/RelatedFeature.tsx +0 -97
  83. package/src/LinearApolloDisplay/glyphs/CanonicalGeneGlyph.ts +0 -1204
  84. package/src/LinearApolloDisplay/glyphs/ImplicitExonGeneGlyph.ts +0 -716
  85. 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.18",
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
- "keywords": [
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
- "jbrowse-plugin": {
51
- "name": "Apollo"
43
+ "config": {
44
+ "jbrowse": {
45
+ "plugin": {
46
+ "name": "Apollo"
47
+ }
48
+ }
52
49
  },
53
50
  "dependencies": {
54
- "@apollo-annotation/common": "^0.1.18",
55
- "@apollo-annotation/mst": "^0.1.18",
56
- "@apollo-annotation/shared": "^0.1.18",
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.7.0",
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": "^17.0.34",
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.1.6"
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) => {
@@ -1,3 +1,4 @@
1
+ /* eslint-disable @typescript-eslint/use-unknown-in-catch-callback-variable */
1
2
  import { isAbortException } from '@jbrowse/core/util'
2
3
  import {
3
4
  Button,
@@ -21,6 +21,9 @@ const ApolloConfigSchema = ConfigurationSchema(
21
21
 
22
22
  export type ApolloInternetAccountConfigModel = typeof ApolloConfigSchema
23
23
 
24
- export type ApolloInternetAccountConfig =
25
- Instance<ApolloInternetAccountConfigModel>
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 { ApolloSessionModel, Collaborator } from '../session'
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
- export type ApolloInternetAccountModel =
458
- Instance<ApolloInternetAccountStateModel>
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,12 @@
1
+ import { ConfigurationSchema } from '@jbrowse/core/configuration'
2
+
3
+ export default ConfigurationSchema(
4
+ 'ApolloRefNameAliasAdapter',
5
+ {
6
+ assemblyId: {
7
+ type: 'string',
8
+ defaultValue: '',
9
+ },
10
+ },
11
+ { explicitlyTyped: true },
12
+ )
@@ -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
+ }
@@ -1,3 +1,4 @@
1
+ /* eslint-disable @typescript-eslint/prefer-promise-reject-errors */
1
2
  /* eslint-disable @typescript-eslint/no-unsafe-assignment */
2
3
  /* eslint-disable @typescript-eslint/no-unsafe-argument */
3
4
  /* eslint-disable @typescript-eslint/no-unsafe-member-access */
@@ -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 { AnnotationFeatureI } from '@apollo-annotation/mst'
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<AnnotationFeatureI>()
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: AnnotationFeatureI
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.end
191
- : feature.start - region.start - 1
192
- const end = feature.end - region.start - 1
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: AnnotationFeatureI | undefined = feat
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 AnnotationFeatureI
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.end
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.start
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
- /* eslint-disable @typescript-eslint/no-unsafe-return */
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
- refSeq: any // eslint-disable-line @typescript-eslint/no-explicit-any
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
- new BaseResult({
41
- label: query,
42
- trackId: this.trackId,
43
- locString: `${feature.refSeq?.name}:${feature.start + 1}..${
44
- feature.end
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 results = []
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
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
54
- const session = this.pluginManager?.rootModel?.session as any
55
- const backendDriver =
56
- session?.apolloDataStore.getBackendDriver(assemblyName)
57
- const r = await backendDriver.searchFeatures(args.queryString, [
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(...r)
64
+ results.push(...this.mapBaseResult(features, assembly, query))
61
65
  }
62
66
 
63
- const query = args.queryString
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) {