@jbrowse/plugin-bed 3.2.0 → 3.4.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 (33) hide show
  1. package/dist/BedAdapter/BedAdapter.d.ts +0 -1
  2. package/dist/BedAdapter/BedAdapter.js +30 -21
  3. package/dist/BedAdapter/configSchema.d.ts +1 -0
  4. package/dist/BedAdapter/configSchema.js +1 -0
  5. package/dist/BedGraphAdapter/BedGraphAdapter.d.ts +0 -1
  6. package/dist/BedGraphAdapter/BedGraphAdapter.js +0 -1
  7. package/dist/BedGraphTabixAdapter/BedGraphTabixAdapter.d.ts +0 -1
  8. package/dist/BedGraphTabixAdapter/BedGraphTabixAdapter.js +0 -1
  9. package/dist/BedTabixAdapter/BedTabixAdapter.d.ts +0 -1
  10. package/dist/BedTabixAdapter/BedTabixAdapter.js +0 -1
  11. package/dist/BedpeAdapter/BedpeAdapter.d.ts +0 -1
  12. package/dist/BedpeAdapter/BedpeAdapter.js +0 -1
  13. package/dist/BedpeAdapter/configSchema.d.ts +1 -0
  14. package/dist/BedpeAdapter/configSchema.js +1 -0
  15. package/dist/BigBedAdapter/BigBedAdapter.d.ts +3 -1
  16. package/dist/BigBedAdapter/BigBedAdapter.js +37 -35
  17. package/esm/BedAdapter/BedAdapter.d.ts +0 -1
  18. package/esm/BedAdapter/BedAdapter.js +31 -22
  19. package/esm/BedAdapter/configSchema.d.ts +1 -0
  20. package/esm/BedAdapter/configSchema.js +1 -0
  21. package/esm/BedGraphAdapter/BedGraphAdapter.d.ts +0 -1
  22. package/esm/BedGraphAdapter/BedGraphAdapter.js +0 -1
  23. package/esm/BedGraphTabixAdapter/BedGraphTabixAdapter.d.ts +0 -1
  24. package/esm/BedGraphTabixAdapter/BedGraphTabixAdapter.js +0 -1
  25. package/esm/BedTabixAdapter/BedTabixAdapter.d.ts +0 -1
  26. package/esm/BedTabixAdapter/BedTabixAdapter.js +0 -1
  27. package/esm/BedpeAdapter/BedpeAdapter.d.ts +0 -1
  28. package/esm/BedpeAdapter/BedpeAdapter.js +0 -1
  29. package/esm/BedpeAdapter/configSchema.d.ts +1 -0
  30. package/esm/BedpeAdapter/configSchema.js +1 -0
  31. package/esm/BigBedAdapter/BigBedAdapter.d.ts +3 -1
  32. package/esm/BigBedAdapter/BigBedAdapter.js +37 -35
  33. package/package.json +6 -6
@@ -33,5 +33,4 @@ export default class BedAdapter extends BaseFeatureDataAdapter {
33
33
  private loadFeatureIntervalTreeHelper;
34
34
  loadFeatureIntervalTree(refName: string): Promise<IntervalTree<any> | undefined>;
35
35
  getFeatures(query: Region, opts?: BaseOptions): import("rxjs").Observable<Feature>;
36
- freeResources(): void;
37
36
  }
@@ -15,31 +15,41 @@ class BedAdapter extends BaseAdapter_1.BaseFeatureDataAdapter {
15
15
  super(...arguments);
16
16
  this.intervalTrees = {};
17
17
  }
