@apollo-annotation/shared 0.3.12 → 1.0.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 (170) hide show
  1. package/dist/Changes/{DeleteFeatureChange.d.ts → AddAndDeleteFeatureChanges.d.ts} +26 -11
  2. package/dist/Changes/AddAndDeleteFeatureChanges.d.ts.map +1 -0
  3. package/dist/Changes/AddAndDeleteFeatureChanges.js +117 -0
  4. package/dist/Changes/AddAndDeleteFeatureChanges.js.map +1 -0
  5. package/dist/Changes/AddAssemblyAliasesChange.d.ts +1 -4
  6. package/dist/Changes/AddAssemblyAliasesChange.d.ts.map +1 -1
  7. package/dist/Changes/AddAssemblyAliasesChange.js +0 -27
  8. package/dist/Changes/AddAssemblyAliasesChange.js.map +1 -1
  9. package/dist/Changes/AddAssemblyAndFeaturesFromFileChange.d.ts +2 -11
  10. package/dist/Changes/AddAssemblyAndFeaturesFromFileChange.d.ts.map +1 -1
  11. package/dist/Changes/AddAssemblyAndFeaturesFromFileChange.js +2 -82
  12. package/dist/Changes/AddAssemblyAndFeaturesFromFileChange.js.map +1 -1
  13. package/dist/Changes/AddAssemblyFromExternalChange.d.ts +1 -9
  14. package/dist/Changes/AddAssemblyFromExternalChange.d.ts.map +1 -1
  15. package/dist/Changes/AddAssemblyFromExternalChange.js +0 -72
  16. package/dist/Changes/AddAssemblyFromExternalChange.js.map +1 -1
  17. package/dist/Changes/AddAssemblyFromFileChange.d.ts +2 -17
  18. package/dist/Changes/AddAssemblyFromFileChange.d.ts.map +1 -1
  19. package/dist/Changes/AddAssemblyFromFileChange.js +2 -119
  20. package/dist/Changes/AddAssemblyFromFileChange.js.map +1 -1
  21. package/dist/Changes/AddFeaturesFromFileChange.d.ts +2 -11
  22. package/dist/Changes/AddFeaturesFromFileChange.d.ts.map +1 -1
  23. package/dist/Changes/AddFeaturesFromFileChange.js +2 -66
  24. package/dist/Changes/AddFeaturesFromFileChange.js.map +1 -1
  25. package/dist/Changes/AddRefSeqAliasesChange.d.ts +1 -4
  26. package/dist/Changes/AddRefSeqAliasesChange.d.ts.map +1 -1
  27. package/dist/Changes/AddRefSeqAliasesChange.js +0 -34
  28. package/dist/Changes/AddRefSeqAliasesChange.js.map +1 -1
  29. package/dist/Changes/DeleteAssemblyChange.d.ts +1 -9
  30. package/dist/Changes/DeleteAssemblyChange.d.ts.map +1 -1
  31. package/dist/Changes/DeleteAssemblyChange.js +0 -53
  32. package/dist/Changes/DeleteAssemblyChange.js.map +1 -1
  33. package/dist/Changes/DeleteUserChange.d.ts +1 -4
  34. package/dist/Changes/DeleteUserChange.d.ts.map +1 -1
  35. package/dist/Changes/DeleteUserChange.js +0 -19
  36. package/dist/Changes/DeleteUserChange.js.map +1 -1
  37. package/dist/Changes/FeatureAttributeChange.d.ts +1 -9
  38. package/dist/Changes/FeatureAttributeChange.d.ts.map +1 -1
  39. package/dist/Changes/FeatureAttributeChange.js +0 -82
  40. package/dist/Changes/FeatureAttributeChange.js.map +1 -1
  41. package/dist/Changes/ImportJBrowseConfigChange.d.ts +1 -4
  42. package/dist/Changes/ImportJBrowseConfigChange.d.ts.map +1 -1
  43. package/dist/Changes/ImportJBrowseConfigChange.js +1 -18
  44. package/dist/Changes/ImportJBrowseConfigChange.js.map +1 -1
  45. package/dist/Changes/LocationEndChange.d.ts +1 -9
  46. package/dist/Changes/LocationEndChange.d.ts.map +1 -1
  47. package/dist/Changes/LocationEndChange.js +0 -90
  48. package/dist/Changes/LocationEndChange.js.map +1 -1
  49. package/dist/Changes/LocationStartChange.d.ts +1 -9
  50. package/dist/Changes/LocationStartChange.d.ts.map +1 -1
  51. package/dist/Changes/LocationStartChange.js +0 -90
  52. package/dist/Changes/LocationStartChange.js.map +1 -1
  53. package/dist/Changes/MergeAndUndoMergeExonsChanges.d.ts +46 -0
  54. package/dist/Changes/MergeAndUndoMergeExonsChanges.d.ts.map +1 -0
  55. package/dist/Changes/MergeAndUndoMergeExonsChanges.js +83 -0
  56. package/dist/Changes/MergeAndUndoMergeExonsChanges.js.map +1 -0
  57. package/dist/Changes/{MergeTranscriptsChange.d.ts → MergeAndUndoMergeTranscriptsChanges.d.ts} +22 -6
  58. package/dist/Changes/MergeAndUndoMergeTranscriptsChanges.d.ts.map +1 -0
  59. package/dist/Changes/{MergeTranscriptsChange.js → MergeAndUndoMergeTranscriptsChanges.js} +40 -50
  60. package/dist/Changes/MergeAndUndoMergeTranscriptsChanges.js.map +1 -0
  61. package/dist/Changes/SplitAndUndoSplitExonChanges.d.ts +55 -0
  62. package/dist/Changes/SplitAndUndoSplitExonChanges.d.ts.map +1 -0
  63. package/dist/Changes/SplitAndUndoSplitExonChanges.js +115 -0
  64. package/dist/Changes/SplitAndUndoSplitExonChanges.js.map +1 -0
  65. package/dist/Changes/StrandChange.d.ts +1 -9
  66. package/dist/Changes/StrandChange.d.ts.map +1 -1
  67. package/dist/Changes/StrandChange.js +0 -77
  68. package/dist/Changes/StrandChange.js.map +1 -1
  69. package/dist/Changes/TypeChange.d.ts +1 -9
  70. package/dist/Changes/TypeChange.d.ts.map +1 -1
  71. package/dist/Changes/TypeChange.js +0 -77
  72. package/dist/Changes/TypeChange.js.map +1 -1
  73. package/dist/Changes/UserChange.d.ts +1 -4
  74. package/dist/Changes/UserChange.d.ts.map +1 -1
  75. package/dist/Changes/UserChange.js +0 -23
  76. package/dist/Changes/UserChange.js.map +1 -1
  77. package/dist/Changes/index.d.ts +29 -22
  78. package/dist/Changes/index.d.ts.map +1 -1
  79. package/dist/Changes/index.js +19 -24
  80. package/dist/Changes/index.js.map +1 -1
  81. package/dist/Validations/Validation.d.ts +2 -2
  82. package/dist/Validations/Validation.d.ts.map +1 -1
  83. package/dist/Validations/Validation.js +1 -1
  84. package/dist/Validations/Validation.js.map +1 -1
  85. package/dist/Validations/ValidationSet.d.ts +2 -2
  86. package/dist/Validations/ValidationSet.d.ts.map +1 -1
  87. package/dist/Validations/ValidationSet.js +2 -2
  88. package/dist/Validations/ValidationSet.js.map +1 -1
  89. package/dist/index.d.ts +0 -1
  90. package/dist/index.d.ts.map +1 -1
  91. package/dist/index.js +0 -1
  92. package/dist/index.js.map +1 -1
  93. package/dist/tsconfig.tsbuildinfo +1 -1
  94. package/package.json +9 -4
  95. package/src/Changes/{DeleteFeatureChange.ts → AddAndDeleteFeatureChanges.ts} +77 -107
  96. package/src/Changes/AddAssemblyAliasesChange.ts +0 -35
  97. package/src/Changes/AddAssemblyAndFeaturesFromFileChange.ts +5 -108
  98. package/src/Changes/AddAssemblyFromExternalChange.ts +0 -87
  99. package/src/Changes/AddAssemblyFromFileChange.ts +5 -169
  100. package/src/Changes/AddFeaturesFromFileChange.ts +5 -86
  101. package/src/Changes/AddRefSeqAliasesChange.ts +0 -44
  102. package/src/Changes/DeleteAssemblyChange.ts +0 -72
  103. package/src/Changes/DeleteUserChange.ts +0 -25
  104. package/src/Changes/FeatureAttributeChange.ts +0 -104
  105. package/src/Changes/ImportJBrowseConfigChange.ts +1 -27
  106. package/src/Changes/LocationEndChange.ts +0 -100
  107. package/src/Changes/LocationStartChange.ts +0 -100
  108. package/src/Changes/{MergeExonsChange.ts → MergeAndUndoMergeExonsChanges.ts} +70 -90
  109. package/src/Changes/{MergeTranscriptsChange.ts → MergeAndUndoMergeTranscriptsChanges.ts} +74 -66
  110. package/src/Changes/{SplitExonChange.ts → SplitAndUndoSplitExonChanges.ts} +95 -122
  111. package/src/Changes/StrandChange.ts +0 -94
  112. package/src/Changes/TypeChange.ts +0 -94
  113. package/src/Changes/UserChange.ts +0 -30
  114. package/src/Changes/index.ts +32 -24
  115. package/src/Validations/Validation.ts +2 -5
  116. package/src/Validations/ValidationSet.ts +3 -6
  117. package/src/index.ts +0 -1
  118. package/dist/Changes/AddFeatureChange.d.ts +0 -37
  119. package/dist/Changes/AddFeatureChange.d.ts.map +0 -1
  120. package/dist/Changes/AddFeatureChange.js +0 -169
  121. package/dist/Changes/AddFeatureChange.js.map +0 -1
  122. package/dist/Changes/DeleteFeatureChange.d.ts.map +0 -1
  123. package/dist/Changes/DeleteFeatureChange.js +0 -161
  124. package/dist/Changes/DeleteFeatureChange.js.map +0 -1
  125. package/dist/Changes/FromFileBaseChange.d.ts +0 -12
  126. package/dist/Changes/FromFileBaseChange.d.ts.map +0 -1
  127. package/dist/Changes/FromFileBaseChange.js +0 -196
  128. package/dist/Changes/FromFileBaseChange.js.map +0 -1
  129. package/dist/Changes/MergeExonsChange.d.ts +0 -30
  130. package/dist/Changes/MergeExonsChange.d.ts.map +0 -1
  131. package/dist/Changes/MergeExonsChange.js +0 -110
  132. package/dist/Changes/MergeExonsChange.js.map +0 -1
  133. package/dist/Changes/MergeTranscriptsChange.d.ts.map +0 -1
  134. package/dist/Changes/MergeTranscriptsChange.js.map +0 -1
  135. package/dist/Changes/SplitExonChange.d.ts +0 -34
  136. package/dist/Changes/SplitExonChange.d.ts.map +0 -1
  137. package/dist/Changes/SplitExonChange.js +0 -138
  138. package/dist/Changes/SplitExonChange.js.map +0 -1
  139. package/dist/Changes/UndoMergeExonsChange.d.ts +0 -28
  140. package/dist/Changes/UndoMergeExonsChange.d.ts.map +0 -1
  141. package/dist/Changes/UndoMergeExonsChange.js +0 -100
  142. package/dist/Changes/UndoMergeExonsChange.js.map +0 -1
  143. package/dist/Changes/UndoMergeTranscriptsChange.d.ts +0 -28
  144. package/dist/Changes/UndoMergeTranscriptsChange.d.ts.map +0 -1
  145. package/dist/Changes/UndoMergeTranscriptsChange.js +0 -100
  146. package/dist/Changes/UndoMergeTranscriptsChange.js.map +0 -1
  147. package/dist/Changes/UndoSplitExonChange.d.ts +0 -33
  148. package/dist/Changes/UndoSplitExonChange.d.ts.map +0 -1
  149. package/dist/Changes/UndoSplitExonChange.js +0 -107
  150. package/dist/Changes/UndoSplitExonChange.js.map +0 -1
  151. package/dist/Operations/GetAssembliesOperation.d.ts +0 -12
  152. package/dist/Operations/GetAssembliesOperation.d.ts.map +0 -1
  153. package/dist/Operations/GetAssembliesOperation.js +0 -16
  154. package/dist/Operations/GetAssembliesOperation.js.map +0 -1
  155. package/dist/Operations/GetFeaturesOperation.d.ts +0 -27
  156. package/dist/Operations/GetFeaturesOperation.d.ts.map +0 -1
  157. package/dist/Operations/GetFeaturesOperation.js +0 -38
  158. package/dist/Operations/GetFeaturesOperation.js.map +0 -1
  159. package/dist/Operations/index.d.ts +0 -9
  160. package/dist/Operations/index.d.ts.map +0 -1
  161. package/dist/Operations/index.js +0 -6
  162. package/dist/Operations/index.js.map +0 -1
  163. package/src/Changes/AddFeatureChange.ts +0 -236
  164. package/src/Changes/FromFileBaseChange.ts +0 -231
  165. package/src/Changes/UndoMergeExonsChange.ts +0 -149
  166. package/src/Changes/UndoMergeTranscriptsChange.ts +0 -153
  167. package/src/Changes/UndoSplitExonChange.ts +0 -174
  168. package/src/Operations/GetAssembliesOperation.ts +0 -28
  169. package/src/Operations/GetFeaturesOperation.ts +0 -58
  170. package/src/Operations/index.ts +0 -6
