@apollo-annotation/shared 0.3.5 → 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 (127) 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/AddAssemblyAndFeaturesFromFileChange.d.ts +1 -1
  5. package/dist/Changes/AddAssemblyFromExternalChange.d.ts +1 -1
  6. package/dist/Changes/AddAssemblyFromFileChange.d.ts +1 -1
  7. package/dist/Changes/AddFeatureChange.d.ts +3 -2
  8. package/dist/Changes/AddFeatureChange.js +5 -25
  9. package/dist/Changes/AddFeatureChange.js.map +1 -1
  10. package/dist/Changes/AddFeaturesFromFileChange.d.ts +1 -1
  11. package/dist/Changes/AddRefSeqAliasesChange.d.ts +1 -1
  12. package/dist/Changes/DeleteAssemblyChange.d.ts +1 -1
  13. package/dist/Changes/DeleteFeatureChange.d.ts +12 -11
  14. package/dist/Changes/DeleteFeatureChange.js +37 -32
  15. package/dist/Changes/DeleteFeatureChange.js.map +1 -1
  16. package/dist/Changes/DeleteUserChange.d.ts +1 -1
  17. package/dist/Changes/FeatureAttributeChange.d.ts +3 -2
  18. package/dist/Changes/FeatureAttributeChange.js +14 -6
  19. package/dist/Changes/FeatureAttributeChange.js.map +1 -1
  20. package/dist/Changes/FromFileBaseChange.d.ts +3 -3
  21. package/dist/Changes/FromFileBaseChange.js.map +1 -1
  22. package/dist/Changes/ImportJBrowseConfigChange.d.ts +4 -1
  23. package/dist/Changes/ImportJBrowseConfigChange.js +17 -13
  24. package/dist/Changes/ImportJBrowseConfigChange.js.map +1 -1
  25. package/dist/Changes/LocationEndChange.d.ts +1 -1
  26. package/dist/Changes/LocationEndChange.js +40 -37
  27. package/dist/Changes/LocationEndChange.js.map +1 -1
  28. package/dist/Changes/LocationStartChange.d.ts +1 -1
  29. package/dist/Changes/LocationStartChange.js +40 -37
  30. package/dist/Changes/LocationStartChange.js.map +1 -1
  31. package/dist/Changes/MergeExonsChange.d.ts +30 -0
  32. package/dist/Changes/MergeExonsChange.js +130 -0
  33. package/dist/Changes/MergeExonsChange.js.map +1 -0
  34. package/dist/Changes/MergeTranscriptsChange.d.ts +36 -0
  35. package/dist/Changes/MergeTranscriptsChange.js +246 -0
  36. package/dist/Changes/MergeTranscriptsChange.js.map +1 -0
  37. package/dist/Changes/SplitExonChange.d.ts +33 -0
  38. package/dist/Changes/SplitExonChange.js +142 -0
  39. package/dist/Changes/SplitExonChange.js.map +1 -0
  40. package/dist/Changes/StrandChange.d.ts +1 -1
  41. package/dist/Changes/TypeChange.d.ts +1 -1
  42. package/dist/Changes/UndoMergeExonsChange.d.ts +27 -0
  43. package/dist/Changes/UndoMergeExonsChange.js +104 -0
  44. package/dist/Changes/UndoMergeExonsChange.js.map +1 -0
  45. package/dist/Changes/UndoMergeTranscriptsChange.d.ts +27 -0
  46. package/dist/Changes/UndoMergeTranscriptsChange.js +104 -0
  47. package/dist/Changes/UndoMergeTranscriptsChange.js.map +1 -0
  48. package/dist/Changes/UndoSplitExonChange.d.ts +32 -0
  49. package/dist/Changes/UndoSplitExonChange.js +111 -0
  50. package/dist/Changes/UndoSplitExonChange.js.map +1 -0
  51. package/dist/Changes/UserChange.d.ts +1 -1
  52. package/dist/Changes/index.d.ts +21 -0
  53. package/dist/Changes/index.js +21 -0
  54. package/dist/Changes/index.js.map +1 -1
  55. package/dist/Checks/CDSCheck.d.ts +1 -1
  56. package/dist/GFF3/annotationFeatureToGFF3.d.ts +2 -2
  57. package/dist/GFF3/annotationFeatureToGFF3.js +7 -1
  58. package/dist/GFF3/annotationFeatureToGFF3.js.map +1 -1
  59. package/dist/GFF3/annotationFeatureToGFF3.test.js +1 -1
  60. package/dist/GFF3/annotationFeatureToGFF3.test.js.map +1 -1
  61. package/dist/GFF3/gff3ToAnnotationFeature.d.ts +2 -2
  62. package/dist/GFF3/gff3ToAnnotationFeature.test.d.ts +1 -1
  63. package/dist/GFF3/gff3ToAnnotationFeature.test.js +1 -1
  64. package/dist/GFF3/gff3ToAnnotationFeature.test.js.map +1 -1
  65. package/dist/GFF3/gffReservedKeys.d.ts +7 -0
  66. package/dist/GFF3/gffReservedKeys.js +21 -1
  67. package/dist/GFF3/gffReservedKeys.js.map +1 -1
  68. package/dist/Messages.d.ts +2 -2
  69. package/dist/Operations/GetAssembliesOperation.d.ts +1 -1
  70. package/dist/Operations/GetFeaturesOperation.d.ts +1 -1
  71. package/dist/Validations/CoreValidation.d.ts +2 -2
  72. package/dist/Validations/CoreValidation.js +1 -1
  73. package/dist/Validations/CoreValidation.js.map +1 -1
  74. package/dist/Validations/ParentChildValidation.d.ts +5 -5
  75. package/dist/Validations/ParentChildValidation.js +3 -1
  76. package/dist/Validations/ParentChildValidation.js.map +1 -1
  77. package/dist/Validations/Validation.d.ts +5 -5
  78. package/dist/Validations/ValidationSet.d.ts +4 -4
  79. package/dist/Validations/ValidationSet.js.map +1 -1
  80. package/dist/tsconfig.tsbuildinfo +1 -1
  81. package/dist/util.d.ts +2 -0
  82. package/dist/util.js +13 -0
  83. package/dist/util.js.map +1 -1
  84. package/package.json +4 -4
  85. package/src/Changes/AddAssemblyAliasesChange.ts +69 -0
  86. package/src/Changes/AddAssemblyAndFeaturesFromFileChange.ts +6 -6
  87. package/src/Changes/AddAssemblyFromExternalChange.ts +5 -5
  88. package/src/Changes/AddAssemblyFromFileChange.ts +5 -5
  89. package/src/Changes/AddFeatureChange.ts +11 -35
  90. package/src/Changes/AddFeaturesFromFileChange.ts +6 -6
  91. package/src/Changes/AddRefSeqAliasesChange.ts +6 -6
  92. package/src/Changes/DeleteAssemblyChange.ts +4 -4
  93. package/src/Changes/DeleteFeatureChange.ts +49 -43
  94. package/src/Changes/DeleteUserChange.ts +5 -5
  95. package/src/Changes/FeatureAttributeChange.ts +22 -13
  96. package/src/Changes/FromFileBaseChange.ts +6 -3
  97. package/src/Changes/ImportJBrowseConfigChange.ts +37 -22
  98. package/src/Changes/LocationEndChange.ts +47 -56
  99. package/src/Changes/LocationStartChange.ts +47 -56
  100. package/src/Changes/MergeExonsChange.ts +185 -0
  101. package/src/Changes/MergeTranscriptsChange.ts +379 -0
  102. package/src/Changes/SplitExonChange.ts +249 -0
  103. package/src/Changes/StrandChange.ts +6 -6
  104. package/src/Changes/TypeChange.ts +6 -6
  105. package/src/Changes/UndoMergeExonsChange.ts +149 -0
  106. package/src/Changes/UndoMergeTranscriptsChange.ts +153 -0
  107. package/src/Changes/UndoSplitExonChange.ts +174 -0
  108. package/src/Changes/UserChange.ts +5 -5
  109. package/src/Changes/index.ts +21 -0
  110. package/src/Checks/CDSCheck.ts +2 -2
  111. package/src/GFF3/annotationFeatureToGFF3.test.ts +4 -2
  112. package/src/GFF3/annotationFeatureToGFF3.ts +11 -5
  113. package/src/GFF3/gff3ToAnnotationFeature.test.ts +3 -3
  114. package/src/GFF3/gff3ToAnnotationFeature.ts +2 -2
  115. package/src/GFF3/gffReservedKeys.ts +25 -0
  116. package/src/Messages.ts +2 -2
  117. package/src/Operations/GetAssembliesOperation.ts +3 -3
  118. package/src/Operations/GetFeaturesOperation.ts +4 -4
  119. package/src/Validations/CoreValidation.ts +4 -3
  120. package/src/Validations/ParentChildValidation.ts +10 -8
  121. package/src/Validations/Validation.ts +5 -5
  122. package/src/Validations/ValidationSet.ts +8 -4
  123. package/src/util.ts +16 -0
  124. package/test_data/example01.json +3 -3
  125. package/test_data/example02.json +3 -3
  126. package/test_data/example04.json +3 -3
  127. package/test_data/gene_representations.gff3 +686 -1686
