@apollo-annotation/shared 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 (157) hide show
  1. package/dist/Changes/AddAssemblyAndFeaturesFromFileChange.d.ts +33 -0
  2. package/dist/Changes/AddAssemblyAndFeaturesFromFileChange.js +83 -0
  3. package/dist/Changes/AddAssemblyAndFeaturesFromFileChange.js.map +1 -0
  4. package/dist/Changes/AddAssemblyFromExternalChange.d.ts +34 -0
  5. package/dist/Changes/AddAssemblyFromExternalChange.js +97 -0
  6. package/dist/Changes/AddAssemblyFromExternalChange.js.map +1 -0
  7. package/dist/Changes/AddAssemblyFromFileChange.d.ts +43 -0
  8. package/dist/Changes/AddAssemblyFromFileChange.js +140 -0
  9. package/dist/Changes/AddAssemblyFromFileChange.js.map +1 -0
  10. package/dist/Changes/AddFeatureChange.d.ts +35 -0
  11. package/dist/Changes/AddFeatureChange.js +169 -0
  12. package/dist/Changes/AddFeatureChange.js.map +1 -0
  13. package/dist/Changes/AddFeaturesFromFileChange.d.ts +32 -0
  14. package/dist/Changes/AddFeaturesFromFileChange.js +76 -0
  15. package/dist/Changes/AddFeaturesFromFileChange.js.map +1 -0
  16. package/dist/Changes/AddRefSeqAliasesChange.d.ts +20 -0
  17. package/dist/Changes/AddRefSeqAliasesChange.js +61 -0
  18. package/dist/Changes/AddRefSeqAliasesChange.js.map +1 -0
  19. package/dist/Changes/DeleteAssemblyChange.d.ts +18 -0
  20. package/dist/Changes/DeleteAssemblyChange.js +72 -0
  21. package/dist/Changes/DeleteAssemblyChange.js.map +1 -0
  22. package/dist/Changes/DeleteFeatureChange.d.ts +42 -0
  23. package/dist/Changes/DeleteFeatureChange.js +143 -0
  24. package/dist/Changes/DeleteFeatureChange.js.map +1 -0
  25. package/dist/Changes/DeleteUserChange.d.ts +25 -0
  26. package/dist/Changes/DeleteUserChange.js +53 -0
  27. package/dist/Changes/DeleteUserChange.js.map +1 -0
  28. package/dist/Changes/FeatureAttributeChange.d.ts +31 -0
  29. package/dist/Changes/FeatureAttributeChange.js +112 -0
  30. package/dist/Changes/FeatureAttributeChange.js.map +1 -0
  31. package/dist/Changes/FromFileBaseChange.d.ts +9 -0
  32. package/dist/Changes/FromFileBaseChange.js +187 -0
  33. package/dist/Changes/FromFileBaseChange.js.map +1 -0
  34. package/dist/Changes/ImportJBrowseConfigChange.d.ts +43 -0
  35. package/dist/Changes/ImportJBrowseConfigChange.js +67 -0
  36. package/dist/Changes/ImportJBrowseConfigChange.js.map +1 -0
  37. package/dist/Changes/LocationEndChange.d.ts +32 -0
  38. package/dist/Changes/LocationEndChange.js +129 -0
  39. package/dist/Changes/LocationEndChange.js.map +1 -0
  40. package/dist/Changes/LocationStartChange.d.ts +32 -0
  41. package/dist/Changes/LocationStartChange.js +129 -0
  42. package/dist/Changes/LocationStartChange.js.map +1 -0
  43. package/dist/Changes/StrandChange.d.ts +31 -0
  44. package/dist/Changes/StrandChange.js +114 -0
  45. package/dist/Changes/StrandChange.js.map +1 -0
  46. package/dist/Changes/TypeChange.d.ts +31 -0
  47. package/dist/Changes/TypeChange.js +114 -0
  48. package/dist/Changes/TypeChange.js.map +1 -0
  49. package/dist/Changes/UserChange.d.ts +25 -0
  50. package/dist/Changes/UserChange.js +51 -0
  51. package/dist/Changes/UserChange.js.map +1 -0
  52. package/dist/Changes/index.d.ts +50 -0
  53. package/dist/Changes/index.js +55 -0
  54. package/dist/Changes/index.js.map +1 -0
  55. package/dist/Checks/CDSCheck.d.ts +8 -0
  56. package/dist/Checks/CDSCheck.js +197 -0
  57. package/dist/Checks/CDSCheck.js.map +1 -0
  58. package/dist/Checks/index.d.ts +1 -0
  59. package/dist/Checks/index.js +5 -0
  60. package/dist/Checks/index.js.map +1 -0
  61. package/dist/Common/index.d.ts +1 -0
  62. package/dist/Common/index.js +5 -0
  63. package/dist/Common/index.js.map +1 -0
  64. package/dist/Common/jwtPayload.d.ts +12 -0
  65. package/dist/Common/jwtPayload.js +16 -0
  66. package/dist/Common/jwtPayload.js.map +1 -0
  67. package/dist/GFF3/gff3ToAnnotationFeature.d.ts +3 -0
  68. package/dist/GFF3/gff3ToAnnotationFeature.js +211 -0
  69. package/dist/GFF3/gff3ToAnnotationFeature.js.map +1 -0
  70. package/dist/GFF3/gff3ToAnnotationFeature.test.d.ts +1 -0
  71. package/dist/GFF3/gff3ToAnnotationFeature.test.js +174 -0
  72. package/dist/GFF3/gff3ToAnnotationFeature.test.js.map +1 -0
  73. package/dist/GFF3/gffReservedKeys.d.ts +5 -0
  74. package/dist/GFF3/gffReservedKeys.js +34 -0
  75. package/dist/GFF3/gffReservedKeys.js.map +1 -0
  76. package/dist/GFF3/index.d.ts +2 -0
  77. package/dist/GFF3/index.js +6 -0
  78. package/dist/GFF3/index.js.map +1 -0
  79. package/dist/Messages.d.ts +28 -0
  80. package/dist/Messages.js +3 -0
  81. package/dist/Messages.js.map +1 -0
  82. package/dist/Operations/GetAssembliesOperation.d.ts +13 -0
  83. package/dist/Operations/GetAssembliesOperation.js +20 -0
  84. package/dist/Operations/GetAssembliesOperation.js.map +1 -0
  85. package/dist/Operations/GetFeaturesOperation.d.ts +26 -0
  86. package/dist/Operations/GetFeaturesOperation.js +42 -0
  87. package/dist/Operations/GetFeaturesOperation.js.map +1 -0
  88. package/dist/Operations/index.d.ts +8 -0
  89. package/dist/Operations/index.js +10 -0
  90. package/dist/Operations/index.js.map +1 -0
  91. package/dist/Validations/CoreValidation.d.ts +17 -0
  92. package/dist/Validations/CoreValidation.js +36 -0
  93. package/dist/Validations/CoreValidation.js.map +1 -0
  94. package/dist/Validations/ParentChildValidation.d.ts +17 -0
  95. package/dist/Validations/ParentChildValidation.js +61 -0
  96. package/dist/Validations/ParentChildValidation.js.map +1 -0
  97. package/dist/Validations/Validation.d.ts +27 -0
  98. package/dist/Validations/Validation.js +27 -0
  99. package/dist/Validations/Validation.js.map +1 -0
  100. package/dist/Validations/ValidationSet.d.ts +24 -0
  101. package/dist/Validations/ValidationSet.js +86 -0
  102. package/dist/Validations/ValidationSet.js.map +1 -0
  103. package/dist/Validations/index.d.ts +4 -0
  104. package/dist/Validations/index.js +8 -0
  105. package/dist/Validations/index.js.map +1 -0
  106. package/dist/Validations/soSequenceTypes.d.ts +2 -0
  107. package/dist/Validations/soSequenceTypes.js +1868 -0
  108. package/dist/Validations/soSequenceTypes.js.map +1 -0
  109. package/dist/index.d.ts +8 -0
  110. package/dist/index.js +12 -0
  111. package/dist/index.js.map +1 -0
  112. package/dist/tsconfig.tsbuildinfo +1 -0
  113. package/dist/util.d.ts +4 -0
  114. package/dist/util.js +102 -0
  115. package/dist/util.js.map +1 -0
  116. package/package.json +17 -8
  117. package/src/Changes/AddAssemblyAndFeaturesFromFileChange.ts +13 -9
  118. package/src/Changes/AddAssemblyFromFileChange.ts +129 -43
  119. package/src/Changes/AddFeatureChange.ts +2 -3
  120. package/src/Changes/AddFeaturesFromFileChange.ts +8 -3
  121. package/src/Changes/AddRefSeqAliasesChange.ts +88 -0
  122. package/src/Changes/DeleteAssemblyChange.ts +1 -1
  123. package/src/Changes/DeleteFeatureChange.ts +1 -1
  124. package/src/Changes/FeatureAttributeChange.ts +1 -1
  125. package/src/Changes/FromFileBaseChange.ts +221 -0
  126. package/src/Changes/ImportJBrowseConfigChange.ts +116 -0
  127. package/src/Changes/LocationEndChange.ts +25 -18
  128. package/src/Changes/LocationStartChange.ts +25 -18
  129. package/src/Changes/TypeChange.ts +1 -1
  130. package/src/Changes/index.ts +6 -6
  131. package/src/Checks/CDSCheck.ts +125 -173
  132. package/src/Common/jwtPayload.ts +1 -1
  133. package/src/GFF3/gff3ToAnnotationFeature.test.ts +209 -0
  134. package/src/GFF3/gff3ToAnnotationFeature.ts +257 -0
  135. package/src/GFF3/gffReservedKeys.ts +61 -0
  136. package/src/GFF3/index.ts +2 -0
  137. package/src/Operations/GetFeaturesOperation.ts +2 -2
  138. package/src/Validations/ParentChildValidation.ts +5 -5
  139. package/src/index.ts +1 -0
  140. package/src/util.ts +16 -12
  141. package/test_data/braker.gff +13 -0
  142. package/test_data/example01.gff3 +26 -0
  143. package/test_data/example01.json +236 -0
  144. package/test_data/example02.json +225 -0
  145. package/test_data/example04.json +225 -0
  146. package/test_data/example05.gff3 +30 -0
  147. package/test_data/example06.gff3 +30 -0
  148. package/test_data/example07.gff3 +30 -0
  149. package/test_data/gene_mrna.gff3 +4 -0
  150. package/test_data/gene_representations.gff3 +1781 -0
  151. package/test_data/one_cds.gff3 +9 -0
  152. package/test_data/one_cds.json +67 -0
  153. package/test_data/two_cds.gff3 +9 -0
  154. package/test_data/two_cds.json +67 -0
  155. package/tsconfig.json +4 -4
  156. package/src/Changes/DiscontinuousLocationEndChange.ts +0 -182
  157. package/src/Changes/DiscontinuousLocationStartChange.ts +0 -182
@@ -0,0 +1,221 @@
1
+ /* eslint-disable @typescript-eslint/restrict-plus-operands */
2
+ /* eslint-disable @typescript-eslint/no-unsafe-assignment */
3
+ /* eslint-disable @typescript-eslint/no-unsafe-member-access */
4
+ /* eslint-disable @typescript-eslint/no-unsafe-call */
5
+ /* eslint-disable @typescript-eslint/no-unsafe-argument */
6
+ import {
7
+ AssemblySpecificChange,
8
+ ServerDataStore,
9
+ } from '@apollo-annotation/common'
10
+ import { FileDocument, RefSeqDocument } from '@apollo-annotation/schemas'
11
+ import { GFF3Feature } from '@gmod/gff'
12
+
13
+ import { gff3ToAnnotationFeature } from '../GFF3'
14
+
15
+ export abstract class FromFileBaseChange extends AssemblySpecificChange {
16
+ async addRefSeqIntoDb(
17
+ fileDoc: FileDocument,
18
+ assembly: string,
19
+ backend: ServerDataStore,
20
+ ) {
21
+ const { logger } = this
22
+ const { filesService, refSeqChunkModel, refSeqModel, user } = backend
23
+ const { CHUNK_SIZE } = process.env
24
+ const customChunkSize = CHUNK_SIZE && Number(CHUNK_SIZE)
25
+ let chunkIndex = 0
26
+ let refSeqLen = 0
27
+ let refSeqDoc: RefSeqDocument | undefined
28
+ let fastaInfoStarted = fileDoc.type !== 'text/x-gff3'
29
+
30
+ // Read data from compressed file and parse the content
31
+ const sequenceStream = filesService.getFileStream(fileDoc)
32
+ let sequenceBuffer = ''
33
+ let incompleteLine = ''
34
+ let lastLineIsIncomplete = true
35
+ let parsingStarted = false
36
+ logger.debug?.('starting sequence stream')
37
+ let lineCount = 0
38
+ for await (const data of sequenceStream) {
39
+ const chunk = data.toString()
40
+ lastLineIsIncomplete = !chunk.endsWith('\n')
41
+ // chunk is small enough that you can split the whole thing into lines without having to make it into smaller chunks first.
42
+ const lines = chunk.split(/\r?\n/)
43
+ if (incompleteLine) {
44
+ lines[0] = `${incompleteLine}${lines[0]}`
45
+ incompleteLine = ''
46
+ }
47
+ if (lastLineIsIncomplete) {
48
+ incompleteLine = lines.pop() || ''
49
+ }
50
+ for await (const line of lines) {
51
+ lineCount++
52
+ if (lineCount % 1_000_000 === 0) {
53
+ logger.debug?.(`Processed ${lineCount} lines`)
54
+ }
55
+ // In case of GFF3 file we start to read sequence after '##FASTA' is found
56
+ if (!fastaInfoStarted) {
57
+ if (line.trim() === '##FASTA') {
58
+ fastaInfoStarted = true
59
+ }
60
+ continue
61
+ }
62
+ const refSeqInfoLine = /^>\s*(\S+)\s*(.*)/.exec(line)
63
+ // Add new ref sequence info if we are reference seq info line
64
+ if (refSeqInfoLine) {
65
+ parsingStarted = true
66
+ logger.debug?.(
67
+ `Reference sequence information line "${refSeqInfoLine[0]}"`,
68
+ )
69
+
70
+ // If there is sequence from previous reference sequence then we need to add it to previous ref seq
71
+ if (sequenceBuffer !== '') {
72
+ if (!refSeqDoc) {
73
+ throw new Error('No refSeq document found')
74
+ }
75
+ refSeqLen += sequenceBuffer.length
76
+ // We cannot use Mongo 'session' / transaction here because Mongo has 16 MB limit for transaction
77
+ await refSeqChunkModel.create([
78
+ {
79
+ refSeq: refSeqDoc._id,
80
+ n: chunkIndex,
81
+ sequence: sequenceBuffer,
82
+ user,
83
+ status: -1,
84
+ },
85
+ ])
86
+ sequenceBuffer = ''
87
+ }
88
+ await refSeqDoc?.updateOne({ length: refSeqLen })
89
+ // await refSeqDoc?.updateOne({ length: refSeqLen }, { session })
90
+ refSeqLen = 0
91
+ chunkIndex = 0
92
+
93
+ const name = refSeqInfoLine[1].trim()
94
+ const description = refSeqInfoLine[2] ? refSeqInfoLine[2].trim() : ''
95
+
96
+ // We cannot use Mongo 'session' / transaction here because Mongo has 16 MB limit for transaction
97
+ const [newRefSeqDoc] = await refSeqModel.create([
98
+ {
99
+ name,
100
+ description,
101
+ assembly,
102
+ length: 0,
103
+ ...(customChunkSize ? { chunkSize: customChunkSize } : null),
104
+ user,
105
+ status: -1,
106
+ },
107
+ ])
108
+ logger.debug?.(
109
+ `Added new refSeq "${name}", desc "${description}", docId "${newRefSeqDoc._id}"`,
110
+ )
111
+ refSeqDoc = newRefSeqDoc
112
+ } else if (/\S/.test(line)) {
113
+ if (!refSeqDoc) {
114
+ throw new Error('No refSeq document found')
115
+ }
116
+ const { _id, chunkSize } = refSeqDoc
117
+ sequenceBuffer += line.replaceAll(/\s/g, '')
118
+ // If sequence block > chunk size then save chunk into Mongo
119
+ while (sequenceBuffer.length >= chunkSize) {
120
+ const sequence = sequenceBuffer.slice(0, chunkSize)
121
+ refSeqLen += sequence.length
122
+ // We cannot use Mongo 'session' / transaction here because Mongo has 16 MB limit for transaction
123
+ await refSeqChunkModel.create([
124
+ { refSeq: _id, n: chunkIndex, sequence, user, status: -1 },
125
+ ])
126
+ chunkIndex++
127
+ // Set remaining sequence
128
+ sequenceBuffer = sequenceBuffer.slice(chunkSize)
129
+ }
130
+ }
131
+ }
132
+ }
133
+ if (!parsingStarted) {
134
+ throw new Error('No reference sequences found in file')
135
+ }
136
+
137
+ if (sequenceBuffer || lastLineIsIncomplete) {
138
+ if (!refSeqDoc) {
139
+ throw new Error('No refSeq document found')
140
+ }
141
+ // If the file did not end with line break so the last line is incomplete
142
+ if (lastLineIsIncomplete) {
143
+ sequenceBuffer += incompleteLine
144
+ }
145
+ refSeqLen += sequenceBuffer.length
146
+ logger.verbose?.(
147
+ `*** Add the very last chunk to ref seq ("${refSeqDoc._id}", index ${chunkIndex} and total length for ref seq is ${refSeqLen}): "${sequenceBuffer}"`,
148
+ )
149
+ logger.debug?.(
150
+ `Creating refSeq chunk number ${chunkIndex} of "${refSeqDoc._id}"`,
151
+ )
152
+ // We cannot use Mongo 'session' / transaction here because Mongo has 16 MB limit for transaction
153
+ await refSeqChunkModel.create([
154
+ {
155
+ refSeq: refSeqDoc._id,
156
+ n: chunkIndex,
157
+ sequence: sequenceBuffer,
158
+ user,
159
+ status: -1,
160
+ },
161
+ ])
162
+ await refSeqDoc.updateOne({ length: refSeqLen })
163
+ }
164
+ }
165
+
166
+ private refSeqCache = new Map<string, RefSeqDocument>()
167
+
168
+ async removeExistingFeatures(backend: ServerDataStore) {
169
+ const { featureModel, refSeqModel } = backend
170
+ const { assembly, logger } = this
171
+ logger.debug?.(`Removing existing features for assembly = ${assembly}`)
172
+
173
+ const refSeqs: RefSeqDocument[] = await refSeqModel
174
+ .find({ assembly })
175
+ .exec()
176
+
177
+ for (const refSeq of refSeqs) {
178
+ await featureModel.deleteMany({ refSeq: refSeq._id })
179
+ }
180
+ }
181
+
182
+ async addFeatureIntoDb(gff3Feature: GFF3Feature, backend: ServerDataStore) {
183
+ const { featureModel, refSeqModel, user } = backend
184
+ const { assembly, refSeqCache } = this
185
+
186
+ const [{ seq_id: refName }] = gff3Feature
187
+ if (!refName) {
188
+ throw new Error(
189
+ `Valid seq_id not found in feature ${JSON.stringify(gff3Feature)}`,
190
+ )
191
+ }
192
+ let refSeqDoc = refSeqCache.get(refName)
193
+ if (!refSeqDoc) {
194
+ refSeqDoc =
195
+ (await refSeqModel.findOne({ assembly, name: refName }).exec()) ??
196
+ undefined
197
+ if (refSeqDoc) {
198
+ refSeqCache.set(refName, refSeqDoc)
199
+ }
200
+ }
201
+ if (!refSeqDoc) {
202
+ throw new Error(
203
+ `RefSeq was not found by assembly "${assembly}" and seq_id "${refName}" not found`,
204
+ )
205
+ }
206
+ // Let's add featureId to parent feature
207
+ const featureIds: string[] = []
208
+
209
+ const newFeature = gff3ToAnnotationFeature(
210
+ gff3Feature,
211
+ refSeqDoc._id,
212
+ featureIds,
213
+ )
214
+
215
+ // Add into Mongo
216
+ // We cannot use Mongo 'session' / transaction here because Mongo has 16 MB limit for transaction
217
+ await featureModel.create([
218
+ { allIds: featureIds, ...newFeature, user, status: -1 },
219
+ ])
220
+ }
221
+ }
@@ -0,0 +1,116 @@
1
+ /* eslint-disable @typescript-eslint/require-await */
2
+ import {
3
+ Change,
4
+ ChangeOptions,
5
+ ClientDataStore,
6
+ LocalGFF3DataStore,
7
+ ServerDataStore,
8
+ } from '@apollo-annotation/common'
9
+
10
+ interface JBrowseAssembly {
11
+ sequence: { adapter: { type: string } }
12
+ }
13
+
14
+ interface JBrowseTrack {
15
+ type: string
16
+ trackId: string
17
+ }
18
+
19
+ interface JBrowsePlugin {
20
+ name: string
21
+ }
22
+
23
+ interface JBrowseInternetAccount {
24
+ type: string
25
+ }
26
+
27
+ export interface JBrowseConfig {
28
+ assemblies?: JBrowseAssembly[]
29
+ tracks?: JBrowseTrack[]
30
+ plugins?: JBrowsePlugin[]
31
+ internetAccounts?: JBrowseInternetAccount[]
32
+ [key: string]: unknown
33
+ }
34
+
35
+ export interface SerializedImportJBrowseConfigChange {
36
+ typeName: 'ImportJBrowseConfigChange'
37
+ oldJBrowseConfig?: JBrowseConfig
38
+ newJBrowseConfig?: JBrowseConfig
39
+ }
40
+
41
+ export function filterJBrowseConfig(config: JBrowseConfig): JBrowseConfig {
42
+ const { assemblies, internetAccounts, plugins, tracks, ...rest } = config
43
+ const filteredAssemblies = assemblies?.filter(
44
+ (a) => a.sequence.adapter.type !== 'ApolloSequenceAdapter',
45
+ )
46
+ const filteredTracks = tracks?.filter((t) => t.type !== 'ApolloTrack')
47
+ const filteredPlugins = plugins?.filter((p) => p.name !== 'Apollo')
48
+ const filteredInternetAccounts = internetAccounts?.filter(
49
+ (i) => i.type !== 'ApolloInternetAccount',
50
+ )
51
+ const filteredConfig = rest as JBrowseConfig
52
+ if (filteredAssemblies) {
53
+ filteredConfig.assemblies = filteredAssemblies
54
+ }
55
+ if (filteredTracks) {
56
+ filteredConfig.tracks = filteredTracks
57
+ }
58
+ if (filteredPlugins) {
59
+ filteredConfig.plugins = filteredPlugins
60
+ }
61
+ if (filteredInternetAccounts) {
62
+ filteredConfig.internetAccounts = filteredInternetAccounts
63
+ }
64
+ return filteredConfig
65
+ }
66
+
67
+ export class ImportJBrowseConfigChange extends Change {
68
+ typeName = 'ImportJBrowseConfigChange' as const
69
+ oldJBrowseConfig?: JBrowseConfig
70
+ newJBrowseConfig?: JBrowseConfig
71
+
72
+ constructor(
73
+ json: SerializedImportJBrowseConfigChange,
74
+ options?: ChangeOptions,
75
+ ) {
76
+ super(json, options)
77
+ this.oldJBrowseConfig = json.oldJBrowseConfig
78
+ this.newJBrowseConfig = json.newJBrowseConfig
79
+ }
80
+
81
+ toJSON(): SerializedImportJBrowseConfigChange {
82
+ const { newJBrowseConfig, oldJBrowseConfig, typeName } = this
83
+ return { typeName, oldJBrowseConfig, newJBrowseConfig }
84
+ }
85
+
86
+ async executeOnServer(backend: ServerDataStore) {
87
+ const { jbrowseConfigModel } = backend
88
+ const { logger, newJBrowseConfig } = this
89
+ await jbrowseConfigModel.deleteMany()
90
+ if (!newJBrowseConfig) {
91
+ return
92
+ }
93
+ const filteredConfig = filterJBrowseConfig(newJBrowseConfig)
94
+ await jbrowseConfigModel.create(filteredConfig)
95
+ logger.debug?.('Stored new JBrowse Config')
96
+ }
97
+
98
+ async executeOnLocalGFF3(_backend: LocalGFF3DataStore) {
99
+ throw new Error('executeOnLocalGFF3 not implemented')
100
+ }
101
+
102
+ // eslint-disable-next-line @typescript-eslint/no-empty-function
103
+ async executeOnClient(_dataStore: ClientDataStore) {}
104
+
105
+ getInverse() {
106
+ const { logger, newJBrowseConfig, oldJBrowseConfig } = this
107
+ return new ImportJBrowseConfigChange(
108
+ {
109
+ typeName: 'ImportJBrowseConfigChange',
110
+ oldJBrowseConfig: newJBrowseConfig,
111
+ newJBrowseConfig: oldJBrowseConfig,
112
+ },
113
+ { logger },
114
+ )
115
+ }
116
+ }
@@ -30,7 +30,7 @@ interface SerializedLocationEndChangeMultiple
30
30
  changes: LocationEndChangeDetails[]