18
- async loadDataP(opts = {}) {
19
- const pm = this.pluginManager;
18
+ async loadDataP(opts) {
19
+ const { statusCallback = () => { } } = opts || {};
20
20
  const bedLoc = this.getConf('bedLocation');
21
- const buffer = await (0, util_1.fetchAndMaybeUnzip)((0, io_1.openLocation)(bedLoc, pm), opts);
22
- if (buffer.length > 536870888) {
23
- throw new Error('Data exceeds maximum string length (512MB)');
24
- }
25
- const data = new TextDecoder('utf8', { fatal: true }).decode(buffer);
26
- const lines = data.split(/\n|\r\n|\r/).filter(f => !!f);
21
+ const buffer = await (0, util_1.fetchAndMaybeUnzip)((0, io_1.openLocation)(bedLoc, this.pluginManager), opts);
27
22
  const headerLines = [];
28
- let i = 0;
29
- for (; i < lines.length && lines[i].startsWith('#'); i++) {
30
- headerLines.push(lines[i]);
31
- }
32
- const header = headerLines.join('\n');
33
23
  const features = {};
34
- for (; i < lines.length; i++) {
35
- const line = lines[i];
36
- const tab = line.indexOf('\t');
37
- const refName = line.slice(0, tab);
38
- if (!features[refName]) {
39
- features[refName] = [];
24
+ let blockStart = 0;
25
+ let i = 0;
26
+ const decoder = new TextDecoder('utf8');
27
+ while (blockStart < buffer.length) {
28
+ const n = buffer.indexOf(10, blockStart);
29
+ const b = n === -1 ? buffer.subarray(blockStart) : buffer.subarray(blockStart, n);
30
+ const line = decoder.decode(b).trim();
31
+ if (line) {
32
+ if (line.startsWith('#')) {
33
+ headerLines.push(line);
34
+ }
35
+ else if (line.startsWith('>')) {
36
+ break;
37
+ }
38
+ else {
39
+ const tab = line.indexOf('\t');
40
+ const refName = line.slice(0, tab);
41
+ if (!features[refName]) {
42
+ features[refName] = [];
43
+ }
44
+ features[refName].push(line);
45
+ }
40
46
  }
41
- features[refName].push(line);
47
+ if (i++ % 10000 === 0) {
48
+ statusCallback(`Loading ${(0, util_1.getProgressDisplayStr)(blockStart, buffer.length)}`);
49
+ }
50
+ blockStart = n + 1;
42
51
  }
52
+ const header = headerLines.join('\n');
43
53
  const autoSql = this.getConf('autoSql');
44
54
  const parser = new bed_1.default({ autoSql });
45
55
  const columnNames = this.getConf('columnNames');
@@ -136,7 +146,6 @@ class BedAdapter extends BaseAdapter_1.BaseFeatureDataAdapter {
136
146
  observer.complete();
137
147
  }, opts.stopToken);
138
148
  }
139
- freeResources() { }
140
149
  }
141
150
  BedAdapter.capabilities = ['getFeatures', 'getRefNames'];
142
151
  exports.default = BedAdapter;
@@ -1,6 +1,7 @@
1
1
  declare const BedAdapter: import("@jbrowse/core/configuration/configurationSchema").ConfigurationSchemaType<{
2
2
  bedLocation: {
3
3
  type: string;
4
+ description: string;
4
5
  defaultValue: {
5
6
  uri: string;
6
7
  locationType: string;
@@ -5,6 +5,7 @@ function x() { }
5
5
  const BedAdapter = (0, configuration_1.ConfigurationSchema)('BedAdapter', {
6
6
  bedLocation: {
7
7
  type: 'fileLocation',
8
+ description: 'path to bed file, also allows gzipped bed',
8
9
  defaultValue: {
9
10
  uri: '/path/to/my.bed.gz',
10
11
  locationType: 'UriLocation',
@@ -20,5 +20,4 @@ export default class BedGraphAdapter extends BaseFeatureDataAdapter {
20
20
  columnNames: string[];
21
21
  }>;
22
22
  getFeatures(query: Region, _opts?: BaseOptions): import("rxjs").Observable<Feature>;
23
- freeResources(): void;
24
23
  }
@@ -125,6 +125,5 @@ class BedGraphAdapter extends BaseAdapter_1.BaseFeatureDataAdapter {
125
125
  observer.complete();
126
126
  });
127
127
  }
128
- freeResources() { }
129
128
  }
130
129
  exports.default = BedGraphAdapter;
@@ -14,5 +14,4 @@ export default class BedGraphAdapter extends BaseFeatureDataAdapter {
14
14
  getRefNames(opts?: BaseOptions): Promise<string[]>;
15
15
  getHeader(): Promise<string>;
16
16
  getFeatures(query: Region, opts?: BaseOptions): import("rxjs").Observable<Feature>;
17
- freeResources(): void;
18
17
  }
@@ -103,6 +103,5 @@ class BedGraphAdapter extends BaseAdapter_1.BaseFeatureDataAdapter {
103
103
  observer.complete();
104
104
  });
105
105
  }
106
- freeResources() { }
107
106
  }
108
107
  exports.default = BedGraphAdapter;
@@ -40,5 +40,4 @@ export default class BedTabixAdapter extends BaseFeatureDataAdapter {
40
40
  }>;
41
41
  getNames(): Promise<string[] | undefined>;
42
42
  getFeatures(query: Region, opts?: BaseOptions): import("rxjs").Observable<Feature>;
43
- freeResources(): void;
44
43
  }
@@ -99,7 +99,6 @@ class BedTabixAdapter extends BaseAdapter_1.BaseFeatureDataAdapter {
99
99
  observer.complete();
100
100
  }, stopToken);
101
101
  }
102
- freeResources() { }
103
102
  }
104
103
  BedTabixAdapter.capabilities = ['getFeatures', 'getRefNames'];
105
104
  exports.default = BedTabixAdapter;
@@ -19,5 +19,4 @@ export default class BedpeAdapter extends BaseFeatureDataAdapter {
19
19
  private loadFeatureTreeP;
20
20
  private loadFeatureTree;
21
21
  getFeatures(query: Region, opts?: BaseOptions): import("rxjs").Observable<Feature>;
22
- freeResources(): void;
23
22
  }
@@ -109,7 +109,6 @@ class BedpeAdapter extends BaseAdapter_1.BaseFeatureDataAdapter {
109
109
  observer.complete();
110
110
  }, opts.stopToken);
111
111
  }
112
- freeResources() { }
113
112
  }
114
113
  BedpeAdapter.capabilities = ['getFeatures', 'getRefNames'];
115
114
  exports.default = BedpeAdapter;
@@ -1,6 +1,7 @@
1
1
  declare const BedpeAdapter: import("@jbrowse/core/configuration/configurationSchema").ConfigurationSchemaType<{
2
2
  bedpeLocation: {
3
3
  type: string;
4
+ description: string;
4
5
  defaultValue: {
5
6
  uri: string;
6
7
  locationType: string;
@@ -5,6 +5,7 @@ function x() { }
5
5
  const BedpeAdapter = (0, configuration_1.ConfigurationSchema)('BedpeAdapter', {
6
6
  bedpeLocation: {
7
7
  type: 'fileLocation',
8
+ description: 'can be plaintext or gzipped, not indexed so loaded into memory on startup',
8
9
  defaultValue: {
9
10
  uri: '/path/to/my.bedpe.gz',
10
11
  locationType: 'UriLocation',
@@ -32,6 +32,9 @@ export default class BigBedAdapter extends BaseFeatureDataAdapter {
32
32
  [k: string]: string;
33
33
  };
34
34
  }>;
35
+ getMetadata(opts?: BaseOptions): Promise<{
36
+ [k: string]: string;
37
+ }>;
35
38
  getFeaturesHelper({ query, opts, observer, allowRedispatch, originalQuery, }: {
36
39
  query: Region;
37
40
  opts: BaseOptions;
@@ -40,5 +43,4 @@ export default class BigBedAdapter extends BaseFeatureDataAdapter {
40
43
  originalQuery?: Region;
41
44
  }): Promise<void>;
42
45
  getFeatures(query: Region, opts?: BaseOptions): import("rxjs").Observable<Feature>;
43
- freeResources(): void;
44
46
  }
@@ -78,9 +78,14 @@ class BigBedAdapter extends BaseAdapter_1.BaseFeatureDataAdapter {
78
78
  version,
79
79
  fileType,
80
80
  autoSql: { ...rest },
81
- fields: Object.fromEntries(fields.map(({ name, comment }) => [name, comment])),
81
+ fields: await this.getMetadata(opts),
82
82
  };
83
83
  }
84
+ async getMetadata(opts) {
85
+ const { parser } = await this.configure(opts);
86
+ const { fields } = parser.autoSql;
87
+ return Object.fromEntries(fields.map(({ name, comment }) => [name, comment]));
88
+ }
84
89
  async getFeaturesHelper({ query, opts, observer, allowRedispatch, originalQuery = query, }) {
85
90
  var _a;
86
91
  const { statusCallback = () => { } } = opts;
@@ -90,38 +95,8 @@ class BigBedAdapter extends BaseAdapter_1.BaseFeatureDataAdapter {
90
95
  const feats = await (0, util_1.updateStatus)('Downloading features', statusCallback, () => bigbed.getFeatures(query.refName, query.start, query.end, {
91
96
  basesPerSpan: query.end - query.start,
92
97
  }));
93
- if (allowRedispatch && feats.length) {
94
- let minStart = Number.POSITIVE_INFINITY;
95
- let maxEnd = Number.NEGATIVE_INFINITY;
96
- let hasAnyAggregationField = false;
97
- for (const feat of feats) {
98
- if (feat.start < minStart) {
99
- minStart = feat.start;
100
- }
101
- if (feat.end > maxEnd) {
102
- maxEnd = feat.end;
103
- }
104
- if (feat[aggregateField]) {
105
- hasAnyAggregationField = true;
106
- }
107
- }
108
- if (hasAnyAggregationField &&
109
- (maxEnd > query.end || minStart < query.start)) {
110
- await this.getFeaturesHelper({
111
- query: {
112
- ...query,
113
- start: minStart - 500000,
114
- end: maxEnd + 500000,
115
- },
116
- opts,
117
- observer,
118
- allowRedispatch: false,
119
- originalQuery: query,
120
- });
121
- return;
122
- }
123
- }
124
98
  const parentAggregation = {};
99
+ const parentAggregationFlat = [];
125
100
  if (feats.some(f => f.uniqueId === undefined)) {
126
101
  throw new Error('found uniqueId undefined');
127
102
  }
@@ -136,7 +111,8 @@ class BigBedAdapter extends BaseAdapter_1.BaseFeatureDataAdapter {
136
111
  uniqueId: feat.uniqueId,
137
112
  });
138
113
  const aggr = data[aggregateField];
139
- if (!parentAggregation[aggr]) {
114
+ const aggrIsNotNone = aggr && aggr !== 'none';
115
+ if (aggrIsNotNone && !parentAggregation[aggr]) {
140
116
  parentAggregation[aggr] = [];
141
117
  }
142
118
  const { uniqueId, type, chrom, chromStart, chromEnd, description, chromStarts: chromStarts2, blockStarts: blockStarts2, blockSizes: blockSizes2, score: score2, blockCount, thickStart, thickEnd, strand, ...rest } = data;
@@ -150,8 +126,9 @@ class BigBedAdapter extends BaseAdapter_1.BaseFeatureDataAdapter {
150
126
  end: feat.end,
151
127
  refName: query.refName,
152
128
  });
153
- if (aggr) {
129
+ if (aggrIsNotNone) {
154
130
  parentAggregation[aggr].push(f);
131
+ parentAggregationFlat.push(f);
155
132
  }
156
133
  else {
157
134
  if ((0, util_1.doesIntersect2)(f.start, f.end, originalQuery.start, originalQuery.end)) {
@@ -162,6 +139,32 @@ class BigBedAdapter extends BaseAdapter_1.BaseFeatureDataAdapter {
162
139
  }
163
140
  }
164
141
  }
142
+ if (allowRedispatch && parentAggregationFlat.length) {
143
+ let minStart = Number.POSITIVE_INFINITY;
144
+ let maxEnd = Number.NEGATIVE_INFINITY;
145
+ for (const feat of parentAggregationFlat) {
146
+ if (feat.start < minStart) {
147
+ minStart = feat.start;
148
+ }
149
+ if (feat.end > maxEnd) {
150
+ maxEnd = feat.end;
151
+ }
152
+ }
153
+ if (maxEnd > query.end || minStart < query.start) {
154
+ await this.getFeaturesHelper({
155
+ query: {
156
+ ...query,
157
+ start: minStart - 500000,
158
+ end: maxEnd + 500000,
159
+ },
160
+ opts,
161
+ observer,
162
+ allowRedispatch: false,
163
+ originalQuery: query,
164
+ });
165
+ return;
166
+ }
167
+ }
165
168
  Object.entries(parentAggregation).map(([name, subfeatures]) => {
166
169
  var _a, _b;
167
170
  const s = (0, util_1.min)(subfeatures.map(f => f.start));
@@ -203,6 +206,5 @@ class BigBedAdapter extends BaseAdapter_1.BaseFeatureDataAdapter {
203
206
  }
204
207
  }, opts.stopToken);
205
208
  }
206
- freeResources() { }
207
209
  }
208
210
  exports.default = BigBedAdapter;
@@ -33,5 +33,4 @@ export default class BedAdapter extends BaseFeatureDataAdapter {
33
33
  private loadFeatureIntervalTreeHelper;
34
34
  loadFeatureIntervalTree(refName: string): Promise<IntervalTree<any> | undefined>;
35
35
  getFeatures(query: Region, opts?: BaseOptions): import("rxjs").Observable<Feature>;
36
- freeResources(): void;
37
36
  }
@@ -1,7 +1,7 @@
1
1
  import IntervalTree from '@flatten-js/interval-tree';
2
2
  import BED from '@gmod/bed';
3
3
  import { BaseFeatureDataAdapter } from '@jbrowse/core/data_adapters/BaseAdapter';
4
- import { SimpleFeature, fetchAndMaybeUnzip } from '@jbrowse/core/util';
4
+ import { SimpleFeature, fetchAndMaybeUnzip, getProgressDisplayStr, } from '@jbrowse/core/util';
5
5
  import { openLocation } from '@jbrowse/core/util/io';
6
6
  import { ObservableCreate } from '@jbrowse/core/util/rxjs';
7
7
  import { featureData } from '../util';
@@ -10,31 +10,41 @@ class BedAdapter extends BaseFeatureDataAdapter {
10
10
  super(...arguments);
11
11
  this.intervalTrees = {};
12
12
  }
13
- async loadDataP(opts = {}) {
14
- const pm = this.pluginManager;
13
+ async loadDataP(opts) {
14
+ const { statusCallback = () => { } } = opts || {};
15
15
  const bedLoc = this.getConf('bedLocation');
16
- const buffer = await fetchAndMaybeUnzip(openLocation(bedLoc, pm), opts);
17
- if (buffer.length > 536870888) {
18
- throw new Error('Data exceeds maximum string length (512MB)');
19
- }
20
- const data = new TextDecoder('utf8', { fatal: true }).decode(buffer);
21
- const lines = data.split(/\n|\r\n|\r/).filter(f => !!f);
16
+ const buffer = await fetchAndMaybeUnzip(openLocation(bedLoc, this.pluginManager), opts);
22
17
  const headerLines = [];
23
- let i = 0;
24
- for (; i < lines.length && lines[i].startsWith('#'); i++) {
25
- headerLines.push(lines[i]);
26
- }
27
- const header = headerLines.join('\n');
28
18
  const features = {};
29
- for (; i < lines.length; i++) {
30
- const line = lines[i];
31
- const tab = line.indexOf('\t');
32
- const refName = line.slice(0, tab);
33
- if (!features[refName]) {
34
- features[refName] = [];
19
+ let blockStart = 0;
20
+ let i = 0;
21
+ const decoder = new TextDecoder('utf8');
22
+ while (blockStart < buffer.length) {
23
+ const n = buffer.indexOf(10, blockStart);
24
+ const b = n === -1 ? buffer.subarray(blockStart) : buffer.subarray(blockStart, n);
25
+ const line = decoder.decode(b).trim();
26
+ if (line) {
27
+ if (line.startsWith('#')) {
28
+ headerLines.push(line);
29
+ }
30
+ else if (line.startsWith('>')) {
31
+ break;
32
+ }
33
+ else {
34
+ const tab = line.indexOf('\t');
35
+ const refName = line.slice(0, tab);
36
+ if (!features[refName]) {
37
+ features[refName] = [];
38
+ }
39
+ features[refName].push(line);
40
+ }
35
41
  }
36
- features[refName].push(line);
42
+ if (i++ % 10000 === 0) {
43
+ statusCallback(`Loading ${getProgressDisplayStr(blockStart, buffer.length)}`);
44
+ }
45
+ blockStart = n + 1;
37
46
  }
47
+ const header = headerLines.join('\n');
38
48
  const autoSql = this.getConf('autoSql');
39
49
  const parser = new BED({ autoSql });
40
50
  const columnNames = this.getConf('columnNames');
@@ -131,7 +141,6 @@ class BedAdapter extends BaseFeatureDataAdapter {
131
141
  observer.complete();
132
142
  }, opts.stopToken);
133
143
  }
134
- freeResources() { }
135
144
  }
136
145
  BedAdapter.capabilities = ['getFeatures', 'getRefNames'];
137
146
  export default BedAdapter;
@@ -1,6 +1,7 @@
1
1
  declare const BedAdapter: import("@jbrowse/core/configuration/configurationSchema").ConfigurationSchemaType<{
2
2
  bedLocation: {
3
3
  type: string;
4
+ description: string;
4
5
  defaultValue: {
5
6
  uri: string;
6
7
  locationType: string;
@@ -3,6 +3,7 @@ function x() { }
3
3
  const BedAdapter = ConfigurationSchema('BedAdapter', {
4
4
  bedLocation: {
5
5
  type: 'fileLocation',
6
+ description: 'path to bed file, also allows gzipped bed',
6
7
  defaultValue: {
7
8
  uri: '/path/to/my.bed.gz',
8
9
  locationType: 'UriLocation',
@@ -20,5 +20,4 @@ export default class BedGraphAdapter extends BaseFeatureDataAdapter {
20
20
  columnNames: string[];
21
21
  }>;
22
22
  getFeatures(query: Region, _opts?: BaseOptions): import("rxjs").Observable<Feature>;
23
- freeResources(): void;
24
23
  }
@@ -120,5 +120,4 @@ export default class BedGraphAdapter extends BaseFeatureDataAdapter {
120
120
  observer.complete();
121
121
  });
122
122
  }
123
- freeResources() { }
124
123
  }
@@ -14,5 +14,4 @@ export default class BedGraphAdapter extends BaseFeatureDataAdapter {
14
14
  getRefNames(opts?: BaseOptions): Promise<string[]>;
15
15
  getHeader(): Promise<string>;
16
16
  getFeatures(query: Region, opts?: BaseOptions): import("rxjs").Observable<Feature>;
17
- freeResources(): void;
18
17
  }
@@ -101,5 +101,4 @@ export default class BedGraphAdapter extends BaseFeatureDataAdapter {
101
101
  observer.complete();
102
102
  });
103
103
  }
104
- freeResources() { }
105
104
  }
@@ -40,5 +40,4 @@ export default class BedTabixAdapter extends BaseFeatureDataAdapter {
40
40
  }>;
41
41
  getNames(): Promise<string[] | undefined>;
42
42
  getFeatures(query: Region, opts?: BaseOptions): import("rxjs").Observable<Feature>;
43
- freeResources(): void;
44
43
  }
@@ -94,7 +94,6 @@ class BedTabixAdapter extends BaseFeatureDataAdapter {
94
94
  observer.complete();
95
95
  }, stopToken);
96
96
  }
97
- freeResources() { }
98
97
  }
99
98
  BedTabixAdapter.capabilities = ['getFeatures', 'getRefNames'];
100
99
  export default BedTabixAdapter;
@@ -19,5 +19,4 @@ export default class BedpeAdapter extends BaseFeatureDataAdapter {
19
19
  private loadFeatureTreeP;
20
20
  private loadFeatureTree;
21
21
  getFeatures(query: Region, opts?: BaseOptions): import("rxjs").Observable<Feature>;
22
- freeResources(): void;
23
22
  }
@@ -104,7 +104,6 @@ class BedpeAdapter extends BaseFeatureDataAdapter {
104
104
  observer.complete();
105
105
  }, opts.stopToken);
106
106
  }
