@apollo-annotation/mst 0.1.21 → 0.2.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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@apollo-annotation/mst",
3
- "version": "0.1.21",
3
+ "version": "0.2.0",
4
4
  "main": "./dist/index.js",
5
5
  "scripts": {
6
6
  "build": "tsc"
@@ -17,6 +17,24 @@ const LateAnnotationFeature = types.late(
17
17
  (): IAnyModelType => AnnotationFeatureModel,
18
18
  )
19
19
 
20
+ export interface TranscriptPartLocation {
21
+ min: number
22
+ max: number
23
+ }
24
+
25
+ export interface TranscriptPartNonCoding extends TranscriptPartLocation {
26
+ type: 'fivePrimeUTR' | 'threePrimeUTR' | 'intron'
27
+ }
28
+
29
+ export interface TranscriptPartCoding extends TranscriptPartLocation {
30
+ type: 'CDS'
31
+ phase: 0 | 1 | 2
32
+ }
33
+
34
+ export type TranscriptPart = TranscriptPartCoding | TranscriptPartNonCoding
35
+
36
+ type TranscriptParts = TranscriptPart[]
37
+
20
38
  export const AnnotationFeatureModel = types
21
39
  .model('AnnotationFeatureModel', {
22
40
  _id: types.identifier,
@@ -108,7 +126,7 @@ export const AnnotationFeatureModel = types
108
126
  }
109
127
  return false
110
128
  },
111
- get cdsLocations(): { min: number; max: number; phase: 0 | 1 | 2 }[][] {
129
+ get transcriptParts(): TranscriptParts[] {
112
130
  if (self.type !== 'mRNA') {
113
131
  throw new Error(
114
132
  'Only features of type "mRNA" or equivalent can calculate CDS locations',
@@ -124,14 +142,22 @@ export const AnnotationFeatureModel = types
124
142
  if (cdsChildren.length === 0) {
125
143
  throw new Error('no CDS in mRNA')
126
144
  }
127
- const cdsLocations: { min: number; max: number; phase: 0 | 1 | 2 }[][] =
128
- []
145
+ const transcriptParts: TranscriptParts[] = []
129
146
  for (const cds of cdsChildren) {
130
147
  const { max: cdsMax, min: cdsMin } = cds
131
- const locs: { min: number; max: number }[] = []
148
+ const parts: TranscriptParts = []
149
+ let hasIntersected = false
150
+ const exonLocations: TranscriptPartLocation[] = []
132
151
  for (const [, child] of children) {
133
- if (child.type !== 'exon') {
134
- continue
152
+ if (child.type === 'exon') {
153
+ exonLocations.push({ min: child.min, max: child.max })
154
+ }
155
+ }
156
+ exonLocations.sort(({ min: a }, { min: b }) => a - b)
157
+ for (const child of exonLocations) {
158
+ const lastPart = parts.at(-1)
159
+ if (lastPart) {
160
+ parts.push({ min: lastPart.max, max: child.min, type: 'intron' })
135
161
  }
136
162
  const [start, end] = intersection2(
137
163
  cdsMin,
@@ -139,16 +165,53 @@ export const AnnotationFeatureModel = types
139
165
  child.min,
140
166
  child.max,
141
167
  )
168
+ let utrType: 'fivePrimeUTR' | 'threePrimeUTR'
169
+ if (hasIntersected) {
170
+ utrType = self.strand === 1 ? 'threePrimeUTR' : 'fivePrimeUTR'
171
+ } else {
172
+ utrType = self.strand === 1 ? 'fivePrimeUTR' : 'threePrimeUTR'
173
+ }
142
174
  if (start !== undefined && end !== undefined) {
143
- locs.push({ min: start, max: end })
175
+ hasIntersected = true
176
+ if (start === child.min && end === child.max) {
177
+ parts.push({ min: start, max: end, phase: 0, type: 'CDS' })
178
+ } else if (start === child.min) {
179
+ parts.push(
180
+ { min: start, max: end, phase: 0, type: 'CDS' },
181
+ { min: end, max: child.max, type: utrType },
182
+ )
183
+ } else if (end === child.max) {
184
+ parts.push(
185
+ { min: child.min, max: start, type: utrType },
186
+ { min: start, max: end, phase: 0, type: 'CDS' },
187
+ )
188
+ } else {
189
+ parts.push(
190
+ { min: child.min, max: start, type: utrType },
191
+ { min: start, max: end, phase: 0, type: 'CDS' },
192
+ {
193
+ min: end,
194
+ max: child.max,
195
+ type:
196
+ utrType === 'fivePrimeUTR'
197
+ ? 'threePrimeUTR'
198
+ : 'fivePrimeUTR',
199
+ },
200
+ )
201
+ }
202
+ } else {
203
+ parts.push({ min: child.min, max: child.max, type: utrType })
144
204
  }
145
205
  }
146
- locs.sort(({ min: a }, { min: b }) => a - b)
206
+ parts.sort(({ min: a }, { min: b }) => a - b)
147
207
  if (self.strand === -1) {
148
- locs.reverse()
208
+ parts.reverse()
149
209
  }
150
210
  let nextPhase: 0 | 1 | 2 = 0
151
- const phasedLocs = locs.map((loc) => {
211
+ const phasedParts = parts.map((loc) => {
212
+ if (loc.type !== 'CDS') {
213
+ return loc
214
+ }
152
215
  const phase = nextPhase
153
216
  nextPhase = ((3 - ((loc.max - loc.min - phase + 3) % 3)) % 3) as
154
217
  | 0
@@ -156,9 +219,17 @@ export const AnnotationFeatureModel = types
156
219
  | 2
157
220
  return { ...loc, phase }
158
221
  })
159
- cdsLocations.push(phasedLocs)
222
+ transcriptParts.push(phasedParts)
160
223
  }
161
- return cdsLocations
224
+ return transcriptParts
225
+ },
226
+ }))
227
+ .views((self) => ({
228
+ get cdsLocations(): TranscriptPartCoding[][] {
229
+ const { transcriptParts } = self
230
+ return transcriptParts.map((transcript) =>
231
+ transcript.filter((transcriptPart) => transcriptPart.type === 'CDS'),
232
+ )
162
233
  },
163
234
  }))
164
235
  .actions((self) => ({
@@ -193,7 +264,7 @@ export const AnnotationFeatureModel = types
193
264
  self.max = max
194
265
  }
195
266
  },
196
- setStrand(strand?: 1 | -1 | undefined) {
267
+ setStrand(strand?: 1 | -1) {
197
268
  self.strand = strand
198
269
  },
199
270
  addChild(childFeature: AnnotationFeatureSnapshot) {
@@ -274,7 +345,7 @@ export type Children = IMSTMap<typeof AnnotationFeatureModel> | undefined
274
345
 
275
346
  // eslint disables because of
276
347
  // https://mobx-state-tree.js.org/tips/typescript#using-a-mst-type-at-design-time
277
- // eslint-disable-next-line @typescript-eslint/no-empty-interface
348
+ // eslint-disable-next-line @typescript-eslint/no-empty-object-type
278
349
  interface AnnotationFeatureRaw
279
350
  extends Instance<typeof AnnotationFeatureModel> {}
280
351
  // This type isn't exactly right, since "children" is actually an IMSTMap and
@@ -283,7 +354,7 @@ export interface AnnotationFeature
283
354
  extends Omit<AnnotationFeatureRaw, 'children'> {
284
355
  children?: Map<string, AnnotationFeature>
285
356
  }
286
- // eslint-disable-next-line @typescript-eslint/no-empty-interface
357
+ // eslint-disable-next-line @typescript-eslint/no-empty-object-type
287
358
  interface AnnotationFeatureSnapshotRaw
288
359
  extends SnapshotIn<typeof AnnotationFeatureModel> {}
289
360
  export interface AnnotationFeatureSnapshot
@@ -37,8 +37,8 @@ export const ApolloAssembly = types
37
37
 
38
38
  // eslint disables because of
39
39
  // https://mobx-state-tree.js.org/tips/typescript#using-a-mst-type-at-design-time
40
- // eslint-disable-next-line @typescript-eslint/no-empty-interface
40
+ // eslint-disable-next-line @typescript-eslint/no-empty-object-type
41
41
  export interface ApolloAssemblyI extends Instance<typeof ApolloAssembly> {}
42
- // eslint-disable-next-line @typescript-eslint/no-empty-interface
42
+ // eslint-disable-next-line @typescript-eslint/no-empty-object-type
43
43
  export interface ApolloAssemblySnapshot
44
44
  extends SnapshotIn<typeof ApolloAssembly> {}
@@ -114,7 +114,7 @@ export const ApolloRefSeq = types
114
114
 
115
115
  // eslint disables because of
116
116
  // https://mobx-state-tree.js.org/tips/typescript#using-a-mst-type-at-design-time
117
- // eslint-disable-next-line @typescript-eslint/no-empty-interface
117
+ // eslint-disable-next-line @typescript-eslint/no-empty-object-type
118
118
  export interface ApolloRefSeqI extends Instance<typeof ApolloRefSeq> {}
119
- // eslint-disable-next-line @typescript-eslint/no-empty-interface
119
+ // eslint-disable-next-line @typescript-eslint/no-empty-object-type
120
120
  export interface ApolloRefSeqSnapshot extends SnapshotIn<typeof ApolloRefSeq> {}
@@ -15,7 +15,7 @@ export const CheckResult = types.model('CheckResult', {
15
15
 
16
16
  // eslint disables because of
17
17
  // https://mobx-state-tree.js.org/tips/typescript#using-a-mst-type-at-design-time
18
- // eslint-disable-next-line @typescript-eslint/no-empty-interface
18
+ // eslint-disable-next-line @typescript-eslint/no-empty-object-type
19
19
  export interface CheckResultI extends Instance<typeof CheckResult> {}
20
- // eslint-disable-next-line @typescript-eslint/no-empty-interface
20
+ // eslint-disable-next-line @typescript-eslint/no-empty-object-type
21
21
  export interface CheckResultSnapshot extends SnapshotIn<typeof CheckResult> {}
package/tsconfig.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "extends": "../../tsconfig.json",
2
+ "extends": "../../tsconfig-base.json",
3
3
  "compilerOptions": {
4
4
  "composite": true,
5
5
  "incremental": true,