@jbrowse/plugin-bed 2.16.1 → 2.17.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.
@@ -9,7 +9,6 @@ const io_1 = require("@jbrowse/core/util/io");
9
9
  const rxjs_1 = require("@jbrowse/core/util/rxjs");
10
10
  const util_1 = require("@jbrowse/core/util");
11
11
  const interval_tree_1 = __importDefault(require("@flatten-js/interval-tree"));
12
- const bgzf_filehandle_1 = require("@gmod/bgzf-filehandle");
13
12
  // locals
14
13
  const util_2 = require("../util");
15
14
  class BedAdapter extends BaseAdapter_1.BaseFeatureDataAdapter {
@@ -20,8 +19,7 @@ class BedAdapter extends BaseAdapter_1.BaseFeatureDataAdapter {
20
19
  async loadDataP(opts = {}) {
21
20
  const pm = this.pluginManager;
22
21
  const bedLoc = this.getConf('bedLocation');
23
- const buf = await (0, io_1.openLocation)(bedLoc, pm).readFile(opts);
24
- const buffer = (0, util_1.isGzip)(buf) ? await (0, bgzf_filehandle_1.unzip)(buf) : buf;
22
+ const buffer = await (0, util_1.fetchAndMaybeUnzip)((0, io_1.openLocation)(bedLoc, pm), opts);
25
23
  // 512MB max chrome string length is 512MB
26
24
  if (buffer.length > 536870888) {
27
25
  throw new Error('Data exceeds maximum string length (512MB)');
@@ -101,9 +99,18 @@ class BedAdapter extends BaseAdapter_1.BaseFeatureDataAdapter {
101
99
  }
102
100
  const names = await this.getNames();
103
101
  const intervalTree = new interval_tree_1.default();
104
- const ret = lines.map((f, i) => {
102
+ const ret = lines.map((line, i) => {
105
103
  const uniqueId = `${this.id}-${refName}-${i}`;
106
- return (0, util_2.featureData)(f, colRef, colStart, colEnd, scoreColumn, parser, uniqueId, names);
104
+ return new util_1.SimpleFeature((0, util_2.featureData)({
105
+ line,
106
+ colRef,
107
+ colStart,
108
+ colEnd,
109
+ scoreColumn,
110
+ parser,
111
+ uniqueId,
112
+ names,
113
+ }));
107
114
  });
108
115
  for (const obj of ret) {
109
116
  intervalTree.insert([obj.get('start'), obj.get('end')], obj);
@@ -7,9 +7,10 @@ const bed_1 = __importDefault(require("@gmod/bed"));
7
7
  const BaseAdapter_1 = require("@jbrowse/core/data_adapters/BaseAdapter");
8
8
  const io_1 = require("@jbrowse/core/util/io");
9
9
  const rxjs_1 = require("@jbrowse/core/util/rxjs");
10
+ const util_1 = require("@jbrowse/core/util");
10
11
  const tabix_1 = require("@gmod/tabix");
11
12
  // locals
12
- const util_1 = require("../util");
13
+ const util_2 = require("../util");
13
14
  class BedTabixAdapter extends BaseAdapter_1.BaseFeatureDataAdapter {
14
15
  constructor(config, getSubAdapter, pluginManager) {
15
16
  super(config, getSubAdapter, pluginManager);
@@ -55,13 +56,19 @@ class BedTabixAdapter extends BaseAdapter_1.BaseFeatureDataAdapter {
55
56
  const colRef = columnNumbers.ref - 1;
56
57
  const colStart = columnNumbers.start - 1;
57
58
  const colEnd = columnNumbers.end - 1;
58
- // colSame handles special case for tabix where a single column is both
59
- // the start and end, this is assumed to be covering the base at this
60
- // position (e.g. tabix -s 1 -b 2 -e 2) begin and end are same
61
59
  const names = await this.getNames();
62
60
  await this.bed.getLines(query.refName, query.start, query.end, {
63
61
  lineCallback: (line, fileOffset) => {
64
- observer.next((0, util_1.featureData)(line, colRef, colStart, colEnd, this.scoreColumn, this.parser, `${this.id}-${fileOffset}`, names));
62
+ observer.next(new util_1.SimpleFeature((0, util_2.featureData)({
63
+ line,
64
+ colRef,
65
+ colStart,
66
+ colEnd,
67
+ scoreColumn: this.scoreColumn,
68
+ parser: this.parser,
69
+ uniqueId: `${this.id}-${fileOffset}`,
70
+ names,
71
+ })));
65
72
  },
66
73
  signal: opts.signal,
67
74
  });
@@ -9,7 +9,6 @@ const io_1 = require("@jbrowse/core/util/io");
9
9
  const rxjs_1 = require("@jbrowse/core/util/rxjs");
10
10
  const util_1 = require("@jbrowse/core/util");
11
11
  const interval_tree_1 = __importDefault(require("@flatten-js/interval-tree"));
12
- const bgzf_filehandle_1 = require("@gmod/bgzf-filehandle");
13
12
  const svTypes = new Set(['DUP', 'TRA', 'INV', 'CNV', 'DEL']);
14
13
  function featureData(line, uniqueId, flip, names) {
15
14
  const l = line.split('\t');
@@ -64,11 +63,11 @@ class BedpeAdapter extends BaseAdapter_1.BaseFeatureDataAdapter {
64
63
  super(...arguments);
65
64
  this.intervalTrees = {};
66
65
  }
67
- async loadDataP(opts = {}) {
66
+ async loadDataP(opts) {
68
67
  const pm = this.pluginManager;
69
68
  const bedLoc = this.getConf('bedpeLocation');
70
- const buf = await (0, io_1.openLocation)(bedLoc, pm).readFile(opts);
71
- const buffer = (0, util_1.isGzip)(buf) ? await (0, bgzf_filehandle_1.unzip)(buf) : buf;
69
+ const loc = (0, io_1.openLocation)(bedLoc, pm);
70
+ const buffer = await (0, util_1.fetchAndMaybeUnzip)(loc, opts);
72
71
  // 512MB max chrome string length is 512MB
73
72
  if (buffer.length > 536870888) {
74
73
  throw new Error('Data exceeds maximum string length (512MB)');
@@ -5,7 +5,7 @@ import { Region } from '@jbrowse/core/util/types';
5
5
  import { Feature } from '@jbrowse/core/util';
6
6
  import { Observer } from 'rxjs';
7
7
  export default class BigBedAdapter extends BaseFeatureDataAdapter {
8
- private cached?;
8
+ private cachedP?;
9
9
  configurePre(opts?: BaseOptions): Promise<{
10
10
  bigbed: BigBed;
11
11
  header: import("@gmod/bbi").Header;
@@ -17,6 +17,7 @@ export default class BigBedAdapter extends BaseFeatureDataAdapter {
17
17
  parser: BED;
18
18
  }>;
19
19
  getRefNames(opts?: BaseOptions): Promise<string[]>;
20
+ getData(): Promise<Feature[]>;
20
21
  getHeader(opts?: BaseOptions): Promise<{
21
22
  version: number;
22
23
  fileType: string;
@@ -25,7 +26,13 @@ export default class BigBedAdapter extends BaseFeatureDataAdapter {
25
26
  [k: string]: string;
26
27
  };
27
28
  }>;
28
- getFeaturesHelper(query: Region, opts: BaseOptions, observer: Observer<Feature>, allowRedispatch: boolean, originalQuery?: Region): Promise<void>;
29
+ getFeaturesHelper({ query, opts, observer, allowRedispatch, originalQuery, }: {
30
+ query: Region;
31
+ opts: BaseOptions;
32
+ observer: Observer<Feature>;
33
+ allowRedispatch: boolean;
34
+ originalQuery?: Region;
35
+ }): Promise<void>;
29
36
  getFeatures(query: Region, opts?: BaseOptions): import("rxjs").Observable<Feature>;
30
37
  freeResources(): void;
31
38
  }
@@ -9,6 +9,7 @@ const BaseAdapter_1 = require("@jbrowse/core/data_adapters/BaseAdapter");
9
9
  const io_1 = require("@jbrowse/core/util/io");
10
10
  const rxjs_1 = require("@jbrowse/core/util/rxjs");
11
11
  const util_1 = require("@jbrowse/core/util");
12
+ const rxjs_2 = require("rxjs");
12
13
  // locals
13
14
  const util_2 = require("../util");
14
15
  class BigBedAdapter extends BaseAdapter_1.BaseFeatureDataAdapter {
@@ -18,22 +19,42 @@ class BigBedAdapter extends BaseAdapter_1.BaseFeatureDataAdapter {
18
19
  filehandle: (0, io_1.openLocation)(this.getConf('bigBedLocation'), pm),
19
20
  });
20
21
  const header = await bigbed.getHeader(opts);
21
- const parser = new bed_1.default({ autoSql: header.autoSql });
22
- return { bigbed, header, parser };
22
+ const parser = new bed_1.default({
23
+ autoSql: header.autoSql,
24
+ });
25
+ return {
26
+ bigbed,
27
+ header,
28
+ parser,
29
+ };
23
30
  }
24
31
  async configure(opts) {
25
- if (!this.cached) {
26
- this.cached = this.configurePre(opts).catch((e) => {
27
- this.cached = undefined;
32
+ if (!this.cachedP) {
33
+ this.cachedP = this.configurePre(opts).catch((e) => {
34
+ this.cachedP = undefined;
28
35
  throw e;
29
36
  });
30
37
  }
31
- return this.cached;
38
+ return this.cachedP;
32
39
  }
33
40
  async getRefNames(opts) {
34
41
  const { header } = await this.configure(opts);
35
42
  return Object.keys(header.refsByName);
36
43
  }
44
+ async getData() {
45
+ const refNames = await this.getRefNames();
46
+ const features = [];
47
+ for (const refName of refNames) {
48
+ const f = await (0, rxjs_2.firstValueFrom)(this.getFeatures({
49
+ assemblyName: 'unknown',
50
+ refName,
51
+ start: 0,
52
+ end: Number.MAX_SAFE_INTEGER,
53
+ }).pipe((0, rxjs_2.toArray)()));
54
+ features.push(f);
55
+ }
56
+ return features.flat();
57
+ }
37
58
  async getHeader(opts) {
38
59
  const { parser, header } = await this.configure(opts);
39
60
  const { version, fileType } = header;
@@ -45,7 +66,7 @@ class BigBedAdapter extends BaseAdapter_1.BaseFeatureDataAdapter {
45
66
  fields: Object.fromEntries(fields.map(({ name, comment }) => [name, comment])),
46
67
  };
47
68
  }
48
- async getFeaturesHelper(query, opts, observer, allowRedispatch, originalQuery = query) {
69
+ async getFeaturesHelper({ query, opts, observer, allowRedispatch, originalQuery = query, }) {
49
70
  const { signal } = opts;
50
71
  const scoreColumn = this.getConf('scoreColumn');
51
72
  const aggregateField = this.getConf('aggregateField');
@@ -66,7 +87,17 @@ class BigBedAdapter extends BaseAdapter_1.BaseFeatureDataAdapter {
66
87
  }
67
88
  }
68
89
  if (maxEnd > query.end || minStart < query.start) {
69
- await this.getFeaturesHelper({ ...query, start: minStart, end: maxEnd }, opts, observer, false, query);
90
+ await this.getFeaturesHelper({
91
+ query: {
92
+ ...query,
93
+ start: minStart,
94
+ end: maxEnd,
95
+ },
96
+ opts,
97
+ observer,
98
+ allowRedispatch: false,
99
+ originalQuery: query,
100
+ });
70
101
  return;
71
102
  }
72
103
  }
@@ -75,62 +106,31 @@ class BigBedAdapter extends BaseAdapter_1.BaseFeatureDataAdapter {
75
106
  throw new Error('found uniqueId undefined');
76
107
  }
77
108
  for (const feat of feats) {
78
- const data = parser.parseLine(`${query.refName}\t${feat.start}\t${feat.end}\t${feat.rest}`, { uniqueId: feat.uniqueId });
109
+ const line = `${query.refName}\t${feat.start}\t${feat.end}\t${feat.rest}`;
110
+ const data = parser.parseLine(line, { uniqueId: feat.uniqueId });
79
111
  const aggr = data[aggregateField];
80
112
  if (!parentAggregation[aggr]) {
81
113
  parentAggregation[aggr] = [];
82
114
  }
83
- const { uniqueId, type, chromStart, chromStarts, blockStarts, blockCount, blockSizes, chromEnd, thickStart, thickEnd, chrom, score, ...rest } = data;
84
- const subfeatures = blockCount
85
- ? (0, util_2.makeBlocks)({
86
- chromStarts,
87
- blockStarts,
88
- blockCount,
89
- blockSizes,
90
- uniqueId,
91
- refName: query.refName,
92
- start: feat.start,
93
- })
94
- : [];
95
- if ((0, util_2.isUcscProcessedTranscript)(data)) {
96
- const f = (0, util_2.ucscProcessedTranscript)({
97
- ...rest,
98
- uniqueId,
99
- type,
100
- start: feat.start,
101
- end: feat.end,
102
- refName: query.refName,
103
- score: scoreColumn ? +data[scoreColumn] : score,
104
- chromStarts,
105
- blockCount,
106
- blockSizes,
107
- thickStart,
108
- thickEnd,
109
- subfeatures,
110
- });
111
- if (aggr) {
112
- parentAggregation[aggr].push(f);
113
- }
114
- else {
115
- if ((0, util_1.doesIntersect2)(f.start, f.end, originalQuery.start, originalQuery.end)) {
116
- observer.next(new util_1.SimpleFeature({ id: `${this.id}-${uniqueId}`, data: f }));
117
- }
118
- }
115
+ const { uniqueId, type, chrom, chromStart, chromEnd, description, chromStarts: chromStarts2, blockStarts: blockStarts2, blockSizes: blockSizes2, score: score2, blockCount, thickStart, thickEnd, strand, ...rest } = data;
116
+ const f = (0, util_2.featureData2)({
117
+ ...rest,
118
+ scoreColumn,
119
+ line,
120
+ parser,
121
+ uniqueId,
122
+ start: feat.start,
123
+ end: feat.end,
124
+ refName: query.refName,
125
+ });
126
+ if (aggr) {
127
+ parentAggregation[aggr].push(f);
119
128
  }
120
129
  else {
121
- if ((0, util_1.doesIntersect2)(feat.start, feat.end, originalQuery.start, originalQuery.end)) {
130
+ if ((0, util_1.doesIntersect2)(f.start, f.end, originalQuery.start, originalQuery.end)) {
122
131
  observer.next(new util_1.SimpleFeature({
123
132
  id: `${this.id}-${uniqueId}`,
124
- data: {
125
- ...rest,
126
- uniqueId,
127
- type,
128
- start: feat.start,
129
- score: scoreColumn ? +data[scoreColumn] : score,
130
- end: feat.end,
131
- refName: query.refName,
132
- subfeatures,
133
- },
133
+ data: f,
134
134
  }));
135
135
  }
136
136
  }
@@ -159,7 +159,12 @@ class BigBedAdapter extends BaseAdapter_1.BaseFeatureDataAdapter {
159
159
  getFeatures(query, opts = {}) {
160
160
  return (0, rxjs_1.ObservableCreate)(async (observer) => {
161
161
  try {
162
- await this.getFeaturesHelper(query, opts, observer, true);
162
+ await this.getFeaturesHelper({
163
+ query,
164
+ opts,
165
+ observer,
166
+ allowRedispatch: true,
167
+ });
163
168
  }
164
169
  catch (e) {
165
170
  observer.error(e);
@@ -0,0 +1,31 @@
1
+ export declare function isBedMethylFeature({ splitLine, start, end, }: {
2
+ splitLine: string[];
3
+ start: number;
4
+ end: number;
5
+ }): boolean;
6
+ export declare function generateBedMethylFeature({ line, uniqueId, refName, start, end, }: {
7
+ line: string;
8
+ uniqueId: string;
9
+ refName: string;
10
+ start: number;
11
+ end: number;
12
+ }): {
13
+ uniqueId: string;
14
+ refName: string;
15
+ start: number;
16
+ end: number;
17
+ code: string | undefined;
18
+ score: string | undefined;
19
+ strand: string | undefined;
20
+ color: string | undefined;
21
+ source: string | undefined;
22
+ n_valid_cov: string | undefined;
23
+ fraction_modified: string | undefined;
24
+ n_mod: string | undefined;
25
+ n_canonical: string | undefined;
26
+ n_other_mod: string | undefined;
27
+ n_delete: string | undefined;
28
+ n_fail: string | undefined;
29
+ n_diff: string | undefined;
30
+ n_nocall: string | undefined;
31
+ };
@@ -0,0 +1,32 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.isBedMethylFeature = isBedMethylFeature;
4
+ exports.generateBedMethylFeature = generateBedMethylFeature;
5
+ function isBedMethylFeature({ splitLine, start, end, }) {
6
+ return +(splitLine[6] || 0) === start && +(splitLine[7] || 0) === end;
7
+ }
8
+ function generateBedMethylFeature({ line, uniqueId, refName, start, end, }) {
9
+ // see
10
+ // https://github.com/nanoporetech/modkit?tab=readme-ov-file#description-of-bedmethyl-output
11
+ const [, , , code, , strand, , , color, n_valid_cov, fraction_modified, n_mod, n_canonical, n_other_mod, n_delete, n_fail, n_diff, n_nocall,] = line.split('\t');
12
+ return {
13
+ uniqueId,
14
+ refName,
15
+ start,
16
+ end,
17
+ code,
18
+ score: fraction_modified,
19
+ strand,
20
+ color,
21
+ source: code,
22
+ n_valid_cov,
23
+ fraction_modified,
24
+ n_mod,
25
+ n_canonical,
26
+ n_other_mod,
27
+ n_delete,
28
+ n_fail,
29
+ n_diff,
30
+ n_nocall,
31
+ };
32
+ }
@@ -0,0 +1,51 @@
1
+ export declare function isRepeatMaskerDescriptionField(desc?: string): desc is string;
2
+ export declare function generateRepeatMaskerFeature({ uniqueId, refName, start, end, description, ...rest }: {
3
+ uniqueId: string;
4
+ refName: string;
5
+ start: number;
6
+ end: number;
7
+ description: string;
8
+ [key: string]: unknown;
9
+ }): {
10
+ uniqueId: string;
11
+ refName: string;
12
+ start: number;
13
+ end: number;
14
+ bitsw_score: string | undefined;
15
+ percent_div: string | undefined;
16
+ percent_del: string | undefined;
17
+ percent_ins: string | undefined;
18
+ query_chr: string | undefined;
19
+ query_begin: string | undefined;
20
+ query_end: string | undefined;
21
+ query_remaining: string | undefined;
22
+ orientation: string | undefined;
23
+ matching_repeat_name: string | undefined;
24
+ matching_repeat_class: string | undefined;
25
+ matching_repeat_begin: string | undefined;
26
+ matching_repeat_end: string | undefined;
27
+ matching_repeat_remaining: string | undefined;
28
+ repeat_id: string | undefined;
29
+ description?: undefined;
30
+ } | {
31
+ uniqueId: string;
32
+ refName: string;
33
+ start: number;
34
+ end: number;
35
+ description: undefined;
36
+ bitsw_score?: undefined;
37
+ percent_div?: undefined;
38
+ percent_del?: undefined;
39
+ percent_ins?: undefined;
40
+ query_chr?: undefined;
41
+ query_begin?: undefined;
42
+ query_end?: undefined;
43
+ query_remaining?: undefined;
44
+ orientation?: undefined;
45
+ matching_repeat_name?: undefined;
46
+ matching_repeat_class?: undefined;
47
+ matching_repeat_begin?: undefined;
48
+ matching_repeat_end?: undefined;
49
+ matching_repeat_remaining?: undefined;
50
+ repeat_id?: undefined;
51
+ };
@@ -0,0 +1,41 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.isRepeatMaskerDescriptionField = isRepeatMaskerDescriptionField;
4
+ exports.generateRepeatMaskerFeature = generateRepeatMaskerFeature;
5
+ function isRepeatMaskerDescriptionField(desc) {
6
+ const ret = desc === null || desc === void 0 ? void 0 : desc.trim().split(' ');
7
+ return [0, 1, 2, 3, 5, 6].every(s => (ret === null || ret === void 0 ? void 0 : ret[s]) !== undefined ? !Number.isNaN(+ret[s]) : false);
8
+ }
9
+ function makeRepeatTrackDescription(description) {
10
+ if (isRepeatMaskerDescriptionField(description)) {
11
+ const [bitsw_score, percent_div, percent_del, percent_ins, query_chr, query_begin, query_end, query_remaining, orientation, matching_repeat_name, matching_repeat_class, matching_repeat_begin, matching_repeat_end, matching_repeat_remaining, repeat_id,] = description.trim().split(' ');
12
+ return {
13
+ bitsw_score,
14
+ percent_div,
15
+ percent_del,
16
+ percent_ins,
17
+ query_chr,
18
+ query_begin,
19
+ query_end,
20
+ query_remaining,
21
+ orientation,
22
+ matching_repeat_name,
23
+ matching_repeat_class,
24
+ matching_repeat_begin,
25
+ matching_repeat_end,
26
+ matching_repeat_remaining,
27
+ repeat_id,
28
+ };
29
+ }
30
+ return { description };
31
+ }
32
+ function generateRepeatMaskerFeature({ uniqueId, refName, start, end, description, ...rest }) {
33
+ return {
34
+ ...rest,
35
+ ...makeRepeatTrackDescription(description),
36
+ uniqueId,
37
+ refName,
38
+ start,
39
+ end,
40
+ };
41
+ }
@@ -0,0 +1,15 @@
1
+ import { MinimalFeature, TranscriptFeat } from './types';
2
+ export declare function isUcscTranscript({ thickStart, blockCount, strand, }: {
3
+ thickStart?: number;
4
+ blockCount?: number;
5
+ strand?: number;
6
+ }): boolean | 0 | undefined;
7
+ export declare function generateUcscTranscript(data: TranscriptFeat): {
8
+ uniqueId: string;
9
+ strand: number;
10
+ type: string;
11
+ refName: string;
12
+ subfeatures: MinimalFeature[];
13
+ start: number;
14
+ end: number;
15
+ };
@@ -0,0 +1,101 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.isUcscTranscript = isUcscTranscript;
4
+ exports.generateUcscTranscript = generateUcscTranscript;
5
+ function isUcscTranscript({ thickStart, blockCount, strand, }) {
6
+ return thickStart && blockCount && strand !== 0;
7
+ }
8
+ function generateUcscTranscript(data) {
9
+ const { strand = 0, chrom: _1, chromStart: _2, chromEnd: _3, chromStarts, blockStarts, blockSizes, uniqueId, ...rest } = data;
10
+ const { subfeatures: oldSubfeatures, thickStart, thickEnd, blockCount, refName, ...rest2 } = rest;
11
+ const subfeatures = [];
12
+ const feats = oldSubfeatures
13
+ .filter(child => child.type === 'block')
14
+ .sort((a, b) => a.start - b.start);
15
+ for (const block of feats) {
16
+ const start = block.start;
17
+ const end = block.end;
18
+ if (thickStart >= end) {
19
+ // left-side UTR
20
+ subfeatures.push({
21
+ type: `${strand > 0 ? 'five' : 'three'}_prime_UTR`,
22
+ start,
23
+ end,
24
+ refName,
25
+ });
26
+ }
27
+ else if (thickStart > start && thickStart < end && thickEnd >= end) {
28
+ // UTR | CDS
29
+ subfeatures.push({
30
+ type: `${strand > 0 ? 'five' : 'three'}_prime_UTR`,
31
+ start,
32
+ end: thickStart,
33
+ refName,
34
+ }, {
35
+ type: 'CDS',
36
+ start: thickStart,
37
+ end,
38
+ refName,
39
+ });
40
+ }
41
+ else if (thickStart <= start && thickEnd >= end) {
42
+ // CDS
43
+ subfeatures.push({
44
+ type: 'CDS',
45
+ start,
46
+ end,
47
+ refName,
48
+ });
49
+ }
50
+ else if (thickStart > start && thickStart < end && thickEnd < end) {
51
+ // UTR | CDS | UTR
52
+ subfeatures.push({
53
+ type: `${strand > 0 ? 'five' : 'three'}_prime_UTR`,
54
+ start,
55
+ end: thickStart,
56
+ refName,
57
+ }, {
58
+ type: 'CDS',
59
+ start: thickStart,
60
+ end: thickEnd,
61
+ refName,
62
+ }, {
63
+ type: `${strand > 0 ? 'three' : 'five'}_prime_UTR`,
64
+ start: thickEnd,
65
+ end,
66
+ refName,
67
+ });
68
+ }
69
+ else if (thickStart <= start && thickEnd > start && thickEnd < end) {
70
+ // CDS | UTR
71
+ subfeatures.push({
72
+ type: 'CDS',
73
+ start,
74
+ end: thickEnd,
75
+ refName,
76
+ }, {
77
+ type: `${strand > 0 ? 'three' : 'five'}_prime_UTR`,
78
+ start: thickEnd,
79
+ end,
80
+ refName,
81
+ });
82
+ }
83
+ else if (thickEnd <= start) {
84
+ // right-side UTR
85
+ subfeatures.push({
86
+ type: `${strand > 0 ? 'three' : 'five'}_prime_UTR`,
87
+ start,
88
+ end,
89
+ refName,
90
+ });
91
+ }
92
+ }
93
+ return {
94
+ ...rest2,
95
+ uniqueId,
96
+ strand,
97
+ type: 'mRNA',
98
+ refName,
99
+ subfeatures,
100
+ };
101
+ }
@@ -0,0 +1,18 @@
1
+ export interface MinimalFeature {
2
+ type: string;
3
+ start: number;
4
+ end: number;
5
+ refName: string;
6
+ [key: string]: unknown;
7
+ }
8
+ export interface TranscriptFeat extends MinimalFeature {
9
+ uniqueId: string;
10
+ thickStart: number;
11
+ thickEnd: number;
12
+ blockCount: number;
13
+ blockSizes: number[];
14
+ chromStarts: number[];
15
+ refName: string;
16
+ strand?: number;
17
+ subfeatures: MinimalFeature[];
18
+ }
package/dist/types.js ADDED
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });