@jbrowse/text-indexing 2.13.0 → 2.14.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/dist/TextIndexing.d.ts +4 -4
- package/dist/TextIndexing.js +96 -57
- package/dist/index.d.ts +3 -0
- package/dist/index.js +6 -1
- package/dist/types/common.d.ts +7 -9
- package/dist/types/common.js +25 -33
- package/dist/types/gff3Adapter.d.ts +11 -2
- package/dist/types/gff3Adapter.js +15 -14
- package/dist/types/vcfAdapter.d.ts +8 -2
- package/dist/types/vcfAdapter.js +7 -9
- package/dist/util.d.ts +19 -8
- package/esm/TextIndexing.d.ts +4 -4
- package/esm/TextIndexing.js +96 -57
- package/esm/index.d.ts +3 -0
- package/esm/index.js +3 -0
- package/esm/types/common.d.ts +7 -9
- package/esm/types/common.js +25 -33
- package/esm/types/gff3Adapter.d.ts +11 -2
- package/esm/types/gff3Adapter.js +15 -14
- package/esm/types/vcfAdapter.d.ts +8 -2
- package/esm/types/vcfAdapter.js +7 -9
- package/esm/util.d.ts +19 -8
- package/package.json +4 -3
package/dist/TextIndexing.d.ts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { Track, indexType } from './util';
|
|
2
2
|
export declare function indexTracks(args: {
|
|
3
3
|
tracks: Track[];
|
|
4
|
-
|
|
4
|
+
outDir?: string;
|
|
5
5
|
signal?: AbortSignal;
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
6
|
+
attributesToIndex?: string[];
|
|
7
|
+
assemblyNames?: string[];
|
|
8
|
+
featureTypesToExclude?: string[];
|
|
9
9
|
indexType?: indexType;
|
|
10
10
|
statusCallback: (message: string) => void;
|
|
11
11
|
}): Promise<never[]>;
|
package/dist/TextIndexing.js
CHANGED
|
@@ -13,17 +13,32 @@ const common_1 = require("./types/common");
|
|
|
13
13
|
const ixixx_1 = require("ixixx");
|
|
14
14
|
const util_1 = require("@jbrowse/core/util");
|
|
15
15
|
async function indexTracks(args) {
|
|
16
|
-
const { tracks,
|
|
16
|
+
const { tracks, outDir, attributesToIndex, featureTypesToExclude, assemblyNames, indexType, statusCallback, signal, } = args;
|
|
17
17
|
const idxType = indexType || 'perTrack';
|
|
18
18
|
(0, util_1.checkAbortSignal)(signal);
|
|
19
19
|
await (idxType === 'perTrack'
|
|
20
|
-
? perTrackIndex(
|
|
21
|
-
|
|
20
|
+
? perTrackIndex({
|
|
21
|
+
tracks,
|
|
22
|
+
statusCallback,
|
|
23
|
+
outDir,
|
|
24
|
+
attributesToIndex,
|
|
25
|
+
featureTypesToExclude,
|
|
26
|
+
signal,
|
|
27
|
+
})
|
|
28
|
+
: aggregateIndex({
|
|
29
|
+
tracks,
|
|
30
|
+
statusCallback,
|
|
31
|
+
outDir,
|
|
32
|
+
attributesToIndex,
|
|
33
|
+
assemblyNames,
|
|
34
|
+
featureTypesToExclude,
|
|
35
|
+
signal,
|
|
36
|
+
}));
|
|
22
37
|
(0, util_1.checkAbortSignal)(signal);
|
|
23
38
|
return [];
|
|
24
39
|
}
|
|
25
|
-
async function perTrackIndex(tracks, statusCallback,
|
|
26
|
-
const outFlag =
|
|
40
|
+
async function perTrackIndex({ tracks, statusCallback, outDir: paramOutDir, attributesToIndex = ['Name', 'ID'], featureTypesToExclude = ['exon', 'CDS'], signal, }) {
|
|
41
|
+
const outFlag = paramOutDir || '.';
|
|
27
42
|
const isDir = fs_1.default.lstatSync(outFlag).isDirectory();
|
|
28
43
|
const confFilePath = isDir ? path_1.default.join(outFlag, 'config.json') : outFlag;
|
|
29
44
|
const outDir = path_1.default.dirname(confFilePath);
|
|
@@ -32,22 +47,24 @@ async function perTrackIndex(tracks, statusCallback, outLocation, attributes, ex
|
|
|
32
47
|
fs_1.default.mkdirSync(trixDir);
|
|
33
48
|
}
|
|
34
49
|
// default settings
|
|
35
|
-
const attrs = attributes || ['Name', 'ID'];
|
|
36
|
-
const excludeTypes = exclude || ['exon', 'CDS'];
|
|
37
|
-
const force = true;
|
|
38
50
|
const supportedTracks = tracks.filter(track => { var _a; return (0, util_1.isSupportedIndexingAdapter)((_a = track.adapter) === null || _a === void 0 ? void 0 : _a.type); });
|
|
39
51
|
for (const trackConfig of supportedTracks) {
|
|
40
|
-
const {
|
|
52
|
+
const { trackId, assemblyNames } = trackConfig;
|
|
41
53
|
const id = `${trackId}-index`;
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
54
|
+
await indexDriver({
|
|
55
|
+
tracks: [trackConfig],
|
|
56
|
+
outDir,
|
|
57
|
+
attributesToIndex,
|
|
58
|
+
name: id,
|
|
59
|
+
featureTypesToExclude,
|
|
60
|
+
assemblyNames,
|
|
61
|
+
statusCallback,
|
|
62
|
+
signal,
|
|
63
|
+
});
|
|
47
64
|
}
|
|
48
65
|
}
|
|
49
|
-
async function aggregateIndex(tracks, statusCallback,
|
|
50
|
-
const outFlag =
|
|
66
|
+
async function aggregateIndex({ tracks, statusCallback, outDir: paramOutDir, attributesToIndex = ['Name', 'ID'], featureTypesToExclude = ['exon', 'CDS'], signal, assemblyNames, }) {
|
|
67
|
+
const outFlag = paramOutDir || '.';
|
|
51
68
|
const isDir = fs_1.default.lstatSync(outFlag).isDirectory();
|
|
52
69
|
const confFilePath = isDir ? path_1.default.join(outFlag, 'config.json') : outFlag;
|
|
53
70
|
const outDir = path_1.default.dirname(confFilePath);
|
|
@@ -55,70 +72,92 @@ async function aggregateIndex(tracks, statusCallback, outLocation, attributes, a
|
|
|
55
72
|
if (!fs_1.default.existsSync(trixDir)) {
|
|
56
73
|
fs_1.default.mkdirSync(trixDir);
|
|
57
74
|
}
|
|
58
|
-
if (!
|
|
75
|
+
if (!assemblyNames) {
|
|
59
76
|
throw new Error('No assemblies passed. Assmeblies required for aggregate indexes');
|
|
60
77
|
}
|
|
61
|
-
for (const asm of
|
|
62
|
-
|
|
63
|
-
const id = asm + '-index';
|
|
64
|
-
// default settings
|
|
65
|
-
const attrs = attributes || ['Name', 'ID'];
|
|
66
|
-
const excludeTypes = exclude || ['exon', 'CDS'];
|
|
67
|
-
// const force = true
|
|
68
|
-
const quiet = true;
|
|
69
|
-
// supported tracks for given assembly
|
|
78
|
+
for (const asm of assemblyNames) {
|
|
79
|
+
const id = `${asm}-index`;
|
|
70
80
|
const supportedTracks = tracks
|
|
71
81
|
.filter(track => { var _a; return (0, util_1.isSupportedIndexingAdapter)((_a = track.adapter) === null || _a === void 0 ? void 0 : _a.type); })
|
|
72
82
|
.filter(track => (asm ? track.assemblyNames.includes(asm) : true));
|
|
73
|
-
await indexDriver(
|
|
83
|
+
await indexDriver({
|
|
84
|
+
tracks: supportedTracks,
|
|
85
|
+
outDir: outDir,
|
|
86
|
+
attributesToIndex,
|
|
87
|
+
name: id,
|
|
88
|
+
featureTypesToExclude,
|
|
89
|
+
assemblyNames: [asm],
|
|
90
|
+
statusCallback,
|
|
91
|
+
signal,
|
|
92
|
+
});
|
|
74
93
|
}
|
|
75
94
|
}
|
|
76
|
-
async function indexDriver(tracks,
|
|
77
|
-
const readable = stream_1.Readable.from(indexFiles(
|
|
95
|
+
async function indexDriver({ tracks, outDir, attributesToIndex, name, featureTypesToExclude, assemblyNames, statusCallback, signal, }) {
|
|
96
|
+
const readable = stream_1.Readable.from(indexFiles({
|
|
97
|
+
tracks,
|
|
98
|
+
attributesToIndex,
|
|
99
|
+
outDir,
|
|
100
|
+
featureTypesToExclude,
|
|
101
|
+
statusCallback,
|
|
102
|
+
signal,
|
|
103
|
+
}));
|
|
78
104
|
statusCallback('Indexing files.');
|
|
79
|
-
|
|
105
|
+
await runIxIxx(readable, outDir, name);
|
|
80
106
|
(0, util_1.checkAbortSignal)(signal);
|
|
81
107
|
await (0, common_1.generateMeta)({
|
|
82
108
|
configs: tracks,
|
|
83
|
-
|
|
84
|
-
outDir
|
|
109
|
+
attributesToIndex,
|
|
110
|
+
outDir,
|
|
85
111
|
name,
|
|
86
|
-
|
|
112
|
+
featureTypesToExclude,
|
|
87
113
|
assemblyNames,
|
|
88
114
|
});
|
|
89
115
|
(0, util_1.checkAbortSignal)(signal);
|
|
90
|
-
return ixIxxStream;
|
|
91
116
|
}
|
|
92
|
-
async function* indexFiles(tracks,
|
|
117
|
+
async function* indexFiles({ tracks, attributesToIndex: idx1, outDir, featureTypesToExclude: edx1, statusCallback, }) {
|
|
93
118
|
for (const track of tracks) {
|
|
94
119
|
const { adapter, textSearching } = track;
|
|
95
|
-
const { type } = adapter;
|
|
96
|
-
const { indexingFeatureTypesToExclude:
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
120
|
+
const { type } = adapter || {};
|
|
121
|
+
const { indexingFeatureTypesToExclude: featureTypesToExclude = edx1, indexingAttributes: attributesToIndex = idx1, } = textSearching || {};
|
|
122
|
+
let myTotalBytes;
|
|
123
|
+
if (type === 'Gff3TabixAdapter' || type === 'Gff3Adapter') {
|
|
124
|
+
yield* (0, gff3Adapter_1.indexGff3)({
|
|
125
|
+
config: track,
|
|
126
|
+
attributesToIndex,
|
|
127
|
+
inLocation: getLoc('gffGzLocation', track),
|
|
128
|
+
outDir,
|
|
129
|
+
featureTypesToExclude,
|
|
130
|
+
onStart: totalBytes => {
|
|
131
|
+
myTotalBytes = totalBytes;
|
|
132
|
+
},
|
|
133
|
+
onUpdate: progressBytes => {
|
|
134
|
+
statusCallback(`${progressBytes}/${myTotalBytes}`);
|
|
135
|
+
},
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
else if (type === 'VcfTabixAdapter' || type === 'VcfAdapter') {
|
|
139
|
+
yield* (0, vcfAdapter_1.indexVcf)({
|
|
140
|
+
config: track,
|
|
141
|
+
attributesToIndex,
|
|
142
|
+
inLocation: getLoc('vcfGzLocation', track),
|
|
143
|
+
outDir,
|
|
144
|
+
onStart: totalBytes => {
|
|
145
|
+
myTotalBytes = totalBytes;
|
|
146
|
+
},
|
|
147
|
+
onUpdate: progressBytes => {
|
|
148
|
+
statusCallback(`${progressBytes}/${myTotalBytes}`);
|
|
149
|
+
},
|
|
150
|
+
});
|
|
116
151
|
}
|
|
117
152
|
}
|
|
118
153
|
return;
|
|
119
154
|
}
|
|
120
155
|
function getLoc(attr, config) {
|
|
121
|
-
|
|
156
|
+
var _a;
|
|
157
|
+
const elt = (_a = config.adapter) === null || _a === void 0 ? void 0 : _a[attr];
|
|
158
|
+
if (!elt) {
|
|
159
|
+
throw new Error('none');
|
|
160
|
+
}
|
|
122
161
|
return elt.uri || elt.localPath;
|
|
123
162
|
}
|
|
124
163
|
function runIxIxx(readStream, idxLocation, name) {
|
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -14,7 +14,12 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
14
14
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
15
|
};
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
-
exports.indexTracks = void 0;
|
|
17
|
+
exports.indexVcf = exports.indexGff3 = exports.indexTracks = void 0;
|
|
18
18
|
__exportStar(require("./util"), exports);
|
|
19
|
+
__exportStar(require("./types/common"), exports);
|
|
19
20
|
var TextIndexing_1 = require("./TextIndexing");
|
|
20
21
|
Object.defineProperty(exports, "indexTracks", { enumerable: true, get: function () { return TextIndexing_1.indexTracks; } });
|
|
22
|
+
var gff3Adapter_1 = require("./types/gff3Adapter");
|
|
23
|
+
Object.defineProperty(exports, "indexGff3", { enumerable: true, get: function () { return gff3Adapter_1.indexGff3; } });
|
|
24
|
+
var vcfAdapter_1 = require("./types/vcfAdapter");
|
|
25
|
+
Object.defineProperty(exports, "indexVcf", { enumerable: true, get: function () { return vcfAdapter_1.indexVcf; } });
|
package/dist/types/common.d.ts
CHANGED
|
@@ -5,23 +5,21 @@ export declare function createRemoteStream(urlIn: string): Promise<fetch.Respons
|
|
|
5
5
|
export declare function isURL(FileName: string): boolean;
|
|
6
6
|
export declare function getLocalOrRemoteStream(uri: string, out: string): Promise<{
|
|
7
7
|
totalBytes: number;
|
|
8
|
-
stream: NodeJS.ReadableStream
|
|
8
|
+
stream: NodeJS.ReadableStream;
|
|
9
|
+
} | {
|
|
10
|
+
totalBytes: number;
|
|
11
|
+
stream: fs.ReadStream;
|
|
9
12
|
}>;
|
|
10
13
|
export declare function makeLocation(location: string, protocol: string): UriLocation | LocalPathLocation;
|
|
11
14
|
export declare function guessAdapterFromFileName(filePath: string): Track;
|
|
12
15
|
/**
|
|
13
16
|
* Generates metadata of index given a filename (trackId or assembly)
|
|
14
|
-
* @param name - assembly name or trackId
|
|
15
|
-
* @param attributes - attributes indexed
|
|
16
|
-
* @param include - feature types included from index
|
|
17
|
-
* @param exclude - feature types excluded from index
|
|
18
|
-
* @param configs - list of track
|
|
19
17
|
*/
|
|
20
|
-
export declare function generateMeta({ configs,
|
|
18
|
+
export declare function generateMeta({ configs, attributesToIndex, outDir, name, featureTypesToExclude, assemblyNames, }: {
|
|
21
19
|
configs: Track[];
|
|
22
|
-
|
|
20
|
+
attributesToIndex: string[];
|
|
23
21
|
outDir: string;
|
|
24
22
|
name: string;
|
|
25
|
-
|
|
23
|
+
featureTypesToExclude: string[];
|
|
26
24
|
assemblyNames: string[];
|
|
27
25
|
}): Promise<void>;
|
package/dist/types/common.js
CHANGED
|
@@ -12,15 +12,14 @@ exports.generateMeta = generateMeta;
|
|
|
12
12
|
const fs_1 = __importDefault(require("fs"));
|
|
13
13
|
const node_fetch_1 = __importDefault(require("node-fetch"));
|
|
14
14
|
const path_1 = __importDefault(require("path"));
|
|
15
|
-
// Method for handing off the parsing of a gff3 file URL.
|
|
16
|
-
//
|
|
17
|
-
// Returns a @gmod/gff stream.
|
|
15
|
+
// Method for handing off the parsing of a gff3 file URL. Calls the proper
|
|
16
|
+
// parser depending on if it is gzipped or not. Returns a @gmod/gff stream.
|
|
18
17
|
async function createRemoteStream(urlIn) {
|
|
19
|
-
const
|
|
20
|
-
if (!
|
|
21
|
-
throw new Error(`Failed to fetch ${urlIn} status ${
|
|
18
|
+
const res = await (0, node_fetch_1.default)(urlIn);
|
|
19
|
+
if (!res.ok) {
|
|
20
|
+
throw new Error(`Failed to fetch ${urlIn} status ${res.status} ${await res.text()}`);
|
|
22
21
|
}
|
|
23
|
-
return
|
|
22
|
+
return res;
|
|
24
23
|
}
|
|
25
24
|
// Checks if the passed in string is a valid URL.
|
|
26
25
|
// Returns a boolean.
|
|
@@ -35,20 +34,20 @@ function isURL(FileName) {
|
|
|
35
34
|
return url.protocol === 'http:' || url.protocol === 'https:';
|
|
36
35
|
}
|
|
37
36
|
async function getLocalOrRemoteStream(uri, out) {
|
|
38
|
-
var _a;
|
|
39
|
-
let stream;
|
|
40
|
-
let totalBytes = 0;
|
|
41
37
|
if (isURL(uri)) {
|
|
42
38
|
const result = await createRemoteStream(uri);
|
|
43
|
-
|
|
44
|
-
|
|
39
|
+
return {
|
|
40
|
+
totalBytes: +(result.headers.get('Content-Length') || 0),
|
|
41
|
+
stream: result.body,
|
|
42
|
+
};
|
|
45
43
|
}
|
|
46
44
|
else {
|
|
47
45
|
const filename = path_1.default.isAbsolute(uri) ? uri : path_1.default.join(out, uri);
|
|
48
|
-
|
|
49
|
-
|
|
46
|
+
return {
|
|
47
|
+
totalBytes: fs_1.default.statSync(filename).size,
|
|
48
|
+
stream: fs_1.default.createReadStream(filename),
|
|
49
|
+
};
|
|
50
50
|
}
|
|
51
|
-
return { totalBytes, stream };
|
|
52
51
|
}
|
|
53
52
|
function makeLocation(location, protocol) {
|
|
54
53
|
if (protocol === 'uri') {
|
|
@@ -127,27 +126,20 @@ function guessAdapterFromFileName(filePath) {
|
|
|
127
126
|
}
|
|
128
127
|
/**
|
|
129
128
|
* Generates metadata of index given a filename (trackId or assembly)
|
|
130
|
-
* @param name - assembly name or trackId
|
|
131
|
-
* @param attributes - attributes indexed
|
|
132
|
-
* @param include - feature types included from index
|
|
133
|
-
* @param exclude - feature types excluded from index
|
|
134
|
-
* @param configs - list of track
|
|
135
129
|
*/
|
|
136
|
-
async function generateMeta({ configs,
|
|
137
|
-
const tracks = configs.map(config => {
|
|
138
|
-
const { trackId, textSearching, adapter } = config;
|
|
139
|
-
const includeExclude = (textSearching === null || textSearching === void 0 ? void 0 : textSearching.indexingFeatureTypesToExclude) || exclude;
|
|
140
|
-
const metaAttrs = (textSearching === null || textSearching === void 0 ? void 0 : textSearching.indexingAttributes) || attributes;
|
|
141
|
-
return {
|
|
142
|
-
trackId: trackId,
|
|
143
|
-
attributesIndexed: metaAttrs,
|
|
144
|
-
excludedTypes: includeExclude,
|
|
145
|
-
adapterConf: adapter,
|
|
146
|
-
};
|
|
147
|
-
});
|
|
130
|
+
async function generateMeta({ configs, attributesToIndex, outDir, name, featureTypesToExclude, assemblyNames, }) {
|
|
148
131
|
fs_1.default.writeFileSync(path_1.default.join(outDir, 'trix', `${name}_meta.json`), JSON.stringify({
|
|
149
132
|
dateCreated: new Date().toISOString(),
|
|
150
|
-
tracks
|
|
133
|
+
tracks: configs.map(config => {
|
|
134
|
+
const { trackId, textSearching, adapter } = config;
|
|
135
|
+
return {
|
|
136
|
+
trackId,
|
|
137
|
+
attributesIndexed: (textSearching === null || textSearching === void 0 ? void 0 : textSearching.indexingAttributes) || attributesToIndex,
|
|
138
|
+
excludedTypes: (textSearching === null || textSearching === void 0 ? void 0 : textSearching.indexingFeatureTypesToExclude) ||
|
|
139
|
+
featureTypesToExclude,
|
|
140
|
+
adapterConf: adapter,
|
|
141
|
+
};
|
|
142
|
+
}),
|
|
151
143
|
assemblyNames,
|
|
152
144
|
}, null, 2));
|
|
153
145
|
}
|
|
@@ -1,2 +1,11 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
export declare function indexGff3({ config, attributesToIndex, inLocation, outDir, featureTypesToExclude, onStart, onUpdate, }: {
|
|
2
|
+
config: {
|
|
3
|
+
trackId: string;
|
|
4
|
+
};
|
|
5
|
+
attributesToIndex: string[];
|
|
6
|
+
inLocation: string;
|
|
7
|
+
outDir: string;
|
|
8
|
+
featureTypesToExclude: string[];
|
|
9
|
+
onStart: (totalBytes: number) => void;
|
|
10
|
+
onUpdate: (progressBytes: number) => void;
|
|
11
|
+
}): AsyncGenerator<string, void, unknown>;
|
|
@@ -6,24 +6,26 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
6
6
|
exports.indexGff3 = indexGff3;
|
|
7
7
|
const zlib_1 = require("zlib");
|
|
8
8
|
const readline_1 = __importDefault(require("readline"));
|
|
9
|
+
// locals
|
|
9
10
|
const util_1 = require("../util");
|
|
10
11
|
const common_1 = require("./common");
|
|
11
|
-
|
|
12
|
-
async function* indexGff3(config, attributes, inLocation, outLocation, typesToExclude, quiet, statusCallback, signal) {
|
|
12
|
+
async function* indexGff3({ config, attributesToIndex, inLocation, outDir, featureTypesToExclude, onStart, onUpdate, }) {
|
|
13
13
|
const { trackId } = config;
|
|
14
14
|
let receivedBytes = 0;
|
|
15
|
-
const { totalBytes, stream } = await (0, common_1.getLocalOrRemoteStream)(inLocation,
|
|
15
|
+
const { totalBytes, stream } = await (0, common_1.getLocalOrRemoteStream)(inLocation, outDir);
|
|
16
|
+
onStart(totalBytes);
|
|
16
17
|
stream.on('data', chunk => {
|
|
17
18
|
receivedBytes += chunk.length;
|
|
18
|
-
|
|
19
|
-
const progress = Math.round((receivedBytes / totalBytes) * 100);
|
|
20
|
-
statusCallback(`${progress}`);
|
|
19
|
+
onUpdate(receivedBytes);
|
|
21
20
|
});
|
|
22
21
|
const rl = readline_1.default.createInterface({
|
|
23
|
-
input:
|
|
22
|
+
input: /.b?gz$/.exec(inLocation) ? stream.pipe((0, zlib_1.createGunzip)()) : stream,
|
|
24
23
|
});
|
|
25
24
|
for await (const line of rl) {
|
|
26
|
-
if (line.
|
|
25
|
+
if (!line.trim()) {
|
|
26
|
+
continue;
|
|
27
|
+
}
|
|
28
|
+
else if (line.startsWith('#')) {
|
|
27
29
|
continue;
|
|
28
30
|
}
|
|
29
31
|
else if (line.startsWith('>')) {
|
|
@@ -31,7 +33,7 @@ async function* indexGff3(config, attributes, inLocation, outLocation, typesToEx
|
|
|
31
33
|
}
|
|
32
34
|
const [seq_id, , type, start, end, , , , col9] = line.split('\t');
|
|
33
35
|
const locStr = `${seq_id}:${start}..${end}`;
|
|
34
|
-
if (!
|
|
36
|
+
if (!featureTypesToExclude.includes(type)) {
|
|
35
37
|
// turns gff3 attrs into a map, and converts the arrays into space
|
|
36
38
|
// separated strings
|
|
37
39
|
const col9attrs = Object.fromEntries(col9
|
|
@@ -41,9 +43,11 @@ async function* indexGff3(config, attributes, inLocation, outLocation, typesToEx
|
|
|
41
43
|
.map(f => f.split('='))
|
|
42
44
|
.map(([key, val]) => [
|
|
43
45
|
key.trim(),
|
|
44
|
-
|
|
46
|
+
val
|
|
47
|
+
? (0, util_1.decodeURIComponentNoThrow)(val).trim().split(',').join(' ')
|
|
48
|
+
: undefined,
|
|
45
49
|
]));
|
|
46
|
-
const attrs =
|
|
50
|
+
const attrs = attributesToIndex
|
|
47
51
|
.map(attr => col9attrs[attr])
|
|
48
52
|
.filter((f) => !!f);
|
|
49
53
|
if (attrs.length) {
|
|
@@ -52,11 +56,8 @@ async function* indexGff3(config, attributes, inLocation, outLocation, typesToEx
|
|
|
52
56
|
encodeURIComponent(trackId),
|
|
53
57
|
...attrs.map(a => encodeURIComponent(a)),
|
|
54
58
|
]).replaceAll(',', '|');
|
|
55
|
-
// Check abort signal
|
|
56
|
-
(0, util_2.checkAbortSignal)(signal);
|
|
57
59
|
yield `${record} ${[...new Set(attrs)].join(' ')}\n`;
|
|
58
60
|
}
|
|
59
61
|
}
|
|
60
62
|
}
|
|
61
|
-
// console.log('done')
|
|
62
63
|
}
|
|
@@ -1,2 +1,8 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
export declare function indexVcf({ config, attributesToIndex, inLocation, outDir, onStart, onUpdate, }: {
|
|
2
|
+
config: any;
|
|
3
|
+
attributesToIndex: string[];
|
|
4
|
+
inLocation: string;
|
|
5
|
+
outDir: string;
|
|
6
|
+
onStart: (totalBytes: number) => void;
|
|
7
|
+
onUpdate: (progressBytes: number) => void;
|
|
8
|
+
}): AsyncGenerator<string, void, unknown>;
|
package/dist/types/vcfAdapter.js
CHANGED
|
@@ -6,19 +6,19 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
6
6
|
exports.indexVcf = indexVcf;
|
|
7
7
|
const zlib_1 = require("zlib");
|
|
8
8
|
const readline_1 = __importDefault(require("readline"));
|
|
9
|
+
// locals
|
|
9
10
|
const util_1 = require("../util");
|
|
10
11
|
const common_1 = require("./common");
|
|
11
|
-
|
|
12
|
-
async function* indexVcf(config, attributesToIndex, inLocation, outLocation, typesToExclude, quiet, statusCallback, signal) {
|
|
12
|
+
async function* indexVcf({ config, attributesToIndex, inLocation, outDir, onStart, onUpdate, }) {
|
|
13
13
|
const { trackId } = config;
|
|
14
14
|
let receivedBytes = 0;
|
|
15
|
-
const { totalBytes, stream } = await (0, common_1.getLocalOrRemoteStream)(inLocation,
|
|
15
|
+
const { totalBytes, stream } = await (0, common_1.getLocalOrRemoteStream)(inLocation, outDir);
|
|
16
|
+
onStart(totalBytes);
|
|
16
17
|
stream.on('data', chunk => {
|
|
17
18
|
receivedBytes += chunk.length;
|
|
18
|
-
|
|
19
|
-
statusCallback(`${progress}`);
|
|
19
|
+
onUpdate(receivedBytes);
|
|
20
20
|
});
|
|
21
|
-
const gzStream =
|
|
21
|
+
const gzStream = /.b?gz$/.exec(inLocation)
|
|
22
22
|
? stream.pipe((0, zlib_1.createGunzip)())
|
|
23
23
|
: stream;
|
|
24
24
|
const rl = readline_1.default.createInterface({
|
|
@@ -30,7 +30,7 @@ async function* indexVcf(config, attributesToIndex, inLocation, outLocation, typ
|
|
|
30
30
|
}
|
|
31
31
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
32
32
|
const [ref, pos, id, _ref, _alt, _qual, _filter, info] = line.split('\t');
|
|
33
|
-
// turns
|
|
33
|
+
// turns gff3 attrs into a map, and converts the arrays into space
|
|
34
34
|
// separated strings
|
|
35
35
|
const fields = Object.fromEntries(info
|
|
36
36
|
.split(';')
|
|
@@ -60,8 +60,6 @@ async function* indexVcf(config, attributesToIndex, inLocation, outLocation, typ
|
|
|
60
60
|
encodeURIComponent(id || ''),
|
|
61
61
|
...infoAttrs.map(a => encodeURIComponent(a || '')),
|
|
62
62
|
]).replaceAll(',', '|');
|
|
63
|
-
// Check abort signal
|
|
64
|
-
(0, util_2.checkAbortSignal)(signal);
|
|
65
63
|
yield `${record} ${[...new Set(attrs)].join(' ')}\n`;
|
|
66
64
|
}
|
|
67
65
|
}
|
package/dist/util.d.ts
CHANGED
|
@@ -50,27 +50,37 @@ export interface Sequence {
|
|
|
50
50
|
trackId: string;
|
|
51
51
|
adapter: IndexedFastaAdapter | BgzipFastaAdapter | TwoBitAdapter | ChromeSizesAdapter | CustomSequenceAdapter;
|
|
52
52
|
}
|
|
53
|
+
type Loc = UriLocation | LocalPathLocation;
|
|
53
54
|
export interface Gff3TabixAdapter {
|
|
54
55
|
type: 'Gff3TabixAdapter';
|
|
55
|
-
gffGzLocation:
|
|
56
|
+
gffGzLocation: Loc;
|
|
56
57
|
}
|
|
57
58
|
export interface Gff3Adapter {
|
|
58
59
|
type: 'Gff3Adapter';
|
|
59
|
-
gffLocation:
|
|
60
|
+
gffLocation: Loc;
|
|
60
61
|
}
|
|
61
62
|
export interface GtfAdapter {
|
|
62
63
|
type: 'GtfAdapter';
|
|
63
|
-
gtfLocation:
|
|
64
|
+
gtfLocation: Loc;
|
|
64
65
|
}
|
|
65
66
|
export interface VcfTabixAdapter {
|
|
66
67
|
type: 'VcfTabixAdapter';
|
|
67
|
-
vcfGzLocation:
|
|
68
|
+
vcfGzLocation: Loc;
|
|
68
69
|
}
|
|
69
70
|
export interface VcfAdapter {
|
|
70
71
|
type: 'VcfAdapter';
|
|
71
|
-
vcfLocation:
|
|
72
|
+
vcfLocation: Loc;
|
|
73
|
+
}
|
|
74
|
+
export interface Track {
|
|
75
|
+
adapter?: {
|
|
76
|
+
type: string;
|
|
77
|
+
[key: string]: unknown;
|
|
78
|
+
};
|
|
79
|
+
textSearching?: TextSearching;
|
|
80
|
+
name: string;
|
|
81
|
+
assemblyNames: string[];
|
|
82
|
+
trackId: string;
|
|
72
83
|
}
|
|
73
|
-
export type Track = Record<string, any>;
|
|
74
84
|
export interface TextSearching {
|
|
75
85
|
indexingFeatureTypesToExclude?: string[];
|
|
76
86
|
indexingAttributes?: string[];
|
|
@@ -87,10 +97,10 @@ export interface TrixTextSearchAdapter {
|
|
|
87
97
|
export interface Config {
|
|
88
98
|
assemblies?: Assembly[];
|
|
89
99
|
assembly?: Assembly;
|
|
90
|
-
configuration?:
|
|
100
|
+
configuration?: Record<string, unknown>;
|
|
91
101
|
aggregateTextSearchAdapters?: TrixTextSearchAdapter[];
|
|
92
102
|
connections?: unknown[];
|
|
93
|
-
defaultSession?:
|
|
103
|
+
defaultSession?: Record<string, unknown>;
|
|
94
104
|
tracks?: Track[];
|
|
95
105
|
}
|
|
96
106
|
export type indexType = 'aggregate' | 'perTrack';
|
|
@@ -114,3 +124,4 @@ export declare function createTextSearchConf(name: string, trackIds: string[], a
|
|
|
114
124
|
};
|
|
115
125
|
export declare function findTrackConfigsToIndex(tracks: Track[], trackIds: string[], assemblyName?: string): Track[];
|
|
116
126
|
export declare function decodeURIComponentNoThrow(uri: string): string;
|
|
127
|
+
export {};
|
package/esm/TextIndexing.d.ts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { Track, indexType } from './util';
|
|
2
2
|
export declare function indexTracks(args: {
|
|
3
3
|
tracks: Track[];
|
|
4
|
-
|
|
4
|
+
outDir?: string;
|
|
5
5
|
signal?: AbortSignal;
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
6
|
+
attributesToIndex?: string[];
|
|
7
|
+
assemblyNames?: string[];
|
|
8
|
+
featureTypesToExclude?: string[];
|
|
9
9
|
indexType?: indexType;
|
|
10
10
|
statusCallback: (message: string) => void;
|
|
11
11
|
}): Promise<never[]>;
|
package/esm/TextIndexing.js
CHANGED
|
@@ -7,17 +7,32 @@ import { generateMeta } from './types/common';
|
|
|
7
7
|
import { ixIxxStream } from 'ixixx';
|
|
8
8
|
import { checkAbortSignal, isSupportedIndexingAdapter, } from '@jbrowse/core/util';
|
|
9
9
|
export async function indexTracks(args) {
|
|
10
|
-
const { tracks,
|
|
10
|
+
const { tracks, outDir, attributesToIndex, featureTypesToExclude, assemblyNames, indexType, statusCallback, signal, } = args;
|
|
11
11
|
const idxType = indexType || 'perTrack';
|
|
12
12
|
checkAbortSignal(signal);
|
|
13
13
|
await (idxType === 'perTrack'
|
|
14
|
-
? perTrackIndex(
|
|
15
|
-
|
|
14
|
+
? perTrackIndex({
|
|
15
|
+
tracks,
|
|
16
|
+
statusCallback,
|
|
17
|
+
outDir,
|
|
18
|
+
attributesToIndex,
|
|
19
|
+
featureTypesToExclude,
|
|
20
|
+
signal,
|
|
21
|
+
})
|
|
22
|
+
: aggregateIndex({
|
|
23
|
+
tracks,
|
|
24
|
+
statusCallback,
|
|
25
|
+
outDir,
|
|
26
|
+
attributesToIndex,
|
|
27
|
+
assemblyNames,
|
|
28
|
+
featureTypesToExclude,
|
|
29
|
+
signal,
|
|
30
|
+
}));
|
|
16
31
|
checkAbortSignal(signal);
|
|
17
32
|
return [];
|
|
18
33
|
}
|
|
19
|
-
async function perTrackIndex(tracks, statusCallback,
|
|
20
|
-
const outFlag =
|
|
34
|
+
async function perTrackIndex({ tracks, statusCallback, outDir: paramOutDir, attributesToIndex = ['Name', 'ID'], featureTypesToExclude = ['exon', 'CDS'], signal, }) {
|
|
35
|
+
const outFlag = paramOutDir || '.';
|
|
21
36
|
const isDir = fs.lstatSync(outFlag).isDirectory();
|
|
22
37
|
const confFilePath = isDir ? path.join(outFlag, 'config.json') : outFlag;
|
|
23
38
|
const outDir = path.dirname(confFilePath);
|
|
@@ -26,22 +41,24 @@ async function perTrackIndex(tracks, statusCallback, outLocation, attributes, ex
|
|
|
26
41
|
fs.mkdirSync(trixDir);
|
|
27
42
|
}
|
|
28
43
|
// default settings
|
|
29
|
-
const attrs = attributes || ['Name', 'ID'];
|
|
30
|
-
const excludeTypes = exclude || ['exon', 'CDS'];
|
|
31
|
-
const force = true;
|
|
32
44
|
const supportedTracks = tracks.filter(track => { var _a; return isSupportedIndexingAdapter((_a = track.adapter) === null || _a === void 0 ? void 0 : _a.type); });
|
|
33
45
|
for (const trackConfig of supportedTracks) {
|
|
34
|
-
const {
|
|
46
|
+
const { trackId, assemblyNames } = trackConfig;
|
|
35
47
|
const id = `${trackId}-index`;
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
48
|
+
await indexDriver({
|
|
49
|
+
tracks: [trackConfig],
|
|
50
|
+
outDir,
|
|
51
|
+
attributesToIndex,
|
|
52
|
+
name: id,
|
|
53
|
+
featureTypesToExclude,
|
|
54
|
+
assemblyNames,
|
|
55
|
+
statusCallback,
|
|
56
|
+
signal,
|
|
57
|
+
});
|
|
41
58
|
}
|
|
42
59
|
}
|
|
43
|
-
async function aggregateIndex(tracks, statusCallback,
|
|
44
|
-
const outFlag =
|
|
60
|
+
async function aggregateIndex({ tracks, statusCallback, outDir: paramOutDir, attributesToIndex = ['Name', 'ID'], featureTypesToExclude = ['exon', 'CDS'], signal, assemblyNames, }) {
|
|
61
|
+
const outFlag = paramOutDir || '.';
|
|
45
62
|
const isDir = fs.lstatSync(outFlag).isDirectory();
|
|
46
63
|
const confFilePath = isDir ? path.join(outFlag, 'config.json') : outFlag;
|
|
47
64
|
const outDir = path.dirname(confFilePath);
|
|
@@ -49,70 +66,92 @@ async function aggregateIndex(tracks, statusCallback, outLocation, attributes, a
|
|
|
49
66
|
if (!fs.existsSync(trixDir)) {
|
|
50
67
|
fs.mkdirSync(trixDir);
|
|
51
68
|
}
|
|
52
|
-
if (!
|
|
69
|
+
if (!assemblyNames) {
|
|
53
70
|
throw new Error('No assemblies passed. Assmeblies required for aggregate indexes');
|
|
54
71
|
}
|
|
55
|
-
for (const asm of
|
|
56
|
-
|
|
57
|
-
const id = asm + '-index';
|
|
58
|
-
// default settings
|
|
59
|
-
const attrs = attributes || ['Name', 'ID'];
|
|
60
|
-
const excludeTypes = exclude || ['exon', 'CDS'];
|
|
61
|
-
// const force = true
|
|
62
|
-
const quiet = true;
|
|
63
|
-
// supported tracks for given assembly
|
|
72
|
+
for (const asm of assemblyNames) {
|
|
73
|
+
const id = `${asm}-index`;
|
|
64
74
|
const supportedTracks = tracks
|
|
65
75
|
.filter(track => { var _a; return isSupportedIndexingAdapter((_a = track.adapter) === null || _a === void 0 ? void 0 : _a.type); })
|
|
66
76
|
.filter(track => (asm ? track.assemblyNames.includes(asm) : true));
|
|
67
|
-
await indexDriver(
|
|
77
|
+
await indexDriver({
|
|
78
|
+
tracks: supportedTracks,
|
|
79
|
+
outDir: outDir,
|
|
80
|
+
attributesToIndex,
|
|
81
|
+
name: id,
|
|
82
|
+
featureTypesToExclude,
|
|
83
|
+
assemblyNames: [asm],
|
|
84
|
+
statusCallback,
|
|
85
|
+
signal,
|
|
86
|
+
});
|
|
68
87
|
}
|
|
69
88
|
}
|
|
70
|
-
async function indexDriver(tracks,
|
|
71
|
-
const readable = Readable.from(indexFiles(
|
|
89
|
+
async function indexDriver({ tracks, outDir, attributesToIndex, name, featureTypesToExclude, assemblyNames, statusCallback, signal, }) {
|
|
90
|
+
const readable = Readable.from(indexFiles({
|
|
91
|
+
tracks,
|
|
92
|
+
attributesToIndex,
|
|
93
|
+
outDir,
|
|
94
|
+
featureTypesToExclude,
|
|
95
|
+
statusCallback,
|
|
96
|
+
signal,
|
|
97
|
+
}));
|
|
72
98
|
statusCallback('Indexing files.');
|
|
73
|
-
|
|
99
|
+
await runIxIxx(readable, outDir, name);
|
|
74
100
|
checkAbortSignal(signal);
|
|
75
101
|
await generateMeta({
|
|
76
102
|
configs: tracks,
|
|
77
|
-
|
|
78
|
-
outDir
|
|
103
|
+
attributesToIndex,
|
|
104
|
+
outDir,
|
|
79
105
|
name,
|
|
80
|
-
|
|
106
|
+
featureTypesToExclude,
|
|
81
107
|
assemblyNames,
|
|
82
108
|
});
|
|
83
109
|
checkAbortSignal(signal);
|
|
84
|
-
return ixIxxStream;
|
|
85
110
|
}
|
|
86
|
-
async function* indexFiles(tracks,
|
|
111
|
+
async function* indexFiles({ tracks, attributesToIndex: idx1, outDir, featureTypesToExclude: edx1, statusCallback, }) {
|
|
87
112
|
for (const track of tracks) {
|
|
88
113
|
const { adapter, textSearching } = track;
|
|
89
|
-
const { type } = adapter;
|
|
90
|
-
const { indexingFeatureTypesToExclude:
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
114
|
+
const { type } = adapter || {};
|
|
115
|
+
const { indexingFeatureTypesToExclude: featureTypesToExclude = edx1, indexingAttributes: attributesToIndex = idx1, } = textSearching || {};
|
|
116
|
+
let myTotalBytes;
|
|
117
|
+
if (type === 'Gff3TabixAdapter' || type === 'Gff3Adapter') {
|
|
118
|
+
yield* indexGff3({
|
|
119
|
+
config: track,
|
|
120
|
+
attributesToIndex,
|
|
121
|
+
inLocation: getLoc('gffGzLocation', track),
|
|
122
|
+
outDir,
|
|
123
|
+
featureTypesToExclude,
|
|
124
|
+
onStart: totalBytes => {
|
|
125
|
+
myTotalBytes = totalBytes;
|
|
126
|
+
},
|
|
127
|
+
onUpdate: progressBytes => {
|
|
128
|
+
statusCallback(`${progressBytes}/${myTotalBytes}`);
|
|
129
|
+
},
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
else if (type === 'VcfTabixAdapter' || type === 'VcfAdapter') {
|
|
133
|
+
yield* indexVcf({
|
|
134
|
+
config: track,
|
|
135
|
+
attributesToIndex,
|
|
136
|
+
inLocation: getLoc('vcfGzLocation', track),
|
|
137
|
+
outDir,
|
|
138
|
+
onStart: totalBytes => {
|
|
139
|
+
myTotalBytes = totalBytes;
|
|
140
|
+
},
|
|
141
|
+
onUpdate: progressBytes => {
|
|
142
|
+
statusCallback(`${progressBytes}/${myTotalBytes}`);
|
|
143
|
+
},
|
|
144
|
+
});
|
|
110
145
|
}
|
|
111
146
|
}
|
|
112
147
|
return;
|
|
113
148
|
}
|
|
114
149
|
function getLoc(attr, config) {
|
|
115
|
-
|
|
150
|
+
var _a;
|
|
151
|
+
const elt = (_a = config.adapter) === null || _a === void 0 ? void 0 : _a[attr];
|
|
152
|
+
if (!elt) {
|
|
153
|
+
throw new Error('none');
|
|
154
|
+
}
|
|
116
155
|
return elt.uri || elt.localPath;
|
|
117
156
|
}
|
|
118
157
|
function runIxIxx(readStream, idxLocation, name) {
|
package/esm/index.d.ts
CHANGED
package/esm/index.js
CHANGED
package/esm/types/common.d.ts
CHANGED
|
@@ -5,23 +5,21 @@ export declare function createRemoteStream(urlIn: string): Promise<fetch.Respons
|
|
|
5
5
|
export declare function isURL(FileName: string): boolean;
|
|
6
6
|
export declare function getLocalOrRemoteStream(uri: string, out: string): Promise<{
|
|
7
7
|
totalBytes: number;
|
|
8
|
-
stream: NodeJS.ReadableStream
|
|
8
|
+
stream: NodeJS.ReadableStream;
|
|
9
|
+
} | {
|
|
10
|
+
totalBytes: number;
|
|
11
|
+
stream: fs.ReadStream;
|
|
9
12
|
}>;
|
|
10
13
|
export declare function makeLocation(location: string, protocol: string): UriLocation | LocalPathLocation;
|
|
11
14
|
export declare function guessAdapterFromFileName(filePath: string): Track;
|
|
12
15
|
/**
|
|
13
16
|
* Generates metadata of index given a filename (trackId or assembly)
|
|
14
|
-
* @param name - assembly name or trackId
|
|
15
|
-
* @param attributes - attributes indexed
|
|
16
|
-
* @param include - feature types included from index
|
|
17
|
-
* @param exclude - feature types excluded from index
|
|
18
|
-
* @param configs - list of track
|
|
19
17
|
*/
|
|
20
|
-
export declare function generateMeta({ configs,
|
|
18
|
+
export declare function generateMeta({ configs, attributesToIndex, outDir, name, featureTypesToExclude, assemblyNames, }: {
|
|
21
19
|
configs: Track[];
|
|
22
|
-
|
|
20
|
+
attributesToIndex: string[];
|
|
23
21
|
outDir: string;
|
|
24
22
|
name: string;
|
|
25
|
-
|
|
23
|
+
featureTypesToExclude: string[];
|
|
26
24
|
assemblyNames: string[];
|
|
27
25
|
}): Promise<void>;
|
package/esm/types/common.js
CHANGED
|
@@ -1,15 +1,14 @@
|
|
|
1
1
|
import fs from 'fs';
|
|
2
2
|
import fetch from 'node-fetch';
|
|
3
3
|
import path from 'path';
|
|
4
|
-
// Method for handing off the parsing of a gff3 file URL.
|
|
5
|
-
//
|
|
6
|
-
// Returns a @gmod/gff stream.
|
|
4
|
+
// Method for handing off the parsing of a gff3 file URL. Calls the proper
|
|
5
|
+
// parser depending on if it is gzipped or not. Returns a @gmod/gff stream.
|
|
7
6
|
export async function createRemoteStream(urlIn) {
|
|
8
|
-
const
|
|
9
|
-
if (!
|
|
10
|
-
throw new Error(`Failed to fetch ${urlIn} status ${
|
|
7
|
+
const res = await fetch(urlIn);
|
|
8
|
+
if (!res.ok) {
|
|
9
|
+
throw new Error(`Failed to fetch ${urlIn} status ${res.status} ${await res.text()}`);
|
|
11
10
|
}
|
|
12
|
-
return
|
|
11
|
+
return res;
|
|
13
12
|
}
|
|
14
13
|
// Checks if the passed in string is a valid URL.
|
|
15
14
|
// Returns a boolean.
|
|
@@ -24,20 +23,20 @@ export function isURL(FileName) {
|
|
|
24
23
|
return url.protocol === 'http:' || url.protocol === 'https:';
|
|
25
24
|
}
|
|
26
25
|
export async function getLocalOrRemoteStream(uri, out) {
|
|
27
|
-
var _a;
|
|
28
|
-
let stream;
|
|
29
|
-
let totalBytes = 0;
|
|
30
26
|
if (isURL(uri)) {
|
|
31
27
|
const result = await createRemoteStream(uri);
|
|
32
|
-
|
|
33
|
-
|
|
28
|
+
return {
|
|
29
|
+
totalBytes: +(result.headers.get('Content-Length') || 0),
|
|
30
|
+
stream: result.body,
|
|
31
|
+
};
|
|
34
32
|
}
|
|
35
33
|
else {
|
|
36
34
|
const filename = path.isAbsolute(uri) ? uri : path.join(out, uri);
|
|
37
|
-
|
|
38
|
-
|
|
35
|
+
return {
|
|
36
|
+
totalBytes: fs.statSync(filename).size,
|
|
37
|
+
stream: fs.createReadStream(filename),
|
|
38
|
+
};
|
|
39
39
|
}
|
|
40
|
-
return { totalBytes, stream };
|
|
41
40
|
}
|
|
42
41
|
export function makeLocation(location, protocol) {
|
|
43
42
|
if (protocol === 'uri') {
|
|
@@ -116,27 +115,20 @@ export function guessAdapterFromFileName(filePath) {
|
|
|
116
115
|
}
|
|
117
116
|
/**
|
|
118
117
|
* Generates metadata of index given a filename (trackId or assembly)
|
|
119
|
-
* @param name - assembly name or trackId
|
|
120
|
-
* @param attributes - attributes indexed
|
|
121
|
-
* @param include - feature types included from index
|
|
122
|
-
* @param exclude - feature types excluded from index
|
|
123
|
-
* @param configs - list of track
|
|
124
118
|
*/
|
|
125
|
-
export async function generateMeta({ configs,
|
|
126
|
-
const tracks = configs.map(config => {
|
|
127
|
-
const { trackId, textSearching, adapter } = config;
|
|
128
|
-
const includeExclude = (textSearching === null || textSearching === void 0 ? void 0 : textSearching.indexingFeatureTypesToExclude) || exclude;
|
|
129
|
-
const metaAttrs = (textSearching === null || textSearching === void 0 ? void 0 : textSearching.indexingAttributes) || attributes;
|
|
130
|
-
return {
|
|
131
|
-
trackId: trackId,
|
|
132
|
-
attributesIndexed: metaAttrs,
|
|
133
|
-
excludedTypes: includeExclude,
|
|
134
|
-
adapterConf: adapter,
|
|
135
|
-
};
|
|
136
|
-
});
|
|
119
|
+
export async function generateMeta({ configs, attributesToIndex, outDir, name, featureTypesToExclude, assemblyNames, }) {
|
|
137
120
|
fs.writeFileSync(path.join(outDir, 'trix', `${name}_meta.json`), JSON.stringify({
|
|
138
121
|
dateCreated: new Date().toISOString(),
|
|
139
|
-
tracks
|
|
122
|
+
tracks: configs.map(config => {
|
|
123
|
+
const { trackId, textSearching, adapter } = config;
|
|
124
|
+
return {
|
|
125
|
+
trackId,
|
|
126
|
+
attributesIndexed: (textSearching === null || textSearching === void 0 ? void 0 : textSearching.indexingAttributes) || attributesToIndex,
|
|
127
|
+
excludedTypes: (textSearching === null || textSearching === void 0 ? void 0 : textSearching.indexingFeatureTypesToExclude) ||
|
|
128
|
+
featureTypesToExclude,
|
|
129
|
+
adapterConf: adapter,
|
|
130
|
+
};
|
|
131
|
+
}),
|
|
140
132
|
assemblyNames,
|
|
141
133
|
}, null, 2));
|
|
142
134
|
}
|
|
@@ -1,2 +1,11 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
export declare function indexGff3({ config, attributesToIndex, inLocation, outDir, featureTypesToExclude, onStart, onUpdate, }: {
|
|
2
|
+
config: {
|
|
3
|
+
trackId: string;
|
|
4
|
+
};
|
|
5
|
+
attributesToIndex: string[];
|
|
6
|
+
inLocation: string;
|
|
7
|
+
outDir: string;
|
|
8
|
+
featureTypesToExclude: string[];
|
|
9
|
+
onStart: (totalBytes: number) => void;
|
|
10
|
+
onUpdate: (progressBytes: number) => void;
|
|
11
|
+
}): AsyncGenerator<string, void, unknown>;
|
package/esm/types/gff3Adapter.js
CHANGED
|
@@ -1,23 +1,25 @@
|
|
|
1
1
|
import { createGunzip } from 'zlib';
|
|
2
2
|
import readline from 'readline';
|
|
3
|
+
// locals
|
|
3
4
|
import { decodeURIComponentNoThrow } from '../util';
|
|
4
5
|
import { getLocalOrRemoteStream } from './common';
|
|
5
|
-
|
|
6
|
-
export async function* indexGff3(config, attributes, inLocation, outLocation, typesToExclude, quiet, statusCallback, signal) {
|
|
6
|
+
export async function* indexGff3({ config, attributesToIndex, inLocation, outDir, featureTypesToExclude, onStart, onUpdate, }) {
|
|
7
7
|
const { trackId } = config;
|
|
8
8
|
let receivedBytes = 0;
|
|
9
|
-
const { totalBytes, stream } = await getLocalOrRemoteStream(inLocation,
|
|
9
|
+
const { totalBytes, stream } = await getLocalOrRemoteStream(inLocation, outDir);
|
|
10
|
+
onStart(totalBytes);
|
|
10
11
|
stream.on('data', chunk => {
|
|
11
12
|
receivedBytes += chunk.length;
|
|
12
|
-
|
|
13
|
-
const progress = Math.round((receivedBytes / totalBytes) * 100);
|
|
14
|
-
statusCallback(`${progress}`);
|
|
13
|
+
onUpdate(receivedBytes);
|
|
15
14
|
});
|
|
16
15
|
const rl = readline.createInterface({
|
|
17
|
-
input:
|
|
16
|
+
input: /.b?gz$/.exec(inLocation) ? stream.pipe(createGunzip()) : stream,
|
|
18
17
|
});
|
|
19
18
|
for await (const line of rl) {
|
|
20
|
-
if (line.
|
|
19
|
+
if (!line.trim()) {
|
|
20
|
+
continue;
|
|
21
|
+
}
|
|
22
|
+
else if (line.startsWith('#')) {
|
|
21
23
|
continue;
|
|
22
24
|
}
|
|
23
25
|
else if (line.startsWith('>')) {
|
|
@@ -25,7 +27,7 @@ export async function* indexGff3(config, attributes, inLocation, outLocation, ty
|
|
|
25
27
|
}
|
|
26
28
|
const [seq_id, , type, start, end, , , , col9] = line.split('\t');
|
|
27
29
|
const locStr = `${seq_id}:${start}..${end}`;
|
|
28
|
-
if (!
|
|
30
|
+
if (!featureTypesToExclude.includes(type)) {
|
|
29
31
|
// turns gff3 attrs into a map, and converts the arrays into space
|
|
30
32
|
// separated strings
|
|
31
33
|
const col9attrs = Object.fromEntries(col9
|
|
@@ -35,9 +37,11 @@ export async function* indexGff3(config, attributes, inLocation, outLocation, ty
|
|
|
35
37
|
.map(f => f.split('='))
|
|
36
38
|
.map(([key, val]) => [
|
|
37
39
|
key.trim(),
|
|
38
|
-
|
|
40
|
+
val
|
|
41
|
+
? decodeURIComponentNoThrow(val).trim().split(',').join(' ')
|
|
42
|
+
: undefined,
|
|
39
43
|
]));
|
|
40
|
-
const attrs =
|
|
44
|
+
const attrs = attributesToIndex
|
|
41
45
|
.map(attr => col9attrs[attr])
|
|
42
46
|
.filter((f) => !!f);
|
|
43
47
|
if (attrs.length) {
|
|
@@ -46,11 +50,8 @@ export async function* indexGff3(config, attributes, inLocation, outLocation, ty
|
|
|
46
50
|
encodeURIComponent(trackId),
|
|
47
51
|
...attrs.map(a => encodeURIComponent(a)),
|
|
48
52
|
]).replaceAll(',', '|');
|
|
49
|
-
// Check abort signal
|
|
50
|
-
checkAbortSignal(signal);
|
|
51
53
|
yield `${record} ${[...new Set(attrs)].join(' ')}\n`;
|
|
52
54
|
}
|
|
53
55
|
}
|
|
54
56
|
}
|
|
55
|
-
// console.log('done')
|
|
56
57
|
}
|
|
@@ -1,2 +1,8 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
export declare function indexVcf({ config, attributesToIndex, inLocation, outDir, onStart, onUpdate, }: {
|
|
2
|
+
config: any;
|
|
3
|
+
attributesToIndex: string[];
|
|
4
|
+
inLocation: string;
|
|
5
|
+
outDir: string;
|
|
6
|
+
onStart: (totalBytes: number) => void;
|
|
7
|
+
onUpdate: (progressBytes: number) => void;
|
|
8
|
+
}): AsyncGenerator<string, void, unknown>;
|
package/esm/types/vcfAdapter.js
CHANGED
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
import { createGunzip } from 'zlib';
|
|
2
2
|
import readline from 'readline';
|
|
3
|
+
// locals
|
|
3
4
|
import { decodeURIComponentNoThrow } from '../util';
|
|
4
5
|
import { getLocalOrRemoteStream } from './common';
|
|
5
|
-
|
|
6
|
-
export async function* indexVcf(config, attributesToIndex, inLocation, outLocation, typesToExclude, quiet, statusCallback, signal) {
|
|
6
|
+
export async function* indexVcf({ config, attributesToIndex, inLocation, outDir, onStart, onUpdate, }) {
|
|
7
7
|
const { trackId } = config;
|
|
8
8
|
let receivedBytes = 0;
|
|
9
|
-
const { totalBytes, stream } = await getLocalOrRemoteStream(inLocation,
|
|
9
|
+
const { totalBytes, stream } = await getLocalOrRemoteStream(inLocation, outDir);
|
|
10
|
+
onStart(totalBytes);
|
|
10
11
|
stream.on('data', chunk => {
|
|
11
12
|
receivedBytes += chunk.length;
|
|
12
|
-
|
|
13
|
-
statusCallback(`${progress}`);
|
|
13
|
+
onUpdate(receivedBytes);
|
|
14
14
|
});
|
|
15
|
-
const gzStream =
|
|
15
|
+
const gzStream = /.b?gz$/.exec(inLocation)
|
|
16
16
|
? stream.pipe(createGunzip())
|
|
17
17
|
: stream;
|
|
18
18
|
const rl = readline.createInterface({
|
|
@@ -24,7 +24,7 @@ export async function* indexVcf(config, attributesToIndex, inLocation, outLocati
|
|
|
24
24
|
}
|
|
25
25
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
26
26
|
const [ref, pos, id, _ref, _alt, _qual, _filter, info] = line.split('\t');
|
|
27
|
-
// turns
|
|
27
|
+
// turns gff3 attrs into a map, and converts the arrays into space
|
|
28
28
|
// separated strings
|
|
29
29
|
const fields = Object.fromEntries(info
|
|
30
30
|
.split(';')
|
|
@@ -54,8 +54,6 @@ export async function* indexVcf(config, attributesToIndex, inLocation, outLocati
|
|
|
54
54
|
encodeURIComponent(id || ''),
|
|
55
55
|
...infoAttrs.map(a => encodeURIComponent(a || '')),
|
|
56
56
|
]).replaceAll(',', '|');
|
|
57
|
-
// Check abort signal
|
|
58
|
-
checkAbortSignal(signal);
|
|
59
57
|
yield `${record} ${[...new Set(attrs)].join(' ')}\n`;
|
|
60
58
|
}
|
|
61
59
|
}
|
package/esm/util.d.ts
CHANGED
|
@@ -50,27 +50,37 @@ export interface Sequence {
|
|
|
50
50
|
trackId: string;
|
|
51
51
|
adapter: IndexedFastaAdapter | BgzipFastaAdapter | TwoBitAdapter | ChromeSizesAdapter | CustomSequenceAdapter;
|
|
52
52
|
}
|
|
53
|
+
type Loc = UriLocation | LocalPathLocation;
|
|
53
54
|
export interface Gff3TabixAdapter {
|
|
54
55
|
type: 'Gff3TabixAdapter';
|
|
55
|
-
gffGzLocation:
|
|
56
|
+
gffGzLocation: Loc;
|
|
56
57
|
}
|
|
57
58
|
export interface Gff3Adapter {
|
|
58
59
|
type: 'Gff3Adapter';
|
|
59
|
-
gffLocation:
|
|
60
|
+
gffLocation: Loc;
|
|
60
61
|
}
|
|
61
62
|
export interface GtfAdapter {
|
|
62
63
|
type: 'GtfAdapter';
|
|
63
|
-
gtfLocation:
|
|
64
|
+
gtfLocation: Loc;
|
|
64
65
|
}
|
|
65
66
|
export interface VcfTabixAdapter {
|
|
66
67
|
type: 'VcfTabixAdapter';
|
|
67
|
-
vcfGzLocation:
|
|
68
|
+
vcfGzLocation: Loc;
|
|
68
69
|
}
|
|
69
70
|
export interface VcfAdapter {
|
|
70
71
|
type: 'VcfAdapter';
|
|
71
|
-
vcfLocation:
|
|
72
|
+
vcfLocation: Loc;
|
|
73
|
+
}
|
|
74
|
+
export interface Track {
|
|
75
|
+
adapter?: {
|
|
76
|
+
type: string;
|
|
77
|
+
[key: string]: unknown;
|
|
78
|
+
};
|
|
79
|
+
textSearching?: TextSearching;
|
|
80
|
+
name: string;
|
|
81
|
+
assemblyNames: string[];
|
|
82
|
+
trackId: string;
|
|
72
83
|
}
|
|
73
|
-
export type Track = Record<string, any>;
|
|
74
84
|
export interface TextSearching {
|
|
75
85
|
indexingFeatureTypesToExclude?: string[];
|
|
76
86
|
indexingAttributes?: string[];
|
|
@@ -87,10 +97,10 @@ export interface TrixTextSearchAdapter {
|
|
|
87
97
|
export interface Config {
|
|
88
98
|
assemblies?: Assembly[];
|
|
89
99
|
assembly?: Assembly;
|
|
90
|
-
configuration?:
|
|
100
|
+
configuration?: Record<string, unknown>;
|
|
91
101
|
aggregateTextSearchAdapters?: TrixTextSearchAdapter[];
|
|
92
102
|
connections?: unknown[];
|
|
93
|
-
defaultSession?:
|
|
103
|
+
defaultSession?: Record<string, unknown>;
|
|
94
104
|
tracks?: Track[];
|
|
95
105
|
}
|
|
96
106
|
export type indexType = 'aggregate' | 'perTrack';
|
|
@@ -114,3 +124,4 @@ export declare function createTextSearchConf(name: string, trackIds: string[], a
|
|
|
114
124
|
};
|
|
115
125
|
export declare function findTrackConfigsToIndex(tracks: Track[], trackIds: string[], assemblyName?: string): Track[];
|
|
116
126
|
export declare function decodeURIComponentNoThrow(uri: string): string;
|
|
127
|
+
export {};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jbrowse/text-indexing",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.14.0",
|
|
4
4
|
"description": "JBrowse 2 text indexing for desktop",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"jbrowse",
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
"build:esm": "tsc --build tsconfig.build.esm.json",
|
|
33
33
|
"build:commonjs": "tsc --build tsconfig.build.commonjs.json",
|
|
34
34
|
"build": "npm run build:esm && npm run build:commonjs",
|
|
35
|
-
"test": "cd ../..; jest packages/text-indexing",
|
|
35
|
+
"test": "cd ../..; jest --passWithNoTests packages/text-indexing",
|
|
36
36
|
"clean": "rimraf dist esm *.tsbuildinfo",
|
|
37
37
|
"prebuild": "yarn clean",
|
|
38
38
|
"prepack": "yarn build && yarn useDist",
|
|
@@ -42,6 +42,7 @@
|
|
|
42
42
|
},
|
|
43
43
|
"dependencies": {
|
|
44
44
|
"@babel/runtime": "^7.16.3",
|
|
45
|
+
"@jbrowse/core": "^2.14.0",
|
|
45
46
|
"ixixx": "^2.0.1",
|
|
46
47
|
"node-fetch": "^2.6.0",
|
|
47
48
|
"sanitize-filename": "^1.6.3"
|
|
@@ -57,5 +58,5 @@
|
|
|
57
58
|
"publishConfig": {
|
|
58
59
|
"access": "public"
|
|
59
60
|
},
|
|
60
|
-
"gitHead": "
|
|
61
|
+
"gitHead": "9fb8231d932db40adf0a283081765431756c66ff"
|
|
61
62
|
}
|