@apollo-annotation/shared 0.3.6 → 0.3.7

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 (66) hide show
  1. package/dist/Changes/AddAssemblyAliasesChange.d.ts +16 -0
  2. package/dist/Changes/AddAssemblyAliasesChange.js +50 -0
  3. package/dist/Changes/AddAssemblyAliasesChange.js.map +1 -0
  4. package/dist/Changes/AddFeatureChange.d.ts +1 -0
  5. package/dist/Changes/AddFeatureChange.js +5 -25
  6. package/dist/Changes/AddFeatureChange.js.map +1 -1
  7. package/dist/Changes/DeleteFeatureChange.d.ts +9 -8
  8. package/dist/Changes/DeleteFeatureChange.js +37 -32
  9. package/dist/Changes/DeleteFeatureChange.js.map +1 -1
  10. package/dist/Changes/FeatureAttributeChange.d.ts +2 -1
  11. package/dist/Changes/FeatureAttributeChange.js +14 -6
  12. package/dist/Changes/FeatureAttributeChange.js.map +1 -1
  13. package/dist/Changes/ImportJBrowseConfigChange.d.ts +3 -0
  14. package/dist/Changes/ImportJBrowseConfigChange.js +17 -13
  15. package/dist/Changes/ImportJBrowseConfigChange.js.map +1 -1
  16. package/dist/Changes/LocationEndChange.js +40 -37
  17. package/dist/Changes/LocationEndChange.js.map +1 -1
  18. package/dist/Changes/LocationStartChange.js +40 -37
  19. package/dist/Changes/LocationStartChange.js.map +1 -1
  20. package/dist/Changes/MergeExonsChange.d.ts +30 -0
  21. package/dist/Changes/MergeExonsChange.js +130 -0
  22. package/dist/Changes/MergeExonsChange.js.map +1 -0
  23. package/dist/Changes/MergeTranscriptsChange.d.ts +36 -0
  24. package/dist/Changes/MergeTranscriptsChange.js +246 -0
  25. package/dist/Changes/MergeTranscriptsChange.js.map +1 -0
  26. package/dist/Changes/SplitExonChange.d.ts +33 -0
  27. package/dist/Changes/SplitExonChange.js +142 -0
  28. package/dist/Changes/SplitExonChange.js.map +1 -0
  29. package/dist/Changes/UndoMergeExonsChange.d.ts +27 -0
  30. package/dist/Changes/UndoMergeExonsChange.js +104 -0
  31. package/dist/Changes/UndoMergeExonsChange.js.map +1 -0
  32. package/dist/Changes/UndoMergeTranscriptsChange.d.ts +27 -0
  33. package/dist/Changes/UndoMergeTranscriptsChange.js +104 -0
  34. package/dist/Changes/UndoMergeTranscriptsChange.js.map +1 -0
  35. package/dist/Changes/UndoSplitExonChange.d.ts +32 -0
  36. package/dist/Changes/UndoSplitExonChange.js +111 -0
  37. package/dist/Changes/UndoSplitExonChange.js.map +1 -0
  38. package/dist/Changes/index.d.ts +21 -0
  39. package/dist/Changes/index.js +21 -0
  40. package/dist/Changes/index.js.map +1 -1
  41. package/dist/GFF3/annotationFeatureToGFF3.js +7 -1
  42. package/dist/GFF3/annotationFeatureToGFF3.js.map +1 -1
  43. package/dist/Validations/ParentChildValidation.js +3 -1
  44. package/dist/Validations/ParentChildValidation.js.map +1 -1
  45. package/dist/tsconfig.tsbuildinfo +1 -1
  46. package/dist/util.d.ts +2 -0
  47. package/dist/util.js +13 -0
  48. package/dist/util.js.map +1 -1
  49. package/package.json +4 -4
  50. package/src/Changes/AddAssemblyAliasesChange.ts +69 -0
  51. package/src/Changes/AddFeatureChange.ts +5 -29
  52. package/src/Changes/DeleteFeatureChange.ts +42 -36
  53. package/src/Changes/FeatureAttributeChange.ts +16 -7
  54. package/src/Changes/ImportJBrowseConfigChange.ts +33 -18
  55. package/src/Changes/LocationEndChange.ts +41 -50
  56. package/src/Changes/LocationStartChange.ts +41 -50
  57. package/src/Changes/MergeExonsChange.ts +185 -0
  58. package/src/Changes/MergeTranscriptsChange.ts +379 -0
  59. package/src/Changes/SplitExonChange.ts +249 -0
  60. package/src/Changes/UndoMergeExonsChange.ts +149 -0
  61. package/src/Changes/UndoMergeTranscriptsChange.ts +153 -0
  62. package/src/Changes/UndoSplitExonChange.ts +174 -0
  63. package/src/Changes/index.ts +21 -0
  64. package/src/GFF3/annotationFeatureToGFF3.ts +7 -1
  65. package/src/Validations/ParentChildValidation.ts +3 -2
  66. package/src/util.ts +16 -0
@@ -0,0 +1,174 @@
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'
14
+ import { SplitExonChange } from './SplitExonChange'
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
+ }
@@ -1,3 +1,4 @@
1
+ import { AddAssemblyAliasesChange } from './AddAssemblyAliasesChange'
1
2
  import { AddAssemblyAndFeaturesFromFileChange } from './AddAssemblyAndFeaturesFromFileChange'
2
3
  import { AddAssemblyFromExternalChange } from './AddAssemblyFromExternalChange'
3
4
  import { AddAssemblyFromFileChange } from './AddAssemblyFromFileChange'