107
- freeResources() { }
108
107
  }
109
108
  BedpeAdapter.capabilities = ['getFeatures', 'getRefNames'];
110
109
  export default BedpeAdapter;
@@ -1,6 +1,7 @@
1
1
  declare const BedpeAdapter: import("@jbrowse/core/configuration/configurationSchema").ConfigurationSchemaType<{
2
2
  bedpeLocation: {
3
3
  type: string;
4
+ description: string;
4
5
  defaultValue: {
5
6
  uri: string;
6
7
  locationType: string;
@@ -3,6 +3,7 @@ function x() { }
3
3
  const BedpeAdapter = ConfigurationSchema('BedpeAdapter', {
4
4
  bedpeLocation: {
5
5
  type: 'fileLocation',
6
+ description: 'can be plaintext or gzipped, not indexed so loaded into memory on startup',
6
7
  defaultValue: {
7
8
  uri: '/path/to/my.bedpe.gz',
8
9
  locationType: 'UriLocation',
@@ -32,6 +32,9 @@ export default class BigBedAdapter extends BaseFeatureDataAdapter {
32
32
  [k: string]: string;
33
33
  };
34
34
  }>;
35
+ getMetadata(opts?: BaseOptions): Promise<{
36
+ [k: string]: string;
37
+ }>;
35
38
  getFeaturesHelper({ query, opts, observer, allowRedispatch, originalQuery, }: {
36
39
  query: Region;
37
40
  opts: BaseOptions;
@@ -40,5 +43,4 @@ export default class BigBedAdapter extends BaseFeatureDataAdapter {
40
43
  originalQuery?: Region;
41
44
  }): Promise<void>;
42
45
  getFeatures(query: Region, opts?: BaseOptions): import("rxjs").Observable<Feature>;
43
- freeResources(): void;
44
46
  }
@@ -73,9 +73,14 @@ export default class BigBedAdapter extends BaseFeatureDataAdapter {
73
73
  version,
74
74
  fileType,
75
75
  autoSql: { ...rest },
76
- fields: Object.fromEntries(fields.map(({ name, comment }) => [name, comment])),
76
+ fields: await this.getMetadata(opts),
77
77
  };
78
78
  }
79
+ async getMetadata(opts) {
80
+ const { parser } = await this.configure(opts);
81
+ const { fields } = parser.autoSql;
82
+ return Object.fromEntries(fields.map(({ name, comment }) => [name, comment]));
83
+ }
79
84
  async getFeaturesHelper({ query, opts, observer, allowRedispatch, originalQuery = query, }) {
80
85
  var _a;
81
86
  const { statusCallback = () => { } } = opts;
@@ -85,38 +90,8 @@ export default class BigBedAdapter extends BaseFeatureDataAdapter {
85
90
  const feats = await updateStatus('Downloading features', statusCallback, () => bigbed.getFeatures(query.refName, query.start, query.end, {
86
91
  basesPerSpan: query.end - query.start,
87
92
  }));
88
- if (allowRedispatch && feats.length) {
89
- let minStart = Number.POSITIVE_INFINITY;
90
- let maxEnd = Number.NEGATIVE_INFINITY;
91
- let hasAnyAggregationField = false;
92
- for (const feat of feats) {
93
- if (feat.start < minStart) {
94
- minStart = feat.start;
95
- }
96
- if (feat.end > maxEnd) {
97
- maxEnd = feat.end;
98
- }
99
- if (feat[aggregateField]) {
100
- hasAnyAggregationField = true;
101
- }
102
- }
103
- if (hasAnyAggregationField &&
104
- (maxEnd > query.end || minStart < query.start)) {
105
- await this.getFeaturesHelper({
106
- query: {
107
- ...query,
108
- start: minStart - 500000,
109
- end: maxEnd + 500000,
110
- },
111
- opts,
112
- observer,
113
- allowRedispatch: false,
114
- originalQuery: query,
115
- });
116
- return;
117
- }
118
- }
119
93
  const parentAggregation = {};
94
+ const parentAggregationFlat = [];
120
95
  if (feats.some(f => f.uniqueId === undefined)) {
121
96
  throw new Error('found uniqueId undefined');
122
97
  }
@@ -131,7 +106,8 @@ export default class BigBedAdapter extends BaseFeatureDataAdapter {
131
106
  uniqueId: feat.uniqueId,
132
107
  });
133
108
  const aggr = data[aggregateField];
134
- if (!parentAggregation[aggr]) {
109
+ const aggrIsNotNone = aggr && aggr !== 'none';
110
+ if (aggrIsNotNone && !parentAggregation[aggr]) {
135
111
  parentAggregation[aggr] = [];
136
112
  }
137
113
  const { uniqueId, type, chrom, chromStart, chromEnd, description, chromStarts: chromStarts2, blockStarts: blockStarts2, blockSizes: blockSizes2, score: score2, blockCount, thickStart, thickEnd, strand, ...rest } = data;
@@ -145,8 +121,9 @@ export default class BigBedAdapter extends BaseFeatureDataAdapter {
145
121
  end: feat.end,
146
122
  refName: query.refName,
147
123
  });
148
- if (aggr) {
124
+ if (aggrIsNotNone) {
149
125
  parentAggregation[aggr].push(f);
126
+ parentAggregationFlat.push(f);
150
127
  }
151
128
  else {
152
129
  if (doesIntersect2(f.start, f.end, originalQuery.start, originalQuery.end)) {
@@ -157,6 +134,32 @@ export default class BigBedAdapter extends BaseFeatureDataAdapter {
157
134
  }
158
135
  }
159
136
  }
137
+ if (allowRedispatch && parentAggregationFlat.length) {
138
+ let minStart = Number.POSITIVE_INFINITY;
139
+ let maxEnd = Number.NEGATIVE_INFINITY;
140
+ for (const feat of parentAggregationFlat) {
141
+ if (feat.start < minStart) {
142
+ minStart = feat.start;
143
+ }
144
+ if (feat.end > maxEnd) {
145
+ maxEnd = feat.end;
146
+ }
147
+ }
148
+ if (maxEnd > query.end || minStart < query.start) {
149
+ await this.getFeaturesHelper({
150
+ query: {
151
+ ...query,
152
+ start: minStart - 500000,
153
+ end: maxEnd + 500000,
154
+ },
155
+ opts,
156
+ observer,
157
+ allowRedispatch: false,
158
+ originalQuery: query,
159
+ });
160
+ return;
161
+ }
162
+ }
160
163
  Object.entries(parentAggregation).map(([name, subfeatures]) => {
161
164
  var _a, _b;
162
165
  const s = min(subfeatures.map(f => f.start));
@@ -198,5 +201,4 @@ export default class BigBedAdapter extends BaseFeatureDataAdapter {
198
201
  }
199
202
  }, opts.stopToken);
200
203
  }
201
- freeResources() { }
202
204
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jbrowse/plugin-bed",
3
- "version": "3.2.0",
3
+ "version": "3.4.0",
4
4
  "description": "JBrowse 2 bed adapters, tracks, etc.",
5
5
  "keywords": [
6
6
  "jbrowse",
@@ -37,11 +37,11 @@
37
37
  },
38
38
  "dependencies": {
39
39
  "@flatten-js/interval-tree": "^1.0.15",
40
- "@gmod/bbi": "^6.0.0",
40
+ "@gmod/bbi": "^7.0.0",
41
41
  "@gmod/bed": "^2.1.2",
42
- "@gmod/bgzf-filehandle": "^2.0.1",
43
- "@gmod/tabix": "^2.0.0",
44
- "@jbrowse/core": "^3.2.0",
42
+ "@gmod/bgzf-filehandle": "^3.0.2",
43
+ "@gmod/tabix": "^3.0.1",
44
+ "@jbrowse/core": "^3.4.0",
45
45
  "mobx": "^6.0.0",
46
46
  "mobx-react": "^9.0.0",
47
47
  "mobx-state-tree": "^5.0.0",
@@ -53,5 +53,5 @@
53
53
  "distModule": "esm/index.js",
54
54
  "srcModule": "src/index.ts",
55
55
  "module": "esm/index.js",
56
- "gitHead": "c750e3f56706a490c19ba75abd807fec5e38aebf"
56
+ "gitHead": "a9f1ac35fc2dd810bae92cdaf1fc19995bee4413"
57
57
  }