@apollo-annotation/jbrowse-plugin-apollo 0.1.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.
Files changed (116) hide show
  1. package/README.md +76 -0
  2. package/dist/index.esm.js +10248 -0
  3. package/dist/index.esm.js.map +1 -0
  4. package/dist/index.js +7 -0
  5. package/dist/jbrowse-plugin-apollo.cjs.development.js +10298 -0
  6. package/dist/jbrowse-plugin-apollo.cjs.development.js.map +1 -0
  7. package/dist/jbrowse-plugin-apollo.cjs.production.min.js +2 -0
  8. package/dist/jbrowse-plugin-apollo.cjs.production.min.js.map +1 -0
  9. package/dist/jbrowse-plugin-apollo.umd.development.js +46957 -0
  10. package/dist/jbrowse-plugin-apollo.umd.development.js.map +1 -0
  11. package/dist/jbrowse-plugin-apollo.umd.production.min.js +2 -0
  12. package/dist/jbrowse-plugin-apollo.umd.production.min.js.map +1 -0
  13. package/package.json +130 -0
  14. package/src/ApolloInternetAccount/addMenuItems.ts +94 -0
  15. package/src/ApolloInternetAccount/components/AuthTypeSelector.tsx +121 -0
  16. package/src/ApolloInternetAccount/components/LoginButtons.tsx +62 -0
  17. package/src/ApolloInternetAccount/components/LoginIcons.tsx +74 -0
  18. package/src/ApolloInternetAccount/configSchema.ts +26 -0
  19. package/src/ApolloInternetAccount/index.ts +2 -0
  20. package/src/ApolloInternetAccount/model.ts +448 -0
  21. package/src/ApolloJobModel.ts +117 -0
  22. package/src/ApolloSequenceAdapter/ApolloSequenceAdapter.ts +186 -0
  23. package/src/ApolloSequenceAdapter/configSchema.ts +12 -0
  24. package/src/ApolloSequenceAdapter/index.ts +21 -0
  25. package/src/ApolloSixFrameRenderer/ApolloSixFrameRenderer.tsx +12 -0
  26. package/src/ApolloSixFrameRenderer/components/ApolloRendering.tsx +692 -0
  27. package/src/ApolloSixFrameRenderer/configSchema.ts +7 -0
  28. package/src/ApolloSixFrameRenderer/index.ts +3 -0
  29. package/src/ApolloTextSearchAdapter/ApolloTextSearchAdapter.ts +64 -0
  30. package/src/ApolloTextSearchAdapter/configSchema.ts +24 -0
  31. package/src/ApolloTextSearchAdapter/index.ts +18 -0
  32. package/src/BackendDrivers/BackendDriver.ts +31 -0
  33. package/src/BackendDrivers/CollaborationServerDriver.ts +318 -0
  34. package/src/BackendDrivers/DesktopFileDriver.ts +170 -0
  35. package/src/BackendDrivers/InMemoryFileDriver.ts +76 -0
  36. package/src/BackendDrivers/index.ts +4 -0
  37. package/src/ChangeManager.ts +148 -0
  38. package/src/LinearApolloDisplay/components/LinearApolloDisplay.tsx +248 -0
  39. package/src/LinearApolloDisplay/components/index.ts +1 -0
  40. package/src/LinearApolloDisplay/configSchema.ts +16 -0
  41. package/src/LinearApolloDisplay/glyphs/BoxGlyph.ts +422 -0
  42. package/src/LinearApolloDisplay/glyphs/CanonicalGeneGlyph.ts +1191 -0
  43. package/src/LinearApolloDisplay/glyphs/GenericChildGlyph.ts +151 -0
  44. package/src/LinearApolloDisplay/glyphs/Glyph.ts +382 -0
  45. package/src/LinearApolloDisplay/glyphs/ImplicitExonGeneGlyph.ts +697 -0
  46. package/src/LinearApolloDisplay/glyphs/index.ts +4 -0
  47. package/src/LinearApolloDisplay/index.ts +2 -0
  48. package/src/LinearApolloDisplay/stateModel/base.ts +146 -0
  49. package/src/LinearApolloDisplay/stateModel/getGlyph.ts +39 -0
  50. package/src/LinearApolloDisplay/stateModel/glyphs.ts +45 -0
  51. package/src/LinearApolloDisplay/stateModel/index.ts +20 -0
  52. package/src/LinearApolloDisplay/stateModel/layouts.ts +230 -0
  53. package/src/LinearApolloDisplay/stateModel/mouseEvents.ts +513 -0
  54. package/src/LinearApolloDisplay/stateModel/rendering.ts +441 -0
  55. package/src/LinearApolloDisplay/stateModel/trackHeightMixin.ts +43 -0
  56. package/src/LinearApolloDisplay/types.ts +1 -0
  57. package/src/OntologyManager/OntologyStore/__snapshots__/fulltext.test.ts.snap +208 -0
  58. package/src/OntologyManager/OntologyStore/__snapshots__/index.test.ts.snap +18846 -0
  59. package/src/OntologyManager/OntologyStore/fulltext-stopwords.ts +137 -0
  60. package/src/OntologyManager/OntologyStore/fulltext.test.ts +94 -0
  61. package/src/OntologyManager/OntologyStore/fulltext.ts +264 -0
  62. package/src/OntologyManager/OntologyStore/index.test.ts +130 -0
  63. package/src/OntologyManager/OntologyStore/index.ts +526 -0
  64. package/src/OntologyManager/OntologyStore/indexeddb-schema.ts +89 -0
  65. package/src/OntologyManager/OntologyStore/indexeddb-storage.ts +180 -0
  66. package/src/OntologyManager/OntologyStore/obo-graph-json-schema.ts +110 -0
  67. package/src/OntologyManager/OntologyStore/prefixes.ts +35 -0
  68. package/src/OntologyManager/index.ts +173 -0
  69. package/src/SixFrameFeatureDisplay/components/TrackLines.tsx +19 -0
  70. package/src/SixFrameFeatureDisplay/components/index.ts +1 -0
  71. package/src/SixFrameFeatureDisplay/configSchema.ts +21 -0
  72. package/src/SixFrameFeatureDisplay/index.ts +2 -0
  73. package/src/SixFrameFeatureDisplay/stateModel.ts +413 -0
  74. package/src/TabularEditor/HybridGrid/ChangeHandling.ts +88 -0
  75. package/src/TabularEditor/HybridGrid/Feature.tsx +346 -0
  76. package/src/TabularEditor/HybridGrid/FeatureAttributes.tsx +34 -0
  77. package/src/TabularEditor/HybridGrid/Highlight.tsx +40 -0
  78. package/src/TabularEditor/HybridGrid/HybridGrid.tsx +138 -0
  79. package/src/TabularEditor/HybridGrid/NumberCell.tsx +77 -0
  80. package/src/TabularEditor/HybridGrid/ToolBar.tsx +59 -0
  81. package/src/TabularEditor/HybridGrid/featureContextMenuItems.ts +119 -0
  82. package/src/TabularEditor/HybridGrid/index.ts +1 -0
  83. package/src/TabularEditor/TabularEditorPane.tsx +34 -0
  84. package/src/TabularEditor/index.ts +3 -0
  85. package/src/TabularEditor/model.ts +44 -0
  86. package/src/TabularEditor/types.ts +3 -0
  87. package/src/components/AddAssembly.tsx +464 -0
  88. package/src/components/AddChildFeature.tsx +247 -0
  89. package/src/components/AddFeature.tsx +252 -0
  90. package/src/components/CopyFeature.tsx +328 -0
  91. package/src/components/DeleteAssembly.tsx +185 -0
  92. package/src/components/DeleteFeature.tsx +90 -0
  93. package/src/components/Dialog.tsx +47 -0
  94. package/src/components/DownloadGFF3.tsx +213 -0
  95. package/src/components/ImportFeatures.tsx +295 -0
  96. package/src/components/ManageChecks.tsx +280 -0
  97. package/src/components/ManageUsers.tsx +218 -0
  98. package/src/components/ModifyFeatureAttribute.tsx +457 -0
  99. package/src/components/OntologyTermAutocomplete.tsx +240 -0
  100. package/src/components/OntologyTermMultiSelect.tsx +349 -0
  101. package/src/components/OpenLocalFile.tsx +178 -0
  102. package/src/components/ViewChangeLog.tsx +208 -0
  103. package/src/components/ViewCheckResults.tsx +151 -0
  104. package/src/components/index.ts +12 -0
  105. package/src/config.ts +10 -0
  106. package/src/declare.d.ts +3 -0
  107. package/src/extensions/annotationFromPileup.ts +208 -0
  108. package/src/extensions/index.ts +1 -0
  109. package/src/index.ts +394 -0
  110. package/src/makeDisplayComponent.tsx +244 -0
  111. package/src/session/ClientDataStore.ts +282 -0
  112. package/src/session/index.ts +1 -0
  113. package/src/session/session.ts +373 -0
  114. package/src/types.ts +10 -0
  115. package/src/util/index.ts +31 -0
  116. package/src/util/loadAssemblyIntoClient.ts +291 -0
