Skip to content

Commit 997e467

Browse files
cmdcolinclaude
andcommitted
fix: correct multi-location feature handling in parseRecordsJBrowse, misc cleanup
- Fix bug where duplicate IDs in JBrowse parsing would still process parent relationships on the discarded feature, creating dangling subfeature refs - Reorder FASTA/> break checks before comment skip in stringToRecords - Simplify parseDirective to use direct index access instead of two destructures - Remove dead _lineHash skip in parseAttributesJBrowseImpl - Use trimEnd Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent 5ba1ffb commit 997e467

2 files changed

Lines changed: 23 additions & 32 deletions

File tree

src/api.ts

Lines changed: 16 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -44,15 +44,12 @@ function stringToRecords(str: string) {
4444
const lines = str.split(/\r?\n/)
4545
const records: LineRecord[] = []
4646
for (const line of lines) {
47+
if (line.startsWith('##FASTA') || line.startsWith('>')) {
48+
break
49+
}
4750
if (line.length === 0 || line.startsWith('#')) {
48-
if (line.startsWith('##FASTA')) {
49-
break
50-
}
5151
continue
5252
}
53-
if (line.startsWith('>')) {
54-
break
55-
}
5653
records.push({
5754
line,
5855
start: 0,
@@ -174,20 +171,21 @@ export function parseRecordsJBrowse(records: LineRecord[]): JBrowseFeature[] {
174171
continue
175172
}
176173

174+
if (id && byId.has(id)) {
175+
continue
176+
}
177+
177178
if (id) {
178-
const existing = byId.get(id)
179-
if (!existing) {
180-
if (!parent) {
181-
items.push(feature)
182-
}
183-
byId.set(id, feature)
184-
const waiting = orphans.get(id)
185-
if (waiting) {
186-
for (const w of waiting) {
187-
feature.subfeatures.push(w)
188-
}
189-
orphans.delete(id)
179+
if (!parent) {
180+
items.push(feature)
181+
}
182+
byId.set(id, feature)
183+
const waiting = orphans.get(id)
184+
if (waiting) {
185+
for (const w of waiting) {
186+
feature.subfeatures.push(w)
190187
}
188+
orphans.delete(id)
191189
}
192190
}
193191

src/util.ts

Lines changed: 7 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
// JavaScript port of Robert Buels's Bio::GFF3::LowLevel Perl module.
33

44
const directiveRegex = /^\s*##\s*(\S+)\s*(.*)/
5-
const lineEndRegex = /\r?\n$/
65
const whitespaceRegex = /\s+/
76
const nonDigitRegex = /\D/g
87

@@ -252,25 +251,24 @@ export function parseDirective(
252251
return null
253252
}
254253

255-
const [, name] = match
256-
let [, , contents] = match
254+
const name = match[1]!
255+
let contents = match[2]!
257256

258-
const parsed: GFF3Directive = { directive: name! }
259-
if (contents!.length) {
260-
contents = contents!.replace(lineEndRegex, '')
261-
parsed.value = contents
257+
const parsed: GFF3Directive = { directive: name }
258+
if (contents.length) {
259+
parsed.value = contents.trimEnd()
262260
}
263261

264262
if (name === 'sequence-region') {
265-
const c = contents!.split(whitespaceRegex, 3)
263+
const c = contents.split(whitespaceRegex, 3)
266264
return {
267265
...parsed,
268266
seq_id: c[0]!,
269267
start: c[1]!.replaceAll(nonDigitRegex, ''),
270268
end: c[2]!.replaceAll(nonDigitRegex, ''),
271269
}
272270
} else if (name === 'genome-build') {
273-
const [source, buildName] = contents!.split(whitespaceRegex, 2)
271+
const [source, buildName] = contents.split(whitespaceRegex, 2)
274272
return {
275273
...parsed,
276274
source: source!,
@@ -446,11 +444,6 @@ function parseAttributesJBrowseImpl(
446444
const eqIdx = attrString.indexOf('=', start)
447445
if (eqIdx !== -1 && eqIdx < semiIdx && eqIdx + 1 < semiIdx) {
448446
const tag = attrString.slice(start, eqIdx)
449-
if (tag === '_lineHash') {
450-
start = semiIdx + 1
451-
continue
452-
}
453-
454447
let key = COMMON_ATTRS[tag]
455448
if (key === undefined) {
456449
key = tag.toLowerCase()

0 commit comments

Comments
 (0)