@jbrowse/text-indexing 4.3.0 → 5.0.0-beta.10

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.
@@ -1,12 +1,12 @@
1
1
  import type { indexType } from './util.ts';
2
- import type { Track } from '@jbrowse/text-indexing-core';
3
- export declare function indexTracks(args: {
2
+ import type { StatusCallback } from '@jbrowse/core/util';
3
+ import type { IndexingPolicy, Track } from '@jbrowse/text-indexing-core';
4
+ export declare function indexTracks({ tracks, outDir, policy, assemblyNames, indexType, statusCallback, signal, }: {
4
5
  tracks: Track[];
5
- outDir?: string;
6
- stopToken?: string;
7
- attributesToIndex?: string[];
6
+ outDir: string;
7
+ signal?: AbortSignal;
8
+ policy?: IndexingPolicy;
8
9
  assemblyNames?: string[];
9
- featureTypesToExclude?: string[];
10
10
  indexType?: indexType;
11
- statusCallback: (message: string) => void;
12
- }): Promise<never[]>;
11
+ statusCallback: StatusCallback | undefined;
12
+ }): Promise<void>;
@@ -1,188 +1,70 @@
1
- import fs from 'fs';
2
- import path from 'path';
3
- import { Readable } from 'stream';
4
- import { isSupportedIndexingAdapter } from '@jbrowse/core/util';
5
- import { checkStopToken } from '@jbrowse/core/util/stopToken';
6
- import { generateMeta, indexGff3, indexVcf, sanitizeForFilename, } from '@jbrowse/text-indexing-core';
7
- import { ixIxxStream } from 'ixixx';
8
- export async function indexTracks(args) {
9
- const { tracks, outDir, attributesToIndex, featureTypesToExclude, assemblyNames, indexType, statusCallback, stopToken, } = args;
10
- const idxType = indexType || 'perTrack';
11
- checkStopToken(stopToken);
12
- await (idxType === 'perTrack'
13
- ? perTrackIndex({
14
- tracks,
15
- statusCallback,
16
- outDir,
17
- attributesToIndex,
18
- featureTypesToExclude,
19
- stopToken,
20
- })
21
- : aggregateIndex({
22
- tracks,
23
- statusCallback,
24
- outDir,
25
- attributesToIndex,
26
- assemblyNames,
27
- featureTypesToExclude,
28
- stopToken,
29
- }));
30
- checkStopToken(stopToken);
31
- return [];
32
- }
33
- async function perTrackIndex({ tracks, statusCallback, outDir: paramOutDir, attributesToIndex = ['Name', 'ID'], featureTypesToExclude = ['exon', 'CDS'], stopToken, }) {
34
- const outFlag = paramOutDir || '.';
35
- const isDir = fs.lstatSync(outFlag).isDirectory();
36
- const confFilePath = isDir ? path.join(outFlag, 'config.json') : outFlag;
37
- const outDir = path.dirname(confFilePath);
38
- const trixDir = path.join(outDir, 'trix');
39
- if (!fs.existsSync(trixDir)) {
40
- fs.mkdirSync(trixDir);
41
- }
42
- const supportedTracks = tracks.filter(track => isSupportedIndexingAdapter(track.adapter?.type));
43
- for (const trackConfig of supportedTracks) {
44
- const { trackId, assemblyNames } = trackConfig;
45
- const id = `${trackId}-index`;
46
- await indexDriver({
47
- tracks: [trackConfig],
48
- outDir,
49
- attributesToIndex,
50
- name: id,
51
- featureTypesToExclude,
52
- assemblyNames,
53
- statusCallback,
54
- stopToken,
55
- });
1
+ import { checkAbortSignal } from '@jbrowse/core/util/aborting';
2
+ import { defaultIndexingPolicy, isSupportedIndexingAdapter, writeTrixIndex, } from '@jbrowse/text-indexing-core';
3
+ export async function indexTracks({ tracks, outDir, policy = defaultIndexingPolicy, assemblyNames, indexType = 'perTrack', statusCallback, signal, }) {
4
+ checkAbortSignal(signal);
5
+ const supported = tracks.filter(track => isSupportedIndexingAdapter(track.adapter?.type));
6
+ const write = (indexed, name, names) => indexDriver({
7
+ tracks: indexed,
8
+ outDir,
9
+ name,
10
+ policy,
11
+ assemblyNames: names,
12
+ statusCallback,
13
+ signal,
14
+ });
15
+ if (indexType === 'perTrack') {
16
+ for (const track of supported) {
17
+ await write([track], `${track.trackId}-index`, track.assemblyNames);
18
+ }
56
19
  }
57
- }
58
- async function aggregateIndex({ tracks, statusCallback, outDir: paramOutDir, attributesToIndex = ['Name', 'ID'], featureTypesToExclude = ['exon', 'CDS'], stopToken, assemblyNames, }) {
59
- const outFlag = paramOutDir || '.';
60
- const isDir = fs.lstatSync(outFlag).isDirectory();
61
- const confFilePath = isDir ? path.join(outFlag, 'config.json') : outFlag;
62
- const outDir = path.dirname(confFilePath);
63
- const trixDir = path.join(outDir, 'trix');
64
- if (!fs.existsSync(trixDir)) {
65
- fs.mkdirSync(trixDir);
20
+ else if (assemblyNames) {
21
+ for (const asm of assemblyNames) {
22
+ await write(supported.filter(track => track.assemblyNames.includes(asm)), `${asm}-index`, [asm]);
23
+ }
66
24
  }
67
- if (!assemblyNames) {
25
+ else {
68
26
  throw new Error('No assemblies passed. Assemblies required for aggregate indexes');
69
27
  }
70
- for (const asm of assemblyNames) {
71
- const id = `${asm}-index`;
72
- const supportedTracks = tracks
73
- .filter(track => isSupportedIndexingAdapter(track.adapter?.type))
74
- .filter(track => (asm ? track.assemblyNames.includes(asm) : true));
75
- await indexDriver({
76
- tracks: supportedTracks,
77
- outDir: outDir,
78
- attributesToIndex,
79
- name: id,
80
- featureTypesToExclude,
81
- assemblyNames: [asm],
82
- statusCallback,
83
- stopToken,
84
- });
85
- }
28
+ checkAbortSignal(signal);
86
29
  }
87
- async function indexDriver({ tracks, outDir, attributesToIndex, name, featureTypesToExclude, assemblyNames, statusCallback, stopToken, }) {
88
- const readable = Readable.from(indexFiles({
30
+ function indexDriver({ tracks, outDir, name, policy, assemblyNames, statusCallback, signal, }) {
31
+ // accumulate across tracks so an aggregate index reports monotonic progress
32
+ // rather than resetting to zero at each track. The denominator grows as each
33
+ // track's size is discovered (we don't stat every file up front), but the
34
+ // numerator only ever increases
35
+ let bankedBytes = 0;
36
+ let cumulativeTotal = 0;
37
+ statusCallback?.('Indexing files');
38
+ return writeTrixIndex({
89
39
  tracks,
90
- attributesToIndex,
91
- outDir,
92
- featureTypesToExclude,
93
- statusCallback,
94
- stopToken,
95
- }));
96
- statusCallback('Indexing files.');
97
- await runIxIxx(readable, outDir, name);
98
- checkStopToken(stopToken);
99
- generateMeta({
100
- configs: tracks,
101
- attributesToIndex,
102
40
  outDir,
103
41
  name,
104
- featureTypesToExclude,
42
+ policy,
105
43
  assemblyNames,
106
- });
107
- checkStopToken(stopToken);
108
- }
109
- async function* indexFiles({ tracks, attributesToIndex: idx1, outDir, featureTypesToExclude: edx1, statusCallback, }) {
110
- for (const track of tracks) {
111
- const { adapter, textSearching } = track;
112
- const { type } = adapter || {};
113
- const { indexingFeatureTypesToExclude: featureTypesToExclude = edx1, indexingAttributes: attributesToIndex = idx1, } = textSearching || {};
114
- let myTotalBytes;
115
- if (type === 'Gff3Adapter') {
116
- yield* indexGff3({
117
- config: track,
118
- attributesToIndex,
119
- inLocation: getLoc('gffLocation', track),
120
- outDir,
121
- featureTypesToExclude,
122
- onStart: totalBytes => {
123
- myTotalBytes = totalBytes;
44
+ checkAbort: () => {
45
+ checkAbortSignal(signal);
46
+ },
47
+ onSort: () => {
48
+ statusCallback?.('Sorting and writing index');
49
+ },
50
+ makeProgress: () => {
51
+ let trackTotal = 0;
52
+ return {
53
+ onStart: bytes => {
54
+ trackTotal = bytes;
55
+ cumulativeTotal += bytes;
124
56
  },
125
- onUpdate: progressBytes => {
126
- statusCallback(`${progressBytes}/${myTotalBytes}`);
57
+ onUpdate: bytes => {
58
+ statusCallback?.({
59
+ message: 'Indexing files',
60
+ current: bankedBytes + bytes,
61
+ total: cumulativeTotal,
62
+ });
127
63
  },
128
- });
129
- }
130
- else if (type === 'Gff3TabixAdapter') {
131
- yield* indexGff3({
132
- config: track,
133
- attributesToIndex,
134
- inLocation: getLoc('gffGzLocation', track),
135
- outDir,
136
- featureTypesToExclude,
137
- onStart: totalBytes => {
138
- myTotalBytes = totalBytes;
139
- },
140
- onUpdate: progressBytes => {
141
- statusCallback(`${progressBytes}/${myTotalBytes}`);
142
- },
143
- });
144
- }
145
- else if (type === 'VcfAdapter') {
146
- yield* indexVcf({
147
- config: track,
148
- attributesToIndex,
149
- inLocation: getLoc('vcfLocation', track),
150
- outDir,
151
- onStart: totalBytes => {
152
- myTotalBytes = totalBytes;
153
- },
154
- onUpdate: progressBytes => {
155
- statusCallback(`${progressBytes}/${myTotalBytes}`);
156
- },
157
- });
158
- }
159
- else if (type === 'VcfTabixAdapter') {
160
- yield* indexVcf({
161
- config: track,
162
- attributesToIndex,
163
- inLocation: getLoc('vcfGzLocation', track),
164
- outDir,
165
- onStart: totalBytes => {
166
- myTotalBytes = totalBytes;
64
+ onDone: () => {
65
+ bankedBytes += trackTotal;
167
66
  },
168
- onUpdate: progressBytes => {
169
- statusCallback(`${progressBytes}/${myTotalBytes}`);
170
- },
171
- });
172
- }
173
- }
174
- return;
175
- }
176
- function getLoc(attr, config) {
177
- const elt = config.adapter?.[attr];
178
- if (!elt) {
179
- throw new Error(`can't get find ${attr} from ${config.adapter} for text indexing`);
180
- }
181
- return elt.uri || elt.localPath;
182
- }
183
- function runIxIxx(readStream, idxLocation, name) {
184
- const safeName = sanitizeForFilename(name);
185
- const ixFilename = path.join(idxLocation, 'trix', `${safeName}.ix`);
186
- const ixxFilename = path.join(idxLocation, 'trix', `${safeName}.ixx`);
187
- return ixIxxStream(readStream, ixFilename, ixxFilename);
67
+ };
68
+ },
69
+ });
188
70
  }
package/esm/index.d.ts CHANGED
@@ -1,3 +1,3 @@
1
- export * from '@jbrowse/text-indexing-core';
2
- export * from './util.ts';
1
+ export { createTextSearchConf, findTrackConfigsToIndex } from './util.ts';
2
+ export type { indexType } from './util.ts';
3
3
  export { indexTracks } from './TextIndexing.ts';
package/esm/index.js CHANGED
@@ -1,3 +1,6 @@
1
- export * from '@jbrowse/text-indexing-core';
2
- export * from "./util.js";
3
- export { indexTracks } from "./TextIndexing.js";
1
+ // This package is the desktop-facing wrapper around `@jbrowse/text-indexing-core`
2
+ // — it adds `indexTracks` and the config helpers below, and nothing else. It
3
+ // deliberately re-exports none of core's surface: a symbol gets one import path,
4
+ // so the two packages cannot drift into disagreeing about the same name.
5
+ export { createTextSearchConf, findTrackConfigsToIndex } from './util.js';
6
+ export { indexTracks } from './TextIndexing.js';
package/esm/util.d.ts CHANGED
@@ -1,88 +1,15 @@
1
- import type { LocalPathLocation, Track, UriLocation } from '@jbrowse/text-indexing-core';
2
- export interface IndexedFastaAdapter {
3
- type: 'IndexedFastaAdapter';
4
- fastaLocation: UriLocation;
5
- faiLocation: UriLocation;
6
- }
7
- export interface BgzipFastaAdapter {
8
- type: 'BgzipFastaAdapter';
9
- fastaLocation: UriLocation;
10
- faiLocation: UriLocation;
11
- gziLocation: UriLocation;
12
- }
13
- export interface TwoBitAdapter {
14
- type: 'TwoBitAdapter';
15
- twoBitLocation: UriLocation;
16
- }
17
- export interface ChromeSizesAdapter {
18
- type: 'ChromSizesAdapter';
19
- chromSizesLocation: UriLocation;
20
- }
21
- export interface CustomSequenceAdapter {
22
- type: string;
23
- }
24
- export interface RefNameAliasAdapter {
25
- type: 'RefNameAliasAdapter';
26
- location: UriLocation;
27
- }
28
- export interface CustomRefNameAliasAdapter {
29
- type: string;
30
- }
31
- export interface Assembly {
32
- displayName?: string;
33
- name: string;
34
- aliases?: string[];
35
- sequence: Sequence;
36
- refNameAliases?: {
37
- adapter: RefNameAliasAdapter | CustomRefNameAliasAdapter;
38
- };
39
- refNameColors?: string[];
40
- }
41
- export interface Sequence {
42
- type: 'ReferenceSequenceTrack';
43
- trackId: string;
44
- adapter: IndexedFastaAdapter | BgzipFastaAdapter | TwoBitAdapter | ChromeSizesAdapter | CustomSequenceAdapter;
45
- }
46
- export interface TrixTextSearchAdapter {
47
- type: string;
48
- textSearchAdapterId: string;
49
- ixFilePath: UriLocation | LocalPathLocation;
50
- ixxFilePath: UriLocation | LocalPathLocation;
51
- metaFilePath: UriLocation | LocalPathLocation;
52
- assemblyNames: string[];
53
- }
54
- export interface TextSearching {
55
- indexingFeatureTypesToExclude?: string[];
56
- indexingAttributes?: string[];
57
- textSearchAdapter?: TrixTextSearchAdapter;
58
- [key: string]: unknown;
59
- }
60
- export interface Config {
61
- assemblies?: Assembly[];
62
- assembly?: Assembly;
63
- configuration?: Record<string, unknown>;
64
- aggregateTextSearchAdapters?: TrixTextSearchAdapter[];
65
- connections?: unknown[];
66
- defaultSession?: Record<string, unknown>;
67
- tracks?: Track[];
68
- }
1
+ import type { Track } from '@jbrowse/text-indexing-core';
69
2
  export type indexType = 'aggregate' | 'perTrack';
70
- export declare function createTextSearchConf(name: string, trackIds: string[], assemblyNames: string[], locationPath: string): {
71
- type: string;
72
- textSearchAdapterId: string;
3
+ export declare function createTextSearchConf(name: string, assemblyNames: string[], locationPath: string): {
4
+ type: 'TrixTextSearchAdapter';
73
5
  ixFilePath: {
74
6
  localPath: string;
75
- locationType: "LocalPathLocation";
7
+ locationType: 'LocalPathLocation';
76
8
  };
77
9
  ixxFilePath: {
78
10
  localPath: string;
79
- locationType: "LocalPathLocation";
80
- };
81
- metaFilePath: {
82
- localPath: string;
83
- locationType: "LocalPathLocation";
11
+ locationType: 'LocalPathLocation';
84
12
  };
85
- tracks: string[];
86
13
  assemblyNames: string[];
87
14
  };
88
- export declare function findTrackConfigsToIndex(tracks: Track[], trackIds: string[], assemblyName?: string): Track[];
15
+ export declare function findTrackConfigsToIndex(tracks: Track[], trackIds: string[]): Track[];
package/esm/util.js CHANGED
@@ -1,29 +1,20 @@
1
- import path from 'path';
2
- import { isSupportedIndexingAdapter } from '@jbrowse/core/util';
3
- import { sanitizeForFilename } from '@jbrowse/text-indexing-core';
4
- export function createTextSearchConf(name, trackIds, assemblyNames, locationPath) {
5
- const base = path.join(locationPath, 'trix');
6
- const n = sanitizeForFilename(name);
1
+ import { isSupportedIndexingAdapter, trixFilePaths, } from '@jbrowse/text-indexing-core';
2
+ export function createTextSearchConf(name, assemblyNames, locationPath) {
3
+ const paths = trixFilePaths(locationPath, name);
7
4
  return {
8
5
  type: 'TrixTextSearchAdapter',
9
- textSearchAdapterId: name,
10
6
  ixFilePath: {
11
- localPath: path.join(base, `${n}.ix`),
7
+ localPath: paths.ix,
12
8
  locationType: 'LocalPathLocation',
13
9
  },
14
10
  ixxFilePath: {
15
- localPath: path.join(base, `${n}.ixx`),
11
+ localPath: paths.ixx,
16
12
  locationType: 'LocalPathLocation',
17
13
  },
18
- metaFilePath: {
19
- localPath: path.join(base, `${n}_meta.json`),
20
- locationType: 'LocalPathLocation',
21
- },
22
- tracks: trackIds,
23
14
  assemblyNames,
24
15
  };
25
16
  }
26
- export function findTrackConfigsToIndex(tracks, trackIds, assemblyName) {
17
+ export function findTrackConfigsToIndex(tracks, trackIds) {
27
18
  return trackIds
28
19
  .map(trackId => {
29
20
  const currentTrack = tracks.find(t => trackId === t.trackId);
@@ -32,6 +23,5 @@ export function findTrackConfigsToIndex(tracks, trackIds, assemblyName) {
32
23
  }
33
24
  return currentTrack;
34
25
  })
35
- .filter(track => assemblyName ? track.assemblyNames.includes(assemblyName) : true)
36
26
  .filter(track => isSupportedIndexingAdapter(track.adapter?.type));
37
27
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jbrowse/text-indexing",
3
- "version": "4.3.0",
3
+ "version": "5.0.0-beta.10",
4
4
  "type": "module",
5
5
  "description": "JBrowse 2 text indexing for desktop",
6
6
  "keywords": [
@@ -20,34 +20,31 @@
20
20
  },
21
21
  "author": "JBrowse Team",
22
22
  "main": "esm/index.js",
23
+ "exports": {
24
+ ".": "./esm/index.js",
25
+ "./util": "./esm/util.js"
26
+ },
23
27
  "files": [
24
28
  "esm"
25
29
  ],
26
30
  "dependencies": {
27
- "ixixx": "^3.0.4",
28
- "@jbrowse/text-indexing-core": "^4.3.0",
29
- "@jbrowse/core": "^4.3.0"
31
+ "@jbrowse/core": "^5.0.0-beta.10",
32
+ "@jbrowse/text-indexing-core": "^5.0.0-beta.10"
30
33
  },
31
34
  "peerDependencies": {
32
- "react": ">=18.0.0",
33
- "react-dom": ">=18.0.0"
35
+ "react": ">=19.0.0",
36
+ "react-dom": ">=19.0.0"
34
37
  },
35
38
  "publishConfig": {
36
39
  "access": "public"
37
40
  },
38
41
  "sideEffects": false,
39
42
  "scripts": {
40
- "build:esm": "tsc -p tsconfig.build.esm.json",
43
+ "build:esm": "node ../../node_modules/typescript7/bin/tsc --build tsconfig.build.esm.json",
41
44
  "build": "pnpm build:esm",
42
45
  "test": "cd ../..; jest --passWithNoTests packages/text-indexing",
43
46
  "clean": "rimraf esm *.tsbuildinfo",
44
47
  "prebuild": "pnpm clean"
45
48
  },
46
- "types": "esm/index.d.ts",
47
- "exports": {
48
- ".": {
49
- "types": "./esm/index.d.ts",
50
- "import": "./esm/index.js"
51
- }
52
- }
49
+ "types": "esm/index.d.ts"
53
50
  }