31
31
  }
32
32
 
33
- type SerializedLocationEndChange =
33
+ export type SerializedLocationEndChange =
34
34
  | SerializedLocationEndChangeSingle
35
35
  | SerializedLocationEndChangeMultiple
36
36
 
@@ -80,7 +80,9 @@ export class LocationEndChange extends FeatureChange {
80
80
  throw new Error(errMsg)
81
81
  // throw new NotFoundException(errMsg) -- This is causing runtime error because Exception comes from @nestjs/common!!!
82
82
  }
83
- logger.debug?.(`*** Feature found: ${JSON.stringify(topLevelFeature)}`)
83
+ logger.debug?.(
84
+ `*** TOP level feature found: ${JSON.stringify(topLevelFeature)}`,
85
+ )
84
86
 
85
87
  const foundFeature = this.getFeatureFromId(topLevelFeature, featureId)
86
88
  if (!foundFeature) {
@@ -89,28 +91,33 @@ export class LocationEndChange extends FeatureChange {
89
91
  throw new Error(errMsg)
90
92
  }
91
93
  logger.debug?.(`*** Found feature: ${JSON.stringify(foundFeature)}`)
92
- if (
93
- foundFeature.discontinuousLocations &&
94
- foundFeature.discontinuousLocations.length > 0
95
- ) {
96
- const errMsg =
97
- 'Must use "DiscontinuousLocationEndChange" to change a feature end that has discontinuous locations'
98
- logger.error(errMsg)
99
- throw new Error(errMsg)
100
- }
101
- if (foundFeature.end !== oldEnd) {
102
- const errMsg = `*** ERROR: Feature's current end value ${foundFeature.end} doesn't match with expected value ${oldEnd}`
103
- logger.error(errMsg)
104
- throw new Error(errMsg)
94
+ if (foundFeature.max === oldEnd) {
95
+ featuresForChanges.push({ feature: foundFeature, topLevelFeature })
96
+ } else {
97
+ if (foundFeature.children) {
98
+ for (const [, childFeature] of foundFeature.children) {
99
+ if (childFeature.max === oldEnd) {
100
+ logger.debug?.(
101
+ `*************** UPDATE CHILD FEATURE ID= ${featureId}, CHILD: ${JSON.stringify(
102
+ childFeature,
103
+ )}`,
104
+ )
105
+ featuresForChanges.push({
106
+ feature: childFeature,
107
+ topLevelFeature,
108
+ })
109
+ break
110
+ }
111
+ }
112
+ }
105
113
  }
106
- featuresForChanges.push({ feature: foundFeature, topLevelFeature })
107
114
  }
108
115
 
109
116
  // Let's update objects.
110
117
  for (const [idx, change] of changes.entries()) {
111
118
  const { newEnd } = change
112
119
  const { feature, topLevelFeature } = featuresForChanges[idx]
113
- feature.end = newEnd
120
+ feature.max = newEnd
114
121
  if (topLevelFeature._id.equals(feature._id)) {
115
122
  topLevelFeature.markModified('end') // Mark as modified. Without this save() -method is not updating data in database
116
123
  } else {
@@ -144,7 +151,7 @@ export class LocationEndChange extends FeatureChange {
144
151
  if (!feature) {
145
152
  throw new Error(`Could not find feature with identifier "${changedId}"`)
146
153
  }
147
- feature.setEnd(this.changes[idx].newEnd)
154
+ feature.setMax(this.changes[idx].newEnd)
148
155
  }
149
156
  }
150
157
 
@@ -30,7 +30,7 @@ interface SerializedLocationStartChangeMultiple
30
30
  changes: LocationStartChangeDetails[]
31
31
  }
32
32
 
33
- type SerializedLocationStartChange =
33
+ export type SerializedLocationStartChange =
34
34
  | SerializedLocationStartChangeSingle
35
35
  | SerializedLocationStartChangeMultiple
36
36
 
@@ -80,7 +80,9 @@ export class LocationStartChange extends FeatureChange {
80
80
  throw new Error(errMsg)
81
81
  // throw new NotFoundException(errMsg) -- This is causing runtime error because Exception comes from @nestjs/common!!!
82
82
  }
83
- logger.debug?.(`*** Feature found: ${JSON.stringify(topLevelFeature)}`)
83
+ logger.debug?.(
84
+ `*** TOP level feature found: ${JSON.stringify(topLevelFeature)}`,
85
+ )
84
86
 
85
87
  const foundFeature = this.getFeatureFromId(topLevelFeature, featureId)
86
88
  if (!foundFeature) {
@@ -89,28 +91,33 @@ export class LocationStartChange extends FeatureChange {
89
91
  throw new Error(errMsg)
90
92
  }
91
93
  logger.debug?.(`*** Found feature: ${JSON.stringify(foundFeature)}`)
92
- if (
93
- foundFeature.discontinuousLocations &&
94
- foundFeature.discontinuousLocations.length > 0
95
- ) {
96
- const errMsg =
97
- 'Must use "DiscontinuousLocationStartChange" to change a feature start that has discontinuous locations'
98
- logger.error(errMsg)
99
- throw new Error(errMsg)
100
- }
101
- if (foundFeature.start !== oldStart) {
102
- const errMsg = `*** ERROR: Feature's current start value ${foundFeature.start} doesn't match with expected value ${oldStart}`
103
- logger.error(errMsg)
104
- throw new Error(errMsg)
94
+ if (foundFeature.min === oldStart) {
95
+ featuresForChanges.push({ feature: foundFeature, topLevelFeature })
96
+ } else {
97
+ if (foundFeature.children) {
98
+ for (const [, childFeature] of foundFeature.children) {
99
+ if (childFeature.min === oldStart) {
100
+ logger.debug?.(
101
+ `*** UPDATE CHILD FEATURE ID= ${featureId}, CHILD: ${JSON.stringify(
102
+ childFeature,
103
+ )}`,
104
+ )
105
+ featuresForChanges.push({
106
+ feature: childFeature,
107
+ topLevelFeature,
108
+ })
109
+ break
110
+ }
111
+ }
112
+ }
105
113
  }
106
- featuresForChanges.push({ feature: foundFeature, topLevelFeature })
107
114
  }
108
115
 
109
116
  // Let's update objects.
110
117
  for (const [idx, change] of changes.entries()) {
111
118
  const { newStart } = change
112
119
  const { feature, topLevelFeature } = featuresForChanges[idx]
113
- feature.start = newStart
120
+ feature.min = newStart
114
121
  if (topLevelFeature._id.equals(feature._id)) {
115
122
  topLevelFeature.markModified('start') // Mark as modified. Without this save() -method is not updating data in database
116
123
  } else {
@@ -144,7 +151,7 @@ export class LocationStartChange extends FeatureChange {
144
151
  if (!feature) {
145
152
  throw new Error(`Could not find feature with identifier "${changedId}"`)
146
153
  }
147
- feature.setStart(this.changes[idx].newStart)
154
+ feature.setMin(this.changes[idx].newStart)
148
155
  }
149
156
  }
150
157
 
@@ -29,7 +29,7 @@ interface SerializedTypeChangeMultiple extends SerializedTypeChangeBase {
29
29
  changes: TypeChangeDetails[]
30
30
  }
31
31
 
32
- type SerializedTypeChange =
32
+ export type SerializedTypeChange =
33
33
  | SerializedTypeChangeSingle
34
34
  | SerializedTypeChangeMultiple
35
35
 
@@ -3,12 +3,12 @@ import { AddAssemblyFromExternalChange } from './AddAssemblyFromExternalChange'
3
3
  import { AddAssemblyFromFileChange } from './AddAssemblyFromFileChange'
4
4
  import { AddFeatureChange } from './AddFeatureChange'
5
5
  import { AddFeaturesFromFileChange } from './AddFeaturesFromFileChange'
6
+ import { AddRefSeqAliasesChange } from './AddRefSeqAliasesChange'
6
7
  import { DeleteAssemblyChange } from './DeleteAssemblyChange'
7
8
  import { DeleteFeatureChange } from './DeleteFeatureChange'
8
9
  import { DeleteUserChange } from './DeleteUserChange'
9
- import { DiscontinuousLocationEndChange } from './DiscontinuousLocationEndChange'
10
- import { DiscontinuousLocationStartChange } from './DiscontinuousLocationStartChange'
11
10
  import { FeatureAttributeChange } from './FeatureAttributeChange'
11
+ import { ImportJBrowseConfigChange } from './ImportJBrowseConfigChange'
12
12
  import { LocationEndChange } from './LocationEndChange'
13
13
  import { LocationStartChange } from './LocationStartChange'
14
14
  import { StrandChange } from './StrandChange'
@@ -24,14 +24,14 @@ export const changes = {
24
24
  DeleteAssemblyChange,
25
25
  DeleteFeatureChange,
26
26
  DeleteUserChange,
27
- DiscontinuousLocationEndChange,
28
- DiscontinuousLocationStartChange,
29
27
  FeatureAttributeChange,
28
+ ImportJBrowseConfigChange,
30
29
  LocationEndChange,
31
30
  LocationStartChange,
32
31
  StrandChange,
33
32
  TypeChange,
34
33
  UserChange,
34
+ AddRefSeqAliasesChange,
35
35
  }
36
36
 
37
37
  export * from './AddAssemblyAndFeaturesFromFileChange'
@@ -42,11 +42,11 @@ export * from './AddFeaturesFromFileChange'
42
42
  export * from './DeleteAssemblyChange'
43
43
  export * from './DeleteFeatureChange'
44
44
  export * from './DeleteUserChange'
45
- export * from './DiscontinuousLocationEndChange'
46
- export * from './DiscontinuousLocationStartChange'
47
45
  export * from './FeatureAttributeChange'
46
+ export * from './ImportJBrowseConfigChange'
48
47
  export * from './LocationEndChange'
49
48
  export * from './LocationStartChange'
50
49
  export * from './StrandChange'
51
50
  export * from './TypeChange'
52
51
  export * from './UserChange'
52
+ export * from './AddRefSeqAliasesChange'