@jbrowse/graph-walks 0.0.0-stage → 0.1.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.
@@ -0,0 +1,589 @@
1
+ // Format 2 of gfa-to-tabix --walks, one file per reference (that repo's
2
+ // docs/walks-format.md). A chunk lists its `ref` rows, which joined in
3
+ // hapOffset order are the chunk's reference path R; a `nodes` row with the
4
+ // lengths of the nodes its routes visit; `route` rows, each a way off R; and a
5
+ // `walk` row per piece of every other path, naming the routes it takes in
6
+ // order. A handle is 2 * id + 1 when reversed.
7
+ const NONE = -1;
8
+ const idOf = (handle) => (handle - (handle & 1)) / 2;
9
+ // the other strand's handle; arithmetic, which holds past 2^31
10
+ const otherStrand = (handle) => (handle & 1 ? handle - 1 : handle + 1);
11
+ // The handles a column of delta tokens names, each 2 * (id - previous id) +
12
+ // reverse, from `previous.id`, which ends on the last id read
13
+ function tokens(field, previous, out) {
14
+ if (field === '.') {
15
+ return out;
16
+ }
17
+ let v = 0;
18
+ let neg = false;
19
+ for (let p = 0; p <= field.length; p++) {
20
+ const ch = p < field.length ? field.charCodeAt(p) : 44;
21
+ if (ch === 44) {
22
+ const d = neg ? -v : v;
23
+ const r = d & 1;
24
+ previous.id += (d - r) / 2;
25
+ out.push(previous.id * 2 + r);
26
+ v = 0;
27
+ neg = false;
28
+ }
29
+ else if (ch === 45) {
30
+ neg = true;
31
+ }
32
+ else {
33
+ v = v * 10 + (ch - 48);
34
+ }
35
+ }
36
+ return out;
37
+ }
38
+ function numbers(field) {
39
+ return field === '.' ? [] : field.split(',').map(Number);
40
+ }
41
+ // A link the way round the converter writes it, so a link and its reverse
42
+ // are one: the smaller of a and the flipped b first
43
+ export function canonicalLink(a, b) {
44
+ return a > otherStrand(b) ? [otherStrand(b), otherStrand(a)] : [a, b];
45
+ }
46
+ function tags(cols, from, anchor) {
47
+ let prev;
48
+ let next;
49
+ for (let k = from; k < cols.length; k++) {
50
+ const tag = cols[k];
51
+ if (tag.startsWith('pv:') || tag.startsWith('nx:')) {
52
+ const at = tag.lastIndexOf(':');
53
+ const chunk = {
54
+ refName: tag[3] === 'Z' ? tag.slice(5, at) : anchor,
55
+ start: +tag.slice(at + 1),
56
+ };
57
+ if (tag.startsWith('pv:')) {
58
+ prev = chunk;
59
+ }
60
+ else {
61
+ next = chunk;
62
+ }
63
+ }
64
+ }
65
+ return { prev, next };
66
+ }
67
+ // The chunk's reference path R: its handles, the bp of its steps before each
68
+ // position, and each node's occurrences in R
69
+ export class RefPath {
70
+ constructor() {
71
+ this.handles = [];
72
+ this.before = [0];
73
+ this.occurrences = new Map();
74
+ }
75
+ add(handles, lengths) {
76
+ for (let k = 0; k < handles.length; k++) {
77
+ const h = handles[k];
78
+ const i = this.handles.length;
79
+ this.handles.push(h);
80
+ this.before.push(this.before[i] + lengths[k]);
81
+ const id = idOf(h);
82
+ const list = this.occurrences.get(id);
83
+ if (list) {
84
+ list.push(i);
85
+ }
86
+ else {
87
+ this.occurrences.set(id, [i]);
88
+ }
89
+ }
90
+ }
91
+ // bp of R's steps before position i
92
+ bp(i) {
93
+ return this.before[i];
94
+ }
95
+ first(handle) {
96
+ var _a;
97
+ return (_a = this.occurrences.get(idOf(handle))) === null || _a === void 0 ? void 0 : _a[0];
98
+ }
99
+ nearest(handle, i) {
100
+ var _a;
101
+ let best;
102
+ for (const j of (_a = this.occurrences.get(idOf(handle))) !== null && _a !== void 0 ? _a : []) {
103
+ if (best === undefined || Math.abs(j - i) <= Math.abs(best - i)) {
104
+ best = j;
105
+ }
106
+ }
107
+ return best;
108
+ }
109
+ // The position a stretch along R from position i, reading R the way `h`
110
+ // does there, first holds `target`, i itself included
111
+ reach(i, h, target) {
112
+ var _a;
113
+ const forward = this.handles[i] === h;
114
+ let found;
115
+ for (const j of (_a = this.occurrences.get(idOf(target))) !== null && _a !== void 0 ? _a : []) {
116
+ if (forward && j >= i && this.handles[j] === target) {
117
+ if (found === undefined || j < found) {
118
+ found = j;
119
+ }
120
+ }
121
+ else if (!forward &&
122
+ j <= i &&
123
+ otherStrand(this.handles[j]) === target) {
124
+ if (found === undefined || j > found) {
125
+ found = j;
126
+ }
127
+ }
128
+ }
129
+ return found;
130
+ }
131
+ handleAt(i, forward) {
132
+ return forward ? this.handles[i] : otherStrand(this.handles[i]);
133
+ }
134
+ }
135
+ export class WalkRowError extends Error {
136
+ }
137
+ const orientedEntry = (route, flip) => flip ? (route.exit === NONE ? NONE : otherStrand(route.exit)) : route.entry;
138
+ const orientedExit = (route, flip) => flip ? (route.entry === NONE ? NONE : otherStrand(route.entry)) : route.exit;
139
+ // A route's interior handle k, taken the way round `flip` says
140
+ const interiorAt = (route, flip, k) => flip
141
+ ? otherStrand(route.interior[route.interior.length - 1 - k])
142
+ : route.interior[k];
143
+ // A walk row's choices, three numbers each: route index, flip and step count,
144
+ // from `tok` or `tok:count` tokens
145
+ function parseChoices(field) {
146
+ const choices = [];
147
+ if (field !== '.') {
148
+ let previous = 0;
149
+ let v = 0;
150
+ let neg = false;
151
+ let tok = 0;
152
+ let colonSeen = false;
153
+ for (let p = 0; p <= field.length; p++) {
154
+ const ch = p < field.length ? field.charCodeAt(p) : 44;
155
+ if (ch === 44) {
156
+ const value = neg ? -v : v;
157
+ const d = colonSeen ? tok : value;
158
+ const r = d & 1;
159
+ previous += (d - r) / 2;
160
+ choices.push(previous, r, colonSeen ? value : 0);
161
+ v = 0;
162
+ neg = false;
163
+ colonSeen = false;
164
+ }
165
+ else if (ch === 58) {
166
+ tok = neg ? -v : v;
167
+ v = 0;
168
+ neg = false;
169
+ colonSeen = true;
170
+ }
171
+ else if (ch === 45) {
172
+ neg = true;
173
+ }
174
+ else {
175
+ v = v * 10 + (ch - 48);
176
+ }
177
+ }
178
+ }
179
+ return choices;
180
+ }
181
+ // Follows a walk row as docs/walks-format.md decodes it
182
+ function traverse(path, routes, start, endField, choices, visit) {
183
+ const colon = endField.indexOf(':');
184
+ const end = start + +(colon < 0 ? endField : endField.slice(0, colon));
185
+ const counted = colon >= 0;
186
+ const tail = counted ? +endField.slice(colon + 1) : 0;
187
+ const routeOf = (index) => {
188
+ const route = routes[index];
189
+ if (!route) {
190
+ throw new WalkRowError(`route ${index} is not in the chunk`);
191
+ }
192
+ return route;
193
+ };
194
+ let k = 0;
195
+ if (choices.length > 0 &&
196
+ orientedEntry(routeOf(choices[0]), choices[1] === 1) === NONE) {
197
+ if (!visit.route(choices[0], choices[1] === 1)) {
198
+ return;
199
+ }
200
+ k = 3;
201
+ }
202
+ let h = start;
203
+ let i = path.first(h);
204
+ if (i === undefined) {
205
+ throw new WalkRowError('a walk row starts off its chunk');
206
+ }
207
+ visit.step(h);
208
+ const follow = (target, count) => {
209
+ const forward = path.handles[i] === h;
210
+ const j = counted
211
+ ? i + (forward ? count : -count)
212
+ : path.reach(i, h, target);
213
+ if (j === undefined || j < 0 || j >= path.handles.length) {
214
+ throw new WalkRowError('a walk row runs off its chunk');
215
+ }
216
+ if (j !== i) {
217
+ visit.stretch(i, j, forward);
218
+ }
219
+ i = j;
220
+ h = path.handleAt(j, forward);
221
+ };
222
+ for (; k < choices.length; k += 3) {
223
+ const index = choices[k];
224
+ const flip = choices[k + 1] === 1;
225
+ const route = routeOf(index);
226
+ const entry = orientedEntry(route, flip);
227
+ if (entry === NONE) {
228
+ throw new WalkRowError('an open route after the first choice');
229
+ }
230
+ follow(entry, choices[k + 2]);
231
+ if (!visit.route(index, flip)) {
232
+ return;
233
+ }
234
+ const exit = orientedExit(route, flip);
235
+ if (exit === NONE) {
236
+ return;
237
+ }
238
+ h = exit;
239
+ i = path.nearest(h, i);
240
+ if (i === undefined) {
241
+ throw new WalkRowError('a route lands off its chunk');
242
+ }
243
+ visit.step(h);
244
+ }
245
+ follow(end, tail);
246
+ if (h !== end) {
247
+ throw new WalkRowError('a walk row misses its last handle');
248
+ }
249
+ }
250
+ // A walk row's steps as node ids and reverse flags
251
+ function decodeWalk(path, routes, cols, choices, n) {
252
+ const ids = new Int32Array(n);
253
+ const rev = new Uint8Array(n);
254
+ let at = 0;
255
+ const push = (h) => {
256
+ if (at >= n) {
257
+ throw new WalkRowError('a walk row decodes to more steps than it states');
258
+ }
259
+ ids[at] = idOf(h);
260
+ rev[at++] = h & 1;
261
+ };
262
+ traverse(path, routes, +cols[9], cols[10], choices, {
263
+ step: push,
264
+ stretch(from, to, forward) {
265
+ if (forward) {
266
+ for (let j = from + 1; j <= to; j++) {
267
+ push(path.handles[j]);
268
+ }
269
+ }
270
+ else {
271
+ for (let j = from - 1; j >= to; j--) {
272
+ push(otherStrand(path.handles[j]));
273
+ }
274
+ }
275
+ },
276
+ route(index, flip) {
277
+ const route = routes[index];
278
+ for (let k = 0; k < route.interior.length; k++) {
279
+ push(interiorAt(route, flip, k));
280
+ }
281
+ return true;
282
+ },
283
+ });
284
+ if (at !== n) {
285
+ throw new WalkRowError(`a walk row decodes to ${at} steps, not ${n}`);
286
+ }
287
+ return { ids, rev };
288
+ }
289
+ /**
290
+ * Decodes one chunk's rows, each split on tabs. `keep` names the walk rows
291
+ * whose steps a cut wants, undefined for every one.
292
+ */
293
+ export function decodeChunk(rows, keep) {
294
+ var _a, _b, _c;
295
+ const path = new RefPath();
296
+ const lengths = new Map();
297
+ const routes = [];
298
+ const out = {
299
+ rows: [],
300
+ nodes: new Map(),
301
+ ends: [],
302
+ chunk: { path, routes, walks: [], lengths },
303
+ };
304
+ const previous = { id: 0 };
305
+ const refs = rows.filter(c => c[3] === 'ref').sort((a, b) => +a[6] - +b[6]);
306
+ for (const cols of refs) {
307
+ const anchor = cols[0];
308
+ const handles = tokens(cols[9], { id: 0 }, []);
309
+ const nodeLengths = numbers(cols[10]);
310
+ const hapOffset = +cols[6];
311
+ path.add(handles, nodeLengths);
312
+ let start = hapOffset;
313
+ for (let k = 0; k < handles.length; k++) {
314
+ const id = idOf(handles[k]);
315
+ const length = nodeLengths[k];
316
+ lengths.set(id, length);
317
+ if (!out.nodes.has(id)) {
318
+ out.nodes.set(id, {
319
+ refName: cols[4],
320
+ start,
321
+ end: start + length,
322
+ rank: 0,
323
+ });
324
+ }
325
+ start += length;
326
+ }
327
+ out.ends.push({
328
+ name: cols[4],
329
+ fragStart: +cols[5],
330
+ piece: +cols[7],
331
+ first: handles[0],
332
+ last: handles.at(-1),
333
+ });
334
+ if (keep === undefined || keep(cols[4])) {
335
+ out.rows.push({
336
+ chunkStart: +cols[1],
337
+ name: cols[4],
338
+ fragStart: +cols[5],
339
+ hapOffset,
340
+ piece: +cols[7],
341
+ n: handles.length,
342
+ enc: '',
343
+ steps: {
344
+ ids: Int32Array.from(handles, idOf),
345
+ rev: Uint8Array.from(handles, h => h & 1),
346
+ },
347
+ ...tags(cols, 11, anchor),
348
+ });
349
+ }
350
+ }
351
+ for (const cols of rows) {
352
+ if (cols[3] === 'nodes') {
353
+ const ids = numbers(cols[4]);
354
+ const nodeLengths = numbers(cols[5]);
355
+ let id = 0;
356
+ for (let k = 0; k < ids.length; k++) {
357
+ id += ids[k];
358
+ lengths.set(id, nodeLengths[k]);
359
+ }
360
+ }
361
+ else if (cols[3] === 'route') {
362
+ const entry = tokens(cols[4], previous, []);
363
+ const interior = tokens(cols[5], previous, []);
364
+ const exit = tokens(cols[6], previous, []);
365
+ routes.push({ entry: (_a = entry[0]) !== null && _a !== void 0 ? _a : NONE, interior, exit: (_b = exit[0]) !== null && _b !== void 0 ? _b : NONE });
366
+ }
367
+ }
368
+ const routeOf = (index) => {
369
+ const route = routes[index];
370
+ if (!route) {
371
+ throw new WalkRowError(`route ${index} is not in the chunk`);
372
+ }
373
+ return route;
374
+ };
375
+ for (const cols of rows) {
376
+ if (cols[3] !== 'walk') {
377
+ continue;
378
+ }
379
+ const choices = parseChoices(cols[11]);
380
+ out.chunk.walks.push({ cols, choices });
381
+ const name = cols[4];
382
+ const start = +cols[9];
383
+ const endField = cols[10];
384
+ const colon = endField.indexOf(':');
385
+ let first = start;
386
+ let last = start + +(colon < 0 ? endField : endField.slice(0, colon));
387
+ if (choices.length > 0) {
388
+ const lead = routeOf(choices[0]);
389
+ const leadFlip = choices[1] === 1;
390
+ if (orientedEntry(lead, leadFlip) === NONE) {
391
+ first = interiorAt(lead, leadFlip, 0);
392
+ }
393
+ const at = choices.length - 3;
394
+ const tail = routeOf(choices[at]);
395
+ const tailFlip = choices[at + 1] === 1;
396
+ if (orientedExit(tail, tailFlip) === NONE) {
397
+ last = interiorAt(tail, tailFlip, tail.interior.length - 1);
398
+ }
399
+ }
400
+ out.ends.push({
401
+ name,
402
+ fragStart: +cols[5],
403
+ piece: +cols[7],
404
+ first,
405
+ last,
406
+ });
407
+ if (keep === undefined || keep(name)) {
408
+ const n = +cols[8];
409
+ // the walk's nodes off R, by length; placeAndLink gives their position
410
+ for (let k = 0; k < choices.length; k += 3) {
411
+ for (const h of routeOf(choices[k]).interior) {
412
+ const id = idOf(h);
413
+ if (!out.nodes.has(id)) {
414
+ const length = (_c = lengths.get(id)) !== null && _c !== void 0 ? _c : 0;
415
+ out.nodes.set(id, { refName: name, start: 0, end: length, rank: 1 });
416
+ }
417
+ }
418
+ }
419
+ out.rows.push({
420
+ chunkStart: +cols[1],
421
+ name,
422
+ fragStart: +cols[5],
423
+ hapOffset: +cols[6],
424
+ piece: +cols[7],
425
+ n,
426
+ enc: '',
427
+ steps: decodeWalk(path, routes, cols, choices, n),
428
+ ...tags(cols, 12, cols[0]),
429
+ });
430
+ }
431
+ }
432
+ return out;
433
+ }
434
+ /**
435
+ * The positions of the cut's nodes off R, and the links among the cut's
436
+ * nodes, from the chunks a cut read: `kept` holds the node ids the cut draws.
437
+ * A node off R takes its position from the path whose name sorts first among
438
+ * those visiting it in the chunks read, at its earliest offset, as format 1's
439
+ * node rows had it. Links are R's and the routes', both ends in the cut.
440
+ */
441
+ export function placeAndLink(chunks, kept, place, link) {
442
+ const best = new Map();
443
+ for (const { path, routes, walks, lengths } of chunks) {
444
+ const handles = path.handles;
445
+ for (let k = 1; k < handles.length; k++) {
446
+ if (kept.has(idOf(handles[k - 1])) && kept.has(idOf(handles[k]))) {
447
+ link(...canonicalLink(handles[k - 1], handles[k]));
448
+ }
449
+ }
450
+ // routes holding a node of the cut off R
451
+ const wanted = new Uint8Array(routes.length);
452
+ for (let index = 0; index < routes.length; index++) {
453
+ const { entry, interior, exit } = routes[index];
454
+ let any = false;
455
+ let from = entry;
456
+ for (const h of interior) {
457
+ const inCut = kept.has(idOf(h));
458
+ any || (any = inCut);
459
+ if (inCut && from !== NONE && kept.has(idOf(from))) {
460
+ link(...canonicalLink(from, h));
461
+ }
462
+ from = h;
463
+ }
464
+ if (from !== NONE &&
465
+ exit !== NONE &&
466
+ kept.has(idOf(from)) &&
467
+ kept.has(idOf(exit))) {
468
+ link(...canonicalLink(from, exit));
469
+ }
470
+ wanted[index] = any ? 1 : 0;
471
+ }
472
+ const lengthOf = (h) => { var _a; return (_a = lengths.get(idOf(h))) !== null && _a !== void 0 ? _a : 0; };
473
+ const bp = new Float64Array(routes.length).fill(-1);
474
+ const routeBp = (index) => {
475
+ if (bp[index] < 0) {
476
+ bp[index] = routes[index].interior.reduce((s, h) => s + lengthOf(h), 0);
477
+ }
478
+ return bp[index];
479
+ };
480
+ // Walk rows run in path-name order, so a route's first taker is the
481
+ // first-named path to reach its nodes here; each row is followed only as
482
+ // far as the last route it is first to take
483
+ const taken = new Uint8Array(routes.length);
484
+ for (const { cols, choices } of walks) {
485
+ let remaining = 0;
486
+ for (let k = 0; k < choices.length; k += 3) {
487
+ const index = choices[k];
488
+ if (wanted[index] && !taken[index]) {
489
+ remaining++;
490
+ }
491
+ }
492
+ if (remaining === 0) {
493
+ continue;
494
+ }
495
+ const name = cols[4];
496
+ let offset = +cols[6];
497
+ traverse(path, routes, +cols[9], cols[10], choices, {
498
+ step(h) {
499
+ offset += lengthOf(h);
500
+ },
501
+ stretch(from, to, forward) {
502
+ offset += forward
503
+ ? path.bp(to + 1) - path.bp(from + 1)
504
+ : path.bp(from) - path.bp(to);
505
+ },
506
+ route(index, flip) {
507
+ if (!wanted[index] || taken[index]) {
508
+ offset += routeBp(index);
509
+ return true;
510
+ }
511
+ taken[index] = 1;
512
+ const route = routes[index];
513
+ for (let k = 0; k < route.interior.length; k++) {
514
+ const h = interiorAt(route, flip, k);
515
+ const id = idOf(h);
516
+ const length = lengthOf(h);
517
+ if (kept.has(id)) {
518
+ const held = best.get(id);
519
+ if (!held ||
520
+ name < held.refName ||
521
+ (name === held.refName && offset < held.start)) {
522
+ best.set(id, {
523
+ refName: name,
524
+ start: offset,
525
+ end: offset + length,
526
+ rank: 1,
527
+ });
528
+ }
529
+ }
530
+ offset += length;
531
+ }
532
+ remaining--;
533
+ return remaining > 0;
534
+ },
535
+ });
536
+ }
537
+ }
538
+ for (const [id, node] of best) {
539
+ place(id, node);
540
+ }
541
+ }
542
+ // The reference's nodes in a chunk's ref rows, with their positions
543
+ export function referenceNodes(rows) {
544
+ const nodes = [];
545
+ for (const cols of rows) {
546
+ if (cols[3] !== 'ref') {
547
+ continue;
548
+ }
549
+ const handles = tokens(cols[9], { id: 0 }, []);
550
+ const nodeLengths = numbers(cols[10]);
551
+ let start = +cols[6];
552
+ for (let k = 0; k < handles.length; k++) {
553
+ const length = nodeLengths[k];
554
+ nodes.push({
555
+ id: idOf(handles[k]),
556
+ refName: cols[4],
557
+ start,
558
+ end: start + length,
559
+ rank: 0,
560
+ });
561
+ start += length;
562
+ }
563
+ }
564
+ return nodes;
565
+ }
566
+ // Links between consecutive pieces of a path, each piece's last step to the
567
+ // next one's first, among the pieces read
568
+ export function pieceLinks(ends) {
569
+ const byPath = new Map();
570
+ for (const e of ends) {
571
+ const key = `${e.name}\t${e.fragStart}`;
572
+ let pieces = byPath.get(key);
573
+ if (!pieces) {
574
+ pieces = new Map();
575
+ byPath.set(key, pieces);
576
+ }
577
+ pieces.set(e.piece, e);
578
+ }
579
+ const links = [];
580
+ for (const pieces of byPath.values()) {
581
+ for (const [piece, e] of pieces) {
582
+ const next = pieces.get(piece + 1);
583
+ if (next) {
584
+ links.push(canonicalLink(e.last, next.first));
585
+ }
586
+ }
587
+ }
588
+ return links;
589
+ }
@@ -0,0 +1,77 @@
1
+ import { WalkGraph } from './walkRows.ts';
2
+ import type { BudgetNames, WalkHeader } from './walkRows.ts';
3
+ /**
4
+ * A Tabix-indexed file as the reader uses one: @gmod/tabix's
5
+ * TabixIndexedFile is one. `bytesForRegions` estimates the compressed bytes a
6
+ * read fetches, which the byte budget needs.
7
+ */
8
+ export interface TabixSource {
9
+ getHeaderLines(opts?: {
10
+ signal?: AbortSignal;
11
+ }): Promise<string[]>;
12
+ getLines(refName: string, start: number, end: number, opts: {
13
+ signal?: AbortSignal;
14
+ lineCallback: (line: string) => void;
15
+ }): Promise<void>;
16
+ getReferenceSequenceNames(opts?: {
17
+ signal?: AbortSignal;
18
+ }): Promise<string[]>;
19
+ bytesForRegions?(regions: {
20
+ refName: string;
21
+ start: number;
22
+ end: number;
23
+ }[], opts?: {
24
+ signal?: AbortSignal;
25
+ }): Promise<number>;
26
+ }
27
+ export interface WalkFileSet {
28
+ walks: TabixSource;
29
+ nodes?: TabixSource;
30
+ links?: TabixSource;
31
+ }
32
+ export interface WalkCutOptions {
33
+ signal?: AbortSignal;
34
+ keep?: (name: string) => boolean;
35
+ stepBudget?: number;
36
+ byteBudget?: number;
37
+ context?: number;
38
+ links?: boolean;
39
+ sequences?: boolean;
40
+ budgetNames?: BudgetNames;
41
+ }
42
+ export type WalkReaderHeader = WalkHeader & {
43
+ chunk: number;
44
+ lookback: number;
45
+ };
46
+ /**
47
+ * A walk-indexed graph's three files, read a window at a time: one read of
48
+ * each over whole chunks, from the lookback chunks before the window to its
49
+ * end. The indexes first estimate the bytes those reads fetch, and a window
50
+ * past the byte budget reads no row. Only the walks `keep` accepts are
51
+ * decoded. The step budget bounds the steps the cut keeps, and rows holding
52
+ * READ_STEPS_PER_KEPT times as many stop the reads, which go out together.
53
+ */
54
+ export declare class WalkReader {
55
+ private headerRead;
56
+ private readonly files;
57
+ private readonly chunkWithoutHeader;
58
+ constructor(files: WalkFileSet, chunkWithoutHeader?: number);
59
+ header(opts?: {
60
+ signal?: AbortSignal;
61
+ }): Promise<WalkReaderHeader>;
62
+ referenceSequences(opts?: {
63
+ signal?: AbortSignal;
64
+ }): Promise<string[]>;
65
+ queryStart(start: number, opts?: {
66
+ signal?: AbortSignal;
67
+ }): Promise<number>;
68
+ cut(refName: string, region: {
69
+ start: number;
70
+ end: number;
71
+ }, opts?: WalkCutOptions): Promise<{
72
+ kept: Set<number>;
73
+ fragments: import("./walkRows.ts").WalkFragment[];
74
+ open: import("./walkRows.ts").WalkChunk[];
75
+ graph: WalkGraph;
76
+ }>;
77
+ }