@@ -1,231 +0,0 @@
1
- /* eslint-disable @typescript-eslint/no-unsafe-assignment */
2
- /* eslint-disable @typescript-eslint/no-unsafe-argument */
3
- import {
4
- AssemblySpecificChange,
5
- type ServerDataStore,
6
- } from '@apollo-annotation/common'
7
- import type { AnnotationFeatureSnapshot } from '@apollo-annotation/mst'
8
- import type { FileDocument, RefSeqDocument } from '@apollo-annotation/schemas'
9
- import type { GFF3Feature } from '@gmod/gff'
10
-
11
- import { gff3ToAnnotationFeature } from '../GFF3/index.js'
12
-
13
- export abstract class FromFileBaseChange extends AssemblySpecificChange {
14
- async addRefSeqIntoDb(
15
- fileDoc: FileDocument,
16
- assembly: string,
17
- backend: ServerDataStore,
18
- ) {
19
- const { logger } = this
20
- const { filesService, refSeqChunkModel, refSeqModel, user } = backend
21
- const { CHUNK_SIZE } = process.env
22
- const customChunkSize = CHUNK_SIZE && Number(CHUNK_SIZE)
23
- let chunkIndex = 0
24
- let refSeqLen = 0
25
- let refSeqDoc: RefSeqDocument | undefined
26
- let fastaInfoStarted = fileDoc.type !== 'text/x-gff3'
27
-
28
- // Read data from compressed file and parse the content
29
- const sequenceStream = filesService.getFileStream(fileDoc)
30
- let sequenceBuffer = ''
31
- let incompleteLine = ''
32
- let lastLineIsIncomplete = true
33
- let parsingStarted = false
34
- logger.debug?.('starting sequence stream')
35
- let lineCount = 0
36
- const decoder = new TextDecoder()
37
- for await (const data of sequenceStream) {
38
- const chunk = decoder.decode(data)
39
- lastLineIsIncomplete = !chunk.endsWith('\n')
40
- // chunk is small enough that you can split the whole thing into lines without having to make it into smaller chunks first.
41
- const lines = chunk.split(/\r?\n/)
42
- if (incompleteLine) {
43
- lines[0] = `${incompleteLine}${lines[0]}`
44
- incompleteLine = ''
45
- }
46
- if (lastLineIsIncomplete) {
47
- incompleteLine = lines.pop() ?? ''
48
- }
49
- for (const line of lines) {
50
- lineCount++
51
- if (lineCount % 1_000_000 === 0) {
52
- logger.debug?.(`Processed ${lineCount} lines`)
53
- }
54
- // In case of GFF3 file we start to read sequence after '##FASTA' is found
55
- if (!fastaInfoStarted) {
56
- if (line.trim() === '##FASTA') {
57
- fastaInfoStarted = true
58
- }
59
- continue
60
- }
61
- const refSeqInfoLine = /^>\s*(\S+)\s*(.*)/.exec(line)
62
- // Add new ref sequence info if we are reference seq info line
63
- if (refSeqInfoLine) {
64
- parsingStarted = true
65
- logger.debug?.(
66
- `Reference sequence information line "${refSeqInfoLine[0]}"`,
67
- )
68
-
69
- // If there is sequence from previous reference sequence then we need to add it to previous ref seq
70
- if (sequenceBuffer !== '') {
71
- if (!refSeqDoc) {
72
- throw new Error('No refSeq document found')
73
- }
74
- refSeqLen += sequenceBuffer.length
75
- // We cannot use Mongo 'session' / transaction here because Mongo has 16 MB limit for transaction
76
- await refSeqChunkModel.create([
77
- {
78
- refSeq: refSeqDoc._id,
79
- n: chunkIndex,
80
- sequence: sequenceBuffer,
81
- user,
82
- status: -1,
83
- },
84
- ])
85
- sequenceBuffer = ''
86
- }
87
- await refSeqDoc?.updateOne({ length: refSeqLen })
88
- // await refSeqDoc?.updateOne({ length: refSeqLen }, { session })
89
- refSeqLen = 0
90
- chunkIndex = 0
91
-
92
- const name = refSeqInfoLine[1].trim()
93
- const description = refSeqInfoLine[2] ? refSeqInfoLine[2].trim() : ''
94
-
95
- // We cannot use Mongo 'session' / transaction here because Mongo has 16 MB limit for transaction
96
- const [newRefSeqDoc] = await refSeqModel.create([
97
- {
98
- name,
99
- description,
100
- assembly,
101
- length: 0,
102
- ...(customChunkSize ? { chunkSize: customChunkSize } : null),
103
- user,
104
- status: -1,
105
- },
106
- ])
107
- logger.debug?.(
108
- `Added new refSeq "${name}", desc "${description}", docId "${newRefSeqDoc._id}"`,
109
- )
110
- refSeqDoc = newRefSeqDoc
111
- } else if (/\S/.test(line)) {
112
- if (!refSeqDoc) {
113
- throw new Error('No refSeq document found')
114
- }
115
- const { _id, chunkSize } = refSeqDoc
116
- sequenceBuffer += line.replaceAll(/\s/g, '')
117
- // If sequence block > chunk size then save chunk into Mongo
118
- while (sequenceBuffer.length >= chunkSize) {
119
- const sequence = sequenceBuffer.slice(0, chunkSize)
120
- refSeqLen += sequence.length
121
- // We cannot use Mongo 'session' / transaction here because Mongo has 16 MB limit for transaction
122
- await refSeqChunkModel.create([
123
- { refSeq: _id, n: chunkIndex, sequence, user, status: -1 },
124
- ])
125
- chunkIndex++
126
- // Set remaining sequence
127
- sequenceBuffer = sequenceBuffer.slice(chunkSize)
128
- }
129
- }
130
- }
131
- }
132
- if (!parsingStarted) {
133
- throw new Error('No reference sequences found in file')
134
- }
135
-
136
- if (sequenceBuffer || lastLineIsIncomplete) {
137
- if (!refSeqDoc) {
138
- throw new Error('No refSeq document found')
139
- }
140
- // If the file did not end with line break so the last line is incomplete
141
- if (lastLineIsIncomplete) {
142
- sequenceBuffer += incompleteLine
143
- }
144
- refSeqLen += sequenceBuffer.length
145
- logger.verbose?.(
146
- `*** Add the very last chunk to ref seq ("${refSeqDoc._id}", index ${chunkIndex} and total length for ref seq is ${refSeqLen}): "${sequenceBuffer}"`,
147
- )
148
- logger.debug?.(
149
- `Creating refSeq chunk number ${chunkIndex} of "${refSeqDoc._id}"`,
150
- )
151
- // We cannot use Mongo 'session' / transaction here because Mongo has 16 MB limit for transaction
152
- await refSeqChunkModel.create([
153
- {
154
- refSeq: refSeqDoc._id,
155
- n: chunkIndex,
156
- sequence: sequenceBuffer,
157
- user,
158
- status: -1,
159
- },
160
- ])
161
- await refSeqDoc.updateOne({ length: refSeqLen })
162
- }
163
- }
164
-
165
- private refSeqCache = new Map<string, RefSeqDocument>()
166
-
167
- async removeExistingFeatures(backend: ServerDataStore) {
168
- const { featureModel, refSeqModel } = backend
169
- const { assembly, logger } = this
170
- logger.debug?.(`Removing existing features for assembly = ${assembly}`)
171
-
172
- const refSeqs: RefSeqDocument[] = await refSeqModel
173
- .find({ assembly })
174
- .exec()
175
-
176
- for (const refSeq of refSeqs) {
177
- await featureModel.deleteMany({ refSeq: refSeq._id })
178
- }
179
- }
180
-
181
- async addFeatureIntoDb(gff3Feature: GFF3Feature, backend: ServerDataStore) {
182
- const { INDEXED_IDS } = process.env
183
- let idsToIndex: string[] | undefined
184
- if (INDEXED_IDS) {
185
- idsToIndex = INDEXED_IDS.split(',')
186
- }
187
- const { assembly, refSeqCache } = this
188
- const { featureModel, refSeqModel, user } = backend
189
-
190
- const [{ seq_id: refName }] = gff3Feature
191
- if (!refName) {
192
- throw new Error(
193
- `Valid seq_id not found in feature ${JSON.stringify(gff3Feature)}`,
194
- )
195
- }
196
- let refSeqDoc = refSeqCache.get(refName)
197
- if (!refSeqDoc) {
198
- refSeqDoc =
199
- (await refSeqModel.findOne({ assembly, name: refName }).exec()) ??
200
- undefined
201
- if (refSeqDoc) {
202
- refSeqCache.set(refName, refSeqDoc)
203
- }
204
- }
205
- if (!refSeqDoc) {
206
- throw new Error(
207
- `RefSeq was not found by assembly "${assembly}" and seq_id "${refName}" not found`,
208
- )
209
- }
210
- const newFeature = gff3ToAnnotationFeature(gff3Feature, refSeqDoc._id)
211
- const allIds = this.getAllIds(newFeature)
212
- const indexedIds = this.getIndexedIds(newFeature, idsToIndex)
213
-
214
- // Add into Mongo
215
- // We cannot use Mongo 'session' / transaction here because Mongo has 16 MB limit for transaction
216
- await featureModel.create([
217
- { allIds, indexedIds, ...newFeature, user, status: -1 },
218
- ])
219
- }
220
-
221
- getAllIds(feature: AnnotationFeatureSnapshot): string[] {
222
- const allIds = [feature._id]
223
- if (feature.children) {
224
- for (const child of Object.values(feature.children)) {
225
- const childIds = this.getAllIds(child)
226
- allIds.push(...childIds)
227
- }
228
- }
229
- return allIds
230
- }
231
- }
@@ -1,149 +0,0 @@
1
- /* eslint-disable @typescript-eslint/require-await */
2
-
3
- import {
4
- type ChangeOptions,
5
- type ClientDataStore,
6
- FeatureChange,
7
- type LocalGFF3DataStore,
8
- type SerializedFeatureChange,
9
- type ServerDataStore,
10
- } from '@apollo-annotation/common'
11
- import type { AnnotationFeatureSnapshot } from '@apollo-annotation/mst'
12
-
13
- import { MergeExonsChange } from './MergeExonsChange.js'
14
-
15
- interface SerializedUndoMergeExonsChangeBase extends SerializedFeatureChange {
16
- typeName: 'UndoMergeExonsChange'
17
- }
18
-
19
- export interface UndoMergeExonsChangeDetails {
20
- exonsToRestore: AnnotationFeatureSnapshot[]
21
- parentFeatureId: string
22
- }
23
-
24
- interface SerializedUndoMergeExonsChangeSingle
25
- extends SerializedUndoMergeExonsChangeBase,
26
- UndoMergeExonsChangeDetails {}
27
-
28
- interface SerializedUndoMergeExonsChangeMultiple
29
- extends SerializedUndoMergeExonsChangeBase {
30
- changes: UndoMergeExonsChangeDetails[]
31
- }
32
-
33
- export type SerializedUndoMergeExonsChange =
34
- | SerializedUndoMergeExonsChangeSingle
35
- | SerializedUndoMergeExonsChangeMultiple
36
- export class UndoMergeExonsChange extends FeatureChange {
37
- typeName = 'UndoMergeExonsChange' as const
38
- changes: UndoMergeExonsChangeDetails[]
39
-
40
- constructor(json: SerializedUndoMergeExonsChange, options?: ChangeOptions) {
41
- super(json, options)
42
- this.changes = 'changes' in json ? json.changes : [json]
43
- }
44
-
45
- toJSON(): SerializedUndoMergeExonsChange {
46
- const { assembly, changedIds, changes, typeName } = this
47
- if (changes.length === 1) {
48
- const [{ exonsToRestore, parentFeatureId }] = changes
49
-
50
- return {
51
- typeName,
52
- changedIds,
53
- assembly,
54
- exonsToRestore,
55
- parentFeatureId,
56
- }
57
- }
58
- return { typeName, changedIds, assembly, changes }
59
- }
60
-
61
- async executeOnServer(backend: ServerDataStore) {
62
- const { featureModel, session } = backend
63
- const { changes } = this
64
- for (const change of changes) {
65
- const { exonsToRestore, parentFeatureId } = change
66
- if (exonsToRestore.length !== 2) {
67
- throw new Error(
68
- `Expected exactly two exons to restore. Got :${exonsToRestore.length}`,
69
- )
70
- }
71
- const topLevelFeature = await featureModel
72
- .findOne({ allIds: parentFeatureId })
73
- .session(session)
74
- .exec()
75
- if (!topLevelFeature) {
76
- throw new Error(`Could not find feature with ID "${parentFeatureId}"`)
77
- }
78
- const parentFeature = this.getFeatureFromId(
79
- topLevelFeature,
80
- parentFeatureId,
81
- )
82
- if (!parentFeature) {
83
- throw new Error(
84
- `Could not find feature with ID "${parentFeatureId}" in feature "${topLevelFeature._id.toString()}"`,
85
- )
86
- }
87
- if (!parentFeature.children) {
88
- parentFeature.children = new Map()
89
- }
90
- for (const exon of exonsToRestore) {
91
- this.addChild(parentFeature, exon)
92
- const childIds = this.getChildFeatureIds(exon)
93
- topLevelFeature.allIds.push(exon._id, ...childIds)
94
- }
95
- await topLevelFeature.save()
96
- }
97
- }
98
-
99
- async executeOnLocalGFF3(_backend: LocalGFF3DataStore) {
100
- throw new Error('executeOnLocalGFF3 not implemented')
101
- }
102
-
103
- async executeOnClient(dataStore: ClientDataStore) {
104
- // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
105
- if (!dataStore) {
106
- throw new Error('No data store')
107
- }
108
- const { changes } = this
109
- for (const change of changes) {
110
- const { exonsToRestore, parentFeatureId } = change
111
- if (!parentFeatureId) {
112
- throw new Error('Parent ID is missing')
113
- }
114
- const parentFeature = dataStore.getFeature(parentFeatureId)
115
- if (!parentFeature) {
116
- throw new Error(`Could not find parent feature "${parentFeatureId}"`)
117
- }
118
- // create an ID for the parent feature if it does not have one
119
- if (!parentFeature.attributes.get('_id')) {
120
- parentFeature.setAttribute('_id', [parentFeature._id])
121
- }
122
- for (const exon of exonsToRestore) {
123
- parentFeature.addChild(exon)
124
- }
125
- }
126
- }
127
-
128
- getInverse() {
129
- const { assembly, changedIds, changes, logger } = this
130
- const inverseChangedIds = [...changedIds].reverse()
131
- const inverseChanges = [...changes]
132
- .reverse()
133
- .map((undoMergeExonsChange) => ({
134
- firstExon: undoMergeExonsChange.exonsToRestore[0],
135
- secondExon: undoMergeExonsChange.exonsToRestore[1],
136
- parentFeatureId: undoMergeExonsChange.parentFeatureId,
137
- }))
138
-
139
- return new MergeExonsChange(
140
- {
141
- changedIds: inverseChangedIds,
142
- typeName: 'MergeExonsChange',
143
- changes: inverseChanges,
144
- assembly,
145
- },
146
- { logger },
147
- )
148
- }
149
- }
@@ -1,153 +0,0 @@
1
- /* eslint-disable @typescript-eslint/require-await */
2
-
3
- import {
4
- type ChangeOptions,
5
- type ClientDataStore,
6
- FeatureChange,
7
- type LocalGFF3DataStore,
8
- type SerializedFeatureChange,
9
- type ServerDataStore,
10
- } from '@apollo-annotation/common'
11
- import type { AnnotationFeatureSnapshot } from '@apollo-annotation/mst'
12
-
13
- import { MergeTranscriptsChange } from './MergeTranscriptsChange.js'
14
-
15
- interface SerializedUndoMergeTranscriptsChangeBase
16
- extends SerializedFeatureChange {
17
- typeName: 'UndoMergeTranscriptsChange'
18
- }
19
-
20
- export interface UndoMergeTranscriptsChangeDetails {
21
- transcriptsToRestore: AnnotationFeatureSnapshot[]
22
- parentFeatureId: string
23
- }
24
-
25
- interface SerializedUndoMergeTranscriptsChangeSingle
26
- extends SerializedUndoMergeTranscriptsChangeBase,
27
- UndoMergeTranscriptsChangeDetails {}
28
-
29
- interface SerializedUndoMergeTranscriptsChangeMultiple
30
- extends SerializedUndoMergeTranscriptsChangeBase {
31
- changes: UndoMergeTranscriptsChangeDetails[]
32
- }
33
-
34
- export type SerializedUndoMergeTranscriptsChange =
35
- | SerializedUndoMergeTranscriptsChangeSingle
36
- | SerializedUndoMergeTranscriptsChangeMultiple
37
- export class UndoMergeTranscriptsChange extends FeatureChange {
38
- typeName = 'UndoMergeTranscriptsChange' as const
39
- changes: UndoMergeTranscriptsChangeDetails[]
40
-
41
- constructor(
42
- json: SerializedUndoMergeTranscriptsChange,
43
- options?: ChangeOptions,
44
- ) {
45
- super(json, options)
46
- this.changes = 'changes' in json ? json.changes : [json]
47
- }
48
-
49
- toJSON(): SerializedUndoMergeTranscriptsChange {
50
- const { assembly, changedIds, changes, typeName } = this
51
- if (changes.length === 1) {
52
- const [{ transcriptsToRestore, parentFeatureId }] = changes
53
-
54
- return {
55
- typeName,
56
- changedIds,
57
- assembly,
58
- transcriptsToRestore,
59
- parentFeatureId,
60
- }
61
- }
62
- return { typeName, changedIds, assembly, changes }
63
- }
64
-
65
- async executeOnServer(backend: ServerDataStore) {
66
- const { featureModel, session } = backend
67
- const { changes } = this
68
- for (const change of changes) {
69
- const { transcriptsToRestore, parentFeatureId } = change
70
- if (transcriptsToRestore.length !== 2) {
71
- throw new Error(
72
- `Expected exactly two transcripts to restore. Got :${transcriptsToRestore.length}`,
73
- )
74
- }
75
- const topLevelFeature = await featureModel
76
- .findOne({ allIds: parentFeatureId })
77
- .session(session)
78
- .exec()
79
- if (!topLevelFeature) {
80
- throw new Error(`Could not find feature with ID "${parentFeatureId}"`)
81
- }
82
- const parentFeature = this.getFeatureFromId(
83
- topLevelFeature,
84
- parentFeatureId,
85
- )
86
- if (!parentFeature) {
87
- throw new Error(
88
- `Could not find feature with ID "${parentFeatureId}" in feature "${topLevelFeature._id.toString()}"`,
89
- )
90
- }
91
- if (!parentFeature.children) {
92
- parentFeature.children = new Map()
93
- }
94
- for (const transcript of transcriptsToRestore) {
95
- this.addChild(parentFeature, transcript)
96
- const childIds = this.getChildFeatureIds(transcript)
97
- topLevelFeature.allIds.push(transcript._id, ...childIds)
98
- }
99
- await topLevelFeature.save()
100
- }
101
- }
102
-
103
- async executeOnLocalGFF3(_backend: LocalGFF3DataStore) {
104
- throw new Error('executeOnLocalGFF3 not implemented')
105
- }
106
-
107
- async executeOnClient(dataStore: ClientDataStore) {
108
- // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
109
- if (!dataStore) {
110
- throw new Error('No data store')
111
- }
112
- const { changes } = this
113
- for (const change of changes) {
114
- const { transcriptsToRestore, parentFeatureId } = change
115
- if (!parentFeatureId) {
116
- throw new Error('Parent ID is missing')
117
- }
118
- const parentFeature = dataStore.getFeature(parentFeatureId)
119
- if (!parentFeature) {
120
- throw new Error(`Could not find parent feature "${parentFeatureId}"`)
121
- }
122
- // create an ID for the parent feature if it does not have one
123
- if (!parentFeature.attributes.get('_id')) {
124
- parentFeature.setAttribute('_id', [parentFeature._id])
125
- }
126
- for (const transcript of transcriptsToRestore) {
127
- parentFeature.addChild(transcript)
128
- }
129
- }
130
- }
131
-
132
- getInverse() {
133
- const { assembly, changedIds, changes, logger } = this
134
- const inverseChangedIds = [...changedIds].reverse()
135
- const inverseChanges = [...changes]
136
- .reverse()
137
- .map((undoMergeTranscriptsChange) => ({
138
- firstTranscript: undoMergeTranscriptsChange.transcriptsToRestore[0],
139
- secondTranscript: undoMergeTranscriptsChange.transcriptsToRestore[1],
140
- parentFeatureId: undoMergeTranscriptsChange.parentFeatureId,
141
- }))
142
-
143
- return new MergeTranscriptsChange(
144
- {
145
- changedIds: inverseChangedIds,
146
- typeName: 'MergeTranscriptsChange',
147
- changes: inverseChanges,
148
- assembly,
149
- },
150
- { logger },
151
- )
152
- }
153
- }
@@ -1,174 +0,0 @@
1
- /* eslint-disable @typescript-eslint/require-await */
2
-
3
- import {
4
- type ChangeOptions,
5
- type ClientDataStore,
6
- FeatureChange,
7
- type LocalGFF3DataStore,
8
- type SerializedFeatureChange,
9
- type ServerDataStore,
10
- } from '@apollo-annotation/common'
11
- import type { AnnotationFeatureSnapshot } from '@apollo-annotation/mst'
12
-
13
- import { findAndDeleteChildFeature } from './DeleteFeatureChange.js'
14
- import { SplitExonChange } from './SplitExonChange.js'
15
-
16
- interface SerializedUndoSplitExonChangeBase extends SerializedFeatureChange {
17
- typeName: 'UndoSplitExonChange'
18
- }
19
-
20
- export interface UndoSplitExonChangeDetails {
21
- exonToRestore: AnnotationFeatureSnapshot
22
- parentFeatureId: string
23
- idsToDelete: string[]
24
- upstreamCut: number
25
- downstreamCut: number
26
- leftExonId: string
27
- rightExonId: string
28
- }
29
-
30
- interface SerializedUndoSplitExonChangeSingle
31
- extends SerializedUndoSplitExonChangeBase,
32
- UndoSplitExonChangeDetails {}
33
-
34
- interface SerializedUndoSplitExonChangeMultiple
35
- extends SerializedUndoSplitExonChangeBase {
36
- changes: UndoSplitExonChangeDetails[]
37
- }
38
-
39
- export type SerializedUndoSplitExonChange =
40
- | SerializedUndoSplitExonChangeSingle
41
- | SerializedUndoSplitExonChangeMultiple
42
- export class UndoSplitExonChange extends FeatureChange {
43
- typeName = 'UndoSplitExonChange' as const
44
- changes: UndoSplitExonChangeDetails[]
45
-
46
- constructor(json: SerializedUndoSplitExonChange, options?: ChangeOptions) {
47
- super(json, options)
48
- this.changes = 'changes' in json ? json.changes : [json]
49
- }
50
-
51
- toJSON(): SerializedUndoSplitExonChange {
52
- const { assembly, changedIds, changes, typeName } = this
53
- if (changes.length === 1) {
54
- const [
55
- {
56
- exonToRestore,
57
- parentFeatureId,
58
- idsToDelete,
59
- upstreamCut,
60
- downstreamCut,
61
- leftExonId,
62
- rightExonId,
63
- },
64
- ] = changes
65
-
66
- return {
67
- typeName,
68
- changedIds,
69
- assembly,
70
- exonToRestore,
71
- parentFeatureId,
72
- idsToDelete,
73
- upstreamCut,
74
- downstreamCut,
75
- leftExonId,
76
- rightExonId,
77
- }
78
- }
79
- return { typeName, changedIds, assembly, changes }
80
- }
81
-
82
- async executeOnServer(backend: ServerDataStore) {
83
- const { featureModel, session } = backend
84
- const { changes } = this
85
- for (const change of changes) {
86
- const { exonToRestore, parentFeatureId, idsToDelete } = change
87
- const topLevelFeature = await featureModel
88
- .findOne({ allIds: parentFeatureId })
89
- .session(session)
90
- .exec()
91
- if (!topLevelFeature) {
92
- throw new Error(`Could not find feature with ID "${parentFeatureId}"`)
93
- }
94
- const parentFeature = this.getFeatureFromId(
95
- topLevelFeature,
96
- parentFeatureId,
97
- )
98
- if (!parentFeature) {
99
- throw new Error(
100
- `Could not find feature with ID "${parentFeatureId}" in feature "${topLevelFeature._id.toString()}"`,
101
- )
102
- }
103
- if (!parentFeature.children) {
104
- parentFeature.children = new Map()
105
- }
106
-
107
- this.addChild(parentFeature, exonToRestore)
108
- const childIds = this.getChildFeatureIds(exonToRestore)
109
- topLevelFeature.allIds.push(exonToRestore._id, ...childIds)
110
- topLevelFeature.allIds = topLevelFeature.allIds.filter(
111
- (id) => !idsToDelete.includes(id),
112
- )
113
- idsToDelete.map((id) =>
114
- findAndDeleteChildFeature(topLevelFeature, id, this),
115
- )
116
- await topLevelFeature.save()
117
- }
118
- }
119
-
120
- async executeOnLocalGFF3(_backend: LocalGFF3DataStore) {
121
- throw new Error('executeOnLocalGFF3 not implemented')
122
- }
123
-
124
- async executeOnClient(dataStore: ClientDataStore) {
125
- // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
126
- if (!dataStore) {
127
- throw new Error('No data store')
128
- }
129
- const { changes } = this
130
- for (const change of changes) {
131
- const { exonToRestore, parentFeatureId, idsToDelete } = change
132
- if (!parentFeatureId) {
133
- throw new Error('Parent ID is missing')
134
- }
135
- const parentFeature = dataStore.getFeature(parentFeatureId)
136
- if (!parentFeature) {
137
- throw new Error(`Could not find parent feature "${parentFeatureId}"`)
138
- }
139
- // create an ID for the parent feature if it does not have one
140
- if (!parentFeature.attributes.get('_id')) {
141
- parentFeature.setAttribute('_id', [parentFeature._id])
142
- }
143
- parentFeature.addChild(exonToRestore)
144
- idsToDelete.map((id) => {
145
- parentFeature.deleteChild(id)
146
- })
147
- }
148
- }
149
-
150
- getInverse() {
151
- const { assembly, changedIds, changes, logger } = this
152
- const inverseChangedIds = [...changedIds].reverse()
153
- const inverseChanges = [...changes]
154
- .reverse()
155
- .map((undoSplitExonChange) => ({
156
- parentFeatureId: undoSplitExonChange.parentFeatureId,
157
- exonToBeSplit: undoSplitExonChange.exonToRestore,
158
- upstreamCut: undoSplitExonChange.upstreamCut,
159
- downstreamCut: undoSplitExonChange.downstreamCut,
160
- leftExonId: undoSplitExonChange.leftExonId,
161
- rightExonId: undoSplitExonChange.rightExonId,
162
- }))
163
-
164
- return new SplitExonChange(
165
- {
166
- changedIds: inverseChangedIds,
167
- typeName: 'SplitExonChange',
168
- changes: inverseChanges,
169
- assembly,
170
- },
171
- { logger },
172
- )
173
- }
174
- }