@@ -11,8 +12,14 @@ import { FeatureAttributeChange } from './FeatureAttributeChange'
11
12
  import { ImportJBrowseConfigChange } from './ImportJBrowseConfigChange'
12
13
  import { LocationEndChange } from './LocationEndChange'
13
14
  import { LocationStartChange } from './LocationStartChange'
15
+ import { MergeExonsChange } from './MergeExonsChange'
16
+ import { MergeTranscriptsChange } from './MergeTranscriptsChange'
17
+ import { SplitExonChange } from './SplitExonChange'
14
18
  import { StrandChange } from './StrandChange'
15
19
  import { TypeChange } from './TypeChange'
20
+ import { UndoMergeExonsChange } from './UndoMergeExonsChange'
21
+ import { UndoMergeTranscriptsChange } from './UndoMergeTranscriptsChange'
22
+ import { UndoSplitExonChange } from './UndoSplitExonChange'
16
23
  import { UserChange } from './UserChange'
17
24
 
18
25
  export const changes = {
@@ -28,10 +35,17 @@ export const changes = {
28
35
  ImportJBrowseConfigChange,
29
36
  LocationEndChange,
30
37
  LocationStartChange,
38
+ MergeExonsChange,
39
+ SplitExonChange,
40
+ MergeTranscriptsChange,
41
+ UndoMergeExonsChange,
42
+ UndoSplitExonChange,
43
+ UndoMergeTranscriptsChange,
31
44
  StrandChange,
32
45
  TypeChange,
33
46
  UserChange,
34
47
  AddRefSeqAliasesChange,
48
+ AddAssemblyAliasesChange,
35
49
  }
36
50
 
37
51
  export * from './AddAssemblyAndFeaturesFromFileChange'
@@ -46,7 +60,14 @@ export * from './FeatureAttributeChange'
46
60
  export * from './ImportJBrowseConfigChange'
47
61
  export * from './LocationEndChange'
48
62
  export * from './LocationStartChange'
63
+ export * from './MergeExonsChange'
64
+ export * from './SplitExonChange'
65
+ export * from './MergeTranscriptsChange'
66
+ export * from './UndoMergeExonsChange'
67
+ export * from './UndoSplitExonChange'
68
+ export * from './UndoMergeTranscriptsChange'
49
69
  export * from './StrandChange'
50
70
  export * from './TypeChange'
51
71
  export * from './UserChange'
52
72
  export * from './AddRefSeqAliasesChange'
73
+ export * from './AddAssemblyAliasesChange'
@@ -252,7 +252,13 @@ function getTranscriptParts(
252
252
  function getCdsLocations(
253
253
  feature: AnnotationFeatureSnapshot,
254
254
  ): TranscriptPartCoding[][] {
255
- const transcriptParts = getTranscriptParts(feature)
255
+ let transcriptParts: TranscriptParts[] = []
256
+ try {
257
+ transcriptParts = getTranscriptParts(feature)
258
+ } catch {
259
+ return []
260
+ }
261
+
256
262
  return transcriptParts.map((transcript) =>
257
263
  transcript.filter((transcriptPart) => transcriptPart.type === 'CDS'),
258
264
  )
@@ -1,5 +1,5 @@
1
1
  /* eslint-disable @typescript-eslint/no-unnecessary-condition */
2
- /* eslint-disable @typescript-eslint/restrict-template-expressions */
2
+
3
3
  import { type Change } from '@apollo-annotation/common'
4
4
  import { type Feature, type FeatureDocument } from '@apollo-annotation/schemas'
5
5
  import { type ClientSession, type Model } from 'mongoose'
@@ -10,6 +10,7 @@ import {
10
10
  isLocationEndChange,
11
11
  isLocationStartChange,
12
12
  } from '../Changes'
13
+ import { getPrintableId } from '../util'
13
14
 
14
15
  import { Validation, type ValidationResult } from './Validation'
15
16
 
@@ -80,7 +81,7 @@ export class ParentChildValidation extends Validation {
80
81
  (childFeature.max > feature.max || childFeature.min < feature.min)
81
82
  ) {
82
83
  throw new Error(
83
- `Feature "${childFeature._id}" exceeds the bounds of its parent, "${feature._id}"`,
84
+ `Feature ${getPrintableId(childFeature)} exceeds the bounds of its parent, ${getPrintableId(feature)}`,
84
85
  )
85
86
  }
86
87
  this.checkChildFeatureBoundaries(childFeature)
package/src/util.ts CHANGED
@@ -1,3 +1,6 @@
1
+ import { type AnnotationFeature } from '@apollo-annotation/mst'
2
+ import { type Feature } from '@apollo-annotation/schemas'
3
+
1
4
  export function splitStringIntoChunks(
2
5
  input: string,
3
6
  chunkSize: number,
@@ -9,3 +12,16 @@ export function splitStringIntoChunks(
9
12
  }
10
13
  return chunks
11
14
  }
15
+
16
+ export function getPrintableId(feature: Feature): string {
17
+ const ff = feature as unknown as AnnotationFeature
18
+ const gff_id = ff.attributes.get('gff_id')?.join(',')
19
+ if (gff_id) {
20
+ return `ID=${gff_id} (_id: ${feature._id.toString()})`
21
+ }
22
+ const gff_name = ff.attributes.get('gff_name')?.join(',')
23
+ if (gff_name) {
24
+ return `Name=${gff_name} (_id: ${feature._id.toString()})`
25
+ }
26
+ return `_id: ${feature._id.toString()}`
27
+ }