@@ -0,0 +1,149 @@
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'
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
+ }
@@ -0,0 +1,153 @@
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'
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
+ }
@@ -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,11 +1,11 @@
1
1
  /* eslint-disable @typescript-eslint/require-await */
2
2
  import {
3
3
  Change,
4
- ChangeOptions,
5
- ClientDataStore,
6
- LocalGFF3DataStore,
7
- SerializedChange,
8
- ServerDataStore,
4
+ type ChangeOptions,
5
+ type ClientDataStore,
6
+ type LocalGFF3DataStore,
7
+ type SerializedChange,
8
+ type ServerDataStore,
9
9
  } from '@apollo-annotation/common'
10
10
 
11
11
  export interface SerializedUserChangeBase extends SerializedChange {
@@ -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'
@@ -1,7 +1,7 @@
1
1
  import { Check } from '@apollo-annotation/common'
2
2
  import {
3
- AnnotationFeatureSnapshot,
4
- CheckResultSnapshot,
3
+ type AnnotationFeatureSnapshot,
4
+ type CheckResultSnapshot,
5
5
  } from '@apollo-annotation/mst'
6
6
  import { intersection2 } from '@jbrowse/core/util'
7
7
  import ObjectID from 'bson-objectid'
@@ -1,10 +1,12 @@
1
1
  /* eslint-disable prefer-destructuring */
2
2
  /* eslint-disable @typescript-eslint/no-floating-promises */
3
3
  import { describe, it } from 'node:test'
4
+
5
+ import { type AnnotationFeatureSnapshot } from '@apollo-annotation/mst'
4
6
  import { assert } from 'chai'
5
- import { readAnnotationFeatureSnapshot } from './gff3ToAnnotationFeature.test'
7
+
6
8
  import { annotationFeatureToGFF3 } from './annotationFeatureToGFF3'
7
- import { AnnotationFeatureSnapshot } from '@apollo-annotation/mst'
9
+ import { readAnnotationFeatureSnapshot } from './gff3ToAnnotationFeature.test'
8
10
 
9
11
  describe('annotationFeatureToGFF3', () => {
10
12
  it('Test mandatory columns', () => {
@@ -1,11 +1,11 @@
1
1
  /* eslint-disable @typescript-eslint/no-unsafe-assignment */
2
2
 
3
3
  import {
4
- AnnotationFeatureSnapshot,
5
- TranscriptPartLocation,
6
- TranscriptPartNonCoding,
4
+ type AnnotationFeatureSnapshot,
5
+ type TranscriptPartLocation,
6
+ type TranscriptPartNonCoding,
7
7
  } from '@apollo-annotation/mst'
8
- import { GFF3Feature } from '@gmod/gff'
8
+ import { type GFF3Feature } from '@gmod/gff'
9
9
  import { intersection2 } from '@jbrowse/core/util'
10
10
 
11
11
  export function annotationFeatureToGFF3(
@@ -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,13 +1,13 @@
1
1
  /* eslint-disable @typescript-eslint/no-floating-promises */
2
- import { describe, it } from 'node:test'
3
2
  import { readFileSync } from 'node:fs'
3
+ import { describe, it } from 'node:test'
4
4
 
5
- import gff, { GFF3Feature } from '@gmod/gff'
5
+ import { type AnnotationFeatureSnapshot } from '@apollo-annotation/mst'
6
+ import gff, { type GFF3Feature } from '@gmod/gff'
6
7
  import { assert, use } from 'chai'
7
8
  import chaiExclude from 'chai-exclude'
8
9
 
9
10
  import { gff3ToAnnotationFeature } from './gff3ToAnnotationFeature'
10
- import { AnnotationFeatureSnapshot } from '@apollo-annotation/mst'
11
11
 
12
12
  use(chaiExclude)
13
13
 
@@ -1,5 +1,5 @@
1
- import { AnnotationFeatureSnapshot } from '@apollo-annotation/mst'
2
- import { GFF3Feature, GFF3FeatureLineWithRefs } from '@gmod/gff'
1
+ import { type AnnotationFeatureSnapshot } from '@apollo-annotation/mst'
2
+ import { type GFF3Feature, type GFF3FeatureLineWithRefs } from '@gmod/gff'
3
3
  import { doesIntersect2 } from '@jbrowse/core/util'
4
4
  import ObjectID from 'bson-objectid'
5
5
 
@@ -59,3 +59,28 @@ export const internalToGFF: Record<GFFInternalAttribute, GFFReservedAttribute> =
59
59
  gff_ontology_term: 'Ontology_term',
60
60
  gff_is_circular: 'Is_circular',
61
61
  }
62
+
63
+ export function isGFFInternalAttribute(
64
+ attribute: string,
65
+ ): attribute is GFFInternalAttribute {
66
+ return attribute in internalToGFF
67
+ }
68
+
69
+ export type GFFColumn = 'score' | 'source'
70
+ export type GFFColumnInternal = 'gff_score' | 'gff_source'
71
+ export const gffColumnToInternal: Record<GFFColumn, GFFColumnInternal> = {
72
+ score: 'gff_score',
73
+ source: 'gff_source',
74
+ }
75
+ export function isGFFColumn(attribute: string): attribute is GFFColumn {
76
+ return attribute in gffColumnToInternal
77
+ }
78
+ export const gffInternalToColumn: Record<GFFColumnInternal, GFFColumn> = {
79
+ gff_score: 'score',
80
+ gff_source: 'source',
81
+ }
82
+ export function isGFFColumnInternal(
83
+ column: string,
84
+ ): column is GFFColumnInternal {
85
+ return column in gffInternalToColumn
86
+ }
package/src/Messages.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { SerializedChange } from '@apollo-annotation/common'
2
- import { CheckResultSnapshot } from '@apollo-annotation/mst'
1
+ import { type SerializedChange } from '@apollo-annotation/common'
2
+ import { type CheckResultSnapshot } from '@apollo-annotation/mst'
3
3
 
4
4
  interface BaseMessage {
5
5
  channel: string
@@ -1,9 +1,9 @@
1
1
  /* eslint-disable @typescript-eslint/require-await */
2
2
  import {
3
- LocalGFF3DataStore,
3
+ type LocalGFF3DataStore,
4
4
  Operation,
5
- SerializedOperation,
6
- ServerDataStore,
5
+ type SerializedOperation,
6
+ type ServerDataStore,
7
7
  } from '@apollo-annotation/common'
8
8
 
9
9
  interface SerializedGetAssembliesOperation extends SerializedOperation {