@@ -0,0 +1,413 @@
1
+ import { ConfigurationReference } from '@jbrowse/core/configuration'
2
+ import { AnyConfigurationSchemaType } from '@jbrowse/core/configuration/configurationSchema'
3
+ import PluginManager from '@jbrowse/core/PluginManager'
4
+ import {
5
+ defaultStarts,
6
+ defaultStops,
7
+ getContainingView,
8
+ getSession,
9
+ revcom,
10
+ reverse,
11
+ } from '@jbrowse/core/util'
12
+ import { BaseBlock } from '@jbrowse/core/util/blockTypes'
13
+ import { getParentRenderProps } from '@jbrowse/core/util/tracks'
14
+ import type LinearGenomeViewPlugin from '@jbrowse/plugin-linear-genome-view'
15
+ import type { LinearGenomeViewModel } from '@jbrowse/plugin-linear-genome-view'
16
+ import { AnnotationFeatureI } from 'apollo-mst'
17
+ import { autorun } from 'mobx'
18
+ import { Instance, addDisposer, types } from 'mobx-state-tree'
19
+
20
+ import { ApolloSession, ApolloSessionModel } from '../session'
21
+
22
+ const forwardPhaseMap: Record<number, number> = { 0: 2, 1: 1, 2: 0 }
23
+ const reversePhaseMap: Record<number, number> = { 3: 0, 4: 1, 5: 2 }
24
+
25
+ export function stateModelFactory(
26
+ pluginManager: PluginManager,
27
+ configSchema: AnyConfigurationSchemaType,
28
+ ) {
29
+ const LGVPlugin = pluginManager.getPlugin(
30
+ 'LinearGenomeViewPlugin',
31
+ ) as LinearGenomeViewPlugin
32
+ const { BaseLinearDisplay } = LGVPlugin.exports
33
+
34
+ return BaseLinearDisplay.named('SixFrameFeatureDisplay')
35
+ .props({
36
+ type: types.literal('SixFrameFeatureDisplay'),
37
+ configuration: ConfigurationReference(configSchema),
38
+ apolloRowHeight: 20,
39
+ detailsMinHeight: 200,
40
+ showStartCodons: false,
41
+ showStopCodons: true,
42
+ showIntronLines: true,
43
+ })
44
+ .volatile(() => ({
45
+ apolloFeatureUnderMouse: undefined as AnnotationFeatureI | undefined,
46
+ apolloRowUnderMouse: undefined as number | undefined,
47
+ }))
48
+ .views((self) => {
49
+ const { configuration, renderProps: superRenderProps } = self
50
+ return {
51
+ renderProps() {
52
+ return {
53
+ ...superRenderProps(),
54
+ ...getParentRenderProps(self),
55
+ config: configuration.renderer,
56
+ }
57
+ },
58
+ }
59
+ })
60
+ .views((self) => ({
61
+ get regions() {
62
+ let blockDefinitions
63
+ try {
64
+ ;({ blockDefinitions } = self)
65
+ } catch {
66
+ return []
67
+ }
68
+ const regions = blockDefinitions.contentBlocks.map(
69
+ ({ assemblyName, end, refName, start }) => ({
70
+ assemblyName,
71
+ refName,
72
+ start,
73
+ end,
74
+ }),
75
+ )
76
+ return regions
77
+ },
78
+ regionCannotBeRendered(/* region */) {
79
+ const view = getContainingView(self) as unknown as LinearGenomeViewModel
80
+ if (view && view.bpPerPx >= 200) {
81
+ return 'Zoom in to see annotations'
82
+ }
83
+ return
84
+ },
85
+ get session() {
86
+ return getSession(self) as unknown as ApolloSessionModel
87
+ },
88
+ }))
89
+ .actions((self) => {
90
+ let previousBlockKeys: string[] = []
91
+ return {
92
+ afterAttach() {
93
+ addDisposer(
94
+ self,
95
+ autorun(
96
+ () => {
97
+ const session = getSession(self) as ApolloSession
98
+ const view = getContainingView(
99
+ self,
100
+ ) as unknown as LinearGenomeViewModel
101
+ if (view.initialized) {
102
+ if (self.regionCannotBeRendered()) {
103
+ return
104
+ }
105
+ const blockKeys: string[] = []
106
+ const newBlocks: BaseBlock[] = []
107
+ for (const block of self.blockDefinitions.contentBlocks) {
108
+ blockKeys.push(block.key)
109
+ if (!previousBlockKeys.includes(block.key)) {
110
+ newBlocks.push(block)
111
+ }
112
+ }
113
+ session.apolloDataStore.loadFeatures(
114
+ newBlocks.map(({ assemblyName, end, refName, start }) => ({
115
+ assemblyName,
116
+ refName,
117
+ start,
118
+ end,
119
+ })),
120
+ )
121
+ session.apolloDataStore.loadRefSeq(
122
+ newBlocks.map(({ assemblyName, end, refName, start }) => ({
123
+ assemblyName,
124
+ refName,
125
+ start,
126
+ end,
127
+ })),
128
+ )
129
+ previousBlockKeys = blockKeys
130
+ }
131
+ },
132
+ { name: 'SixFrameFeatureDisplay' },
133
+ ),
134
+ )
135
+ },
136
+ }
137
+ })
138
+ .views((self) => ({
139
+ get rendererTypeName() {
140
+ return self.configuration.renderer.type
141
+ },
142
+ get changeManager() {
143
+ const session = getSession(self) as ApolloSession
144
+ return session.apolloDataStore?.changeManager
145
+ },
146
+ get sequence() {
147
+ const { regions } = self
148
+ const session = getSession(self) as ApolloSession
149
+ const seq = new Map<number, string>()
150
+ for (const region of regions) {
151
+ const assembly = session.apolloDataStore.assemblies.get(
152
+ region.assemblyName,
153
+ )
154
+ const ref = assembly?.getByRefName(region.refName)
155
+ const refSeq: string | undefined = ref?.getSequence(
156
+ region.start,
157
+ region.end,
158
+ )
159
+ seq.set(region.start, refSeq ?? '')
160
+ }
161
+ return seq
162
+ },
163
+ get features() {
164
+ const { regions } = self
165
+ const session = getSession(self) as ApolloSession
166
+ const features = new Map<string, Map<string, AnnotationFeatureI>>()
167
+ for (const region of regions) {
168
+ const assembly = session.apolloDataStore.assemblies.get(
169
+ region.assemblyName,
170
+ )
171
+ const ref = assembly?.getByRefName(region.refName)
172
+ let filteredRef = features.get(region.refName)
173
+ if (!filteredRef) {
174
+ filteredRef = new Map<string, AnnotationFeatureI>()
175
+ features.set(region.refName, filteredRef)
176
+ }
177
+ for (const [featureId, feature] of ref?.features.entries() ??
178
+ new Map()) {
179
+ if (region.start < feature.end && region.end > feature.start) {
180
+ filteredRef.set(featureId, feature)
181
+ }
182
+ }
183
+ }
184
+ return features
185
+ },
186
+ get featuresMinMax() {
187
+ const minMax: Record<string, [number, number]> = {}
188
+ for (const [refSeq, featuresForRefSeq] of this.features || []) {
189
+ let min: number | undefined
190
+ let max: number | undefined
191
+ for (const [, featureLocation] of featuresForRefSeq) {
192
+ if (min === undefined) {
193
+ ;({ min } = featureLocation)
194
+ }
195
+ if (max === undefined) {
196
+ ;({ max } = featureLocation)
197
+ }
198
+ if (featureLocation.min < min) {
199
+ ;({ min } = featureLocation)
200
+ }
201
+ if (featureLocation.end > max) {
202
+ ;({ max } = featureLocation)
203
+ }
204
+ }
205
+ if (min !== undefined && max !== undefined) {
206
+ minMax[refSeq] = [min, max]
207
+ }
208
+ }
209
+ return minMax
210
+ },
211
+ get codonLayout() {
212
+ const codonLayout = new Map<
213
+ number,
214
+ { starts: number[]; stops: number[] }
215
+ >()
216
+ let fullSeq = ''
217
+ let fullStart = 0
218
+ for (const [regionStart, seq] of this.sequence || []) {
219
+ if (!seq) {
220
+ continue
221
+ }
222
+ if (!fullSeq) {
223
+ fullStart = regionStart
224
+ }
225
+ fullSeq += seq
226
+ }
227
+ const rowCount = 6
228
+ for (let i = 0; i < rowCount; i++) {
229
+ const starts: number[] = []
230
+ const stops: number[] = []
231
+ const reversed = i in reversePhaseMap
232
+ // the tilt variable normalizes the frame to where we are starting from,
233
+ // which increases consistency across blocks
234
+ let tilt
235
+ // the effectiveFrame incorporates tilt and the frame to say what the
236
+ // effective frame that is plotted. The +3 is for when frame is -2 and this
237
+ // can otherwise result in effectiveFrame -1
238
+ let effectiveFrame
239
+ let seqSliced
240
+ if (reversed) {
241
+ tilt = (fullSeq.length + fullStart) % 3
242
+ effectiveFrame = (reversePhaseMap[i] + tilt + 3) % 3
243
+ seqSliced = reverse(fullSeq).slice(effectiveFrame)
244
+ } else {
245
+ tilt = 3 - (fullStart % 3)
246
+ effectiveFrame = (forwardPhaseMap[i] + tilt + 3) % 3
247
+ seqSliced = fullSeq.slice(effectiveFrame)
248
+ }
249
+ for (let j = 0; j < seqSliced.length; j += 3) {
250
+ const codon = seqSliced.slice(j, j + 3)
251
+ const normalizedCodon = reversed ? reverse(revcom(codon)) : codon
252
+ const start = reversed
253
+ ? fullStart + seqSliced.length - (3 + j)
254
+ : fullStart + j + effectiveFrame
255
+ if (defaultStarts.includes(normalizedCodon.toUpperCase())) {
256
+ starts.push(start)
257
+ } else if (defaultStops.includes(normalizedCodon.toUpperCase())) {
258
+ stops.push(start)
259
+ }
260
+ }
261
+ codonLayout.set(i, { starts, stops })
262
+ }
263
+ return codonLayout
264
+ },
265
+ get featureLayout() {
266
+ const featureLayout = new Map<number, [string, AnnotationFeatureI][]>()
267
+ for (const [refSeq, featuresForRefSeq] of this.features || []) {
268
+ if (!featuresForRefSeq) {
269
+ continue
270
+ }
271
+ const minMaxfeatures = this.featuresMinMax[refSeq]
272
+ if (!minMaxfeatures) {
273
+ continue
274
+ }
275
+ const [min, max] = minMaxfeatures
276
+ const rows: boolean[][] = []
277
+ const rowCount = 6
278
+ for (let i = 0; i < rowCount; i++) {
279
+ const newRowNumber = rows.length
280
+ rows[newRowNumber] = Array.from({ length: max - min })
281
+ featureLayout.set(newRowNumber, [])
282
+ }
283
+ for (const feature of [...featuresForRefSeq.values()].sort(
284
+ (f1, f2) => {
285
+ const { max: end1, min: start1 } = f1
286
+ const { max: end2, min: start2 } = f2
287
+ return start1 - start2 || end1 - end2
288
+ },
289
+ )) {
290
+ for (const [, childFeature] of feature.children ?? new Map()) {
291
+ if (childFeature.type === 'mRNA') {
292
+ for (const [, grandChildFeature] of childFeature.children ||
293
+ new Map()) {
294
+ let startingRow
295
+ if (grandChildFeature.type === 'CDS') {
296
+ let discontinuousLocations
297
+ if (grandChildFeature.discontinuousLocations.length > 0) {
298
+ ;({ discontinuousLocations } = grandChildFeature)
299
+ } else {
300
+ discontinuousLocations = [grandChildFeature]
301
+ }
302
+ for (const cds of discontinuousLocations) {
303
+ const min = cds.start + 3
304
+ const max = cds.end - 3
305
+ // Remove codons either end of feature when considering intersect.
306
+ for (const [row, { stops }] of this.codonLayout) {
307
+ if (
308
+ (row < 3 && feature.strand === 1) ||
309
+ (row >= 3 && feature.strand === -1)
310
+ ) {
311
+ const filteredArray = stops.filter(
312
+ (value) => value >= min && value <= max,
313
+ )
314
+ if (filteredArray.length === 0) {
315
+ startingRow = row
316
+ const layoutRow = featureLayout.get(startingRow)
317
+ layoutRow?.push([childFeature.featureId, cds])
318
+ break
319
+ }
320
+ }
321
+ }
322
+ }
323
+ }
324
+ }
325
+ }
326
+ }
327
+ }
328
+ }
329
+ return featureLayout
330
+ },
331
+ getAssemblyId(assemblyName: string) {
332
+ const { assemblyManager } = getSession(self)
333
+ const assembly = assemblyManager.get(assemblyName)
334
+ if (!assembly) {
335
+ throw new Error(`Could not find assembly named ${assemblyName}`)
336
+ }
337
+ return assembly.name
338
+ },
339
+ get selectedFeature(): AnnotationFeatureI | undefined {
340
+ const session = getSession(self) as ApolloSession
341
+ return session.apolloSelectedFeature
342
+ },
343
+ get setSelectedFeature() {
344
+ const session = getSession(self) as ApolloSession
345
+ return session.apolloSetSelectedFeature
346
+ },
347
+ }))
348
+ .actions((self) => ({
349
+ setSelectedFeature(feature?: AnnotationFeatureI) {
350
+ const session = getSession(self) as ApolloSession
351
+ return session.apolloSetSelectedFeature(feature)
352
+ },
353
+ setApolloFeatureUnderMouse(feature?: AnnotationFeatureI) {
354
+ self.apolloFeatureUnderMouse = feature
355
+ },
356
+ setApolloRowUnderMouse(row?: number) {
357
+ self.apolloRowUnderMouse = row
358
+ },
359
+ toggleShowStartCodons() {
360
+ self.showStartCodons = !self.showStartCodons
361
+ },
362
+ toggleShowStopCodons() {
363
+ self.showStopCodons = !self.showStopCodons
364
+ },
365
+ toggleShowIntronLines() {
366
+ self.showIntronLines = !self.showIntronLines
367
+ },
368
+ }))
369
+ .views((self) => ({
370
+ get highestRow() {
371
+ if (self.featureLayout.size === 0) {
372
+ return 0
373
+ }
374
+ return Math.max(...self.featureLayout.keys())
375
+ },
376
+ get featuresHeight() {
377
+ return (this.highestRow + 1) * self.apolloRowHeight
378
+ },
379
+ get detailsHeight() {
380
+ return Math.max(
381
+ self.detailsMinHeight,
382
+ self.height - this.featuresHeight,
383
+ )
384
+ },
385
+ trackMenuItems() {
386
+ return [
387
+ {
388
+ label: 'Show start codons',
389
+ type: 'checkbox',
390
+ checked: self.showStartCodons,
391
+ onClick: () => self.toggleShowStartCodons(),
392
+ },
393
+ {
394
+ label: 'Show stop codons',
395
+ type: 'checkbox',
396
+ checked: self.showStopCodons,
397
+ onClick: () => self.toggleShowStopCodons(),
398
+ },
399
+ {
400
+ label: 'Show intron lines',
401
+ type: 'checkbox',
402
+ checked: self.showIntronLines,
403
+ onClick: () => self.toggleShowIntronLines(),
404
+ },
405
+ ]
406
+ },
407
+ }))
408
+ }
409
+
410
+ export type SixFrameFeatureDisplayStateModel = ReturnType<
411
+ typeof stateModelFactory
412
+ >
413
+ export type SixFrameFeatureDisplay = Instance<SixFrameFeatureDisplayStateModel>
@@ -0,0 +1,88 @@
1
+ import type { AnnotationFeatureI } from 'apollo-mst'
2
+ import {
3
+ DiscontinuousLocationEndChange,
4
+ DiscontinuousLocationStartChange,
5
+ LocationEndChange,
6
+ LocationStartChange,
7
+ TypeChange,
8
+ } from 'apollo-shared'
9
+
10
+ import type { ChangeManager } from '../../ChangeManager'
11
+
12
+ export function handleFeatureTypeChange(
13
+ changeManager: ChangeManager,
14
+ feature: AnnotationFeatureI,
15
+ oldType: string,
16
+ newType: string,
17
+ ) {
18
+ const featureId = feature._id
19
+ const change = new TypeChange({
20
+ typeName: 'TypeChange',
21
+ changedIds: [featureId],
22
+ featureId,
23
+ oldType: String(oldType),
24
+ newType: String(newType),
25
+ assembly: feature.assemblyId,
26
+ })
27
+ return changeManager.submit(change)
28
+ }
29
+
30
+ export function handleFeatureStartChange(
31
+ changeManager: ChangeManager,
32
+ feature: AnnotationFeatureI,
33
+ oldStart: number,
34
+ newStart: number,
35
+ index?: number,
36
+ ) {
37
+ const featureId = feature._id
38
+ const change =
39
+ index === undefined
40
+ ? new LocationStartChange({
41
+ typeName: 'LocationStartChange',
42
+ changedIds: [featureId],
43
+ featureId,
44
+ oldStart,
45
+ newStart,
46
+ assembly: feature.assemblyId,
47
+ })
48
+ : new DiscontinuousLocationStartChange({
49
+ typeName: 'DiscontinuousLocationStartChange',
50
+ changedIds: [featureId],
51
+ featureId,
52
+ oldStart,
53
+ newStart,
54
+ assembly: feature.assemblyId,
55
+ index,
56
+ })
57
+ return changeManager.submit(change)
58
+ }
59
+
60
+ export function handleFeatureEndChange(
61
+ changeManager: ChangeManager,
62
+ feature: AnnotationFeatureI,
63
+ oldEnd: number,
64
+ newEnd: number,
65
+ index?: number,
66
+ ) {
67
+ const featureId = feature._id
68
+ const change =
69
+ index === undefined
70
+ ? new LocationEndChange({
71
+ typeName: 'LocationEndChange',
72
+ changedIds: [featureId],
73
+ featureId,
74
+ oldEnd,
75
+ newEnd,
76
+ assembly: feature.assemblyId,
77
+ })
78
+ : new DiscontinuousLocationEndChange({
79
+ typeName: 'DiscontinuousLocationEndChange',
80
+ changedIds: [featureId],
81
+ featureId,
82
+ oldEnd,
83
+ newEnd,
84
+ assembly: feature.assemblyId,
85
+ index,
86
+ })
87
+ return changeManager.submit(change)
88
+ }