msa-parsers 5.10.0 → 6.0.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 (49) hide show
  1. package/dist/gff/annotationsToGFF.d.ts +9 -0
  2. package/dist/gff/annotationsToGFF.js +36 -0
  3. package/dist/gff/annotationsToGFF.js.map +1 -0
  4. package/dist/gff/gffToAnnotations.d.ts +9 -0
  5. package/dist/gff/gffToAnnotations.js +53 -0
  6. package/dist/gff/gffToAnnotations.js.map +1 -0
  7. package/dist/gff/gffToAnnotations.test.js +71 -0
  8. package/dist/gff/gffToAnnotations.test.js.map +1 -0
  9. package/dist/gff/index.d.ts +2 -1
  10. package/dist/gff/index.js +2 -1
  11. package/dist/gff/index.js.map +1 -1
  12. package/dist/gff/interProToGFF.d.ts +3 -2
  13. package/dist/gff/interProToGFF.js +7 -43
  14. package/dist/gff/interProToGFF.js.map +1 -1
  15. package/dist/gff/interProToGFF.test.js +3 -2
  16. package/dist/gff/interProToGFF.test.js.map +1 -1
  17. package/dist/index.d.ts +2 -1
  18. package/dist/index.js +3 -1
  19. package/dist/index.js.map +1 -1
  20. package/dist/interProScanToAnnotations.d.ts +21 -0
  21. package/dist/interProScanToAnnotations.js +38 -0
  22. package/dist/interProScanToAnnotations.js.map +1 -0
  23. package/dist/types.d.ts +24 -0
  24. package/dist/util.d.ts +10 -0
  25. package/dist/util.js +27 -6
  26. package/dist/util.js.map +1 -1
  27. package/dist/util.test.d.ts +1 -0
  28. package/dist/util.test.js +40 -0
  29. package/dist/util.test.js.map +1 -0
  30. package/package.json +1 -1
  31. package/src/gff/annotationsToGFF.ts +37 -0
  32. package/src/gff/gffToAnnotations.test.ts +85 -0
  33. package/src/gff/gffToAnnotations.ts +59 -0
  34. package/src/gff/index.ts +2 -1
  35. package/src/gff/interProToGFF.test.ts +3 -2
  36. package/src/gff/interProToGFF.ts +11 -50
  37. package/src/index.ts +9 -2
  38. package/src/interProScanToAnnotations.ts +55 -0
  39. package/src/types.ts +25 -0
  40. package/src/util.test.ts +47 -0
  41. package/src/util.ts +29 -9
  42. package/dist/gff/gffToInterPro.d.ts +0 -6
  43. package/dist/gff/gffToInterPro.js +0 -90
  44. package/dist/gff/gffToInterPro.js.map +0 -1
  45. package/dist/gff/gffToInterPro.test.js +0 -241
  46. package/dist/gff/gffToInterPro.test.js.map +0 -1
  47. package/src/gff/gffToInterPro.test.ts +0 -265
  48. package/src/gff/gffToInterPro.ts +0 -122
  49. /package/dist/gff/{gffToInterPro.test.d.ts → gffToAnnotations.test.d.ts} +0 -0
@@ -0,0 +1,9 @@
1
+ import type { Annotation } from '../types.ts';
2
+ /**
3
+ * Write annotations as GFF3, one line per annotation, in list order.
4
+ *
5
+ * The source column is always `InterProScan`: an Annotation records no source
6
+ * of its own, and the CLI's precomputed-lookup path depends on this output
7
+ * matching what a real InterProScan run emits, byte for byte.
8
+ */
9
+ export declare function annotationsToGFF(annotations: Annotation[]): string;
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Write annotations as GFF3, one line per annotation, in list order.
3
+ *
4
+ * The source column is always `InterProScan`: an Annotation records no source
5
+ * of its own, and the CLI's precomputed-lookup path depends on this output
6
+ * matching what a real InterProScan run emits, byte for byte.
7
+ */
8
+ export function annotationsToGFF(annotations) {
9
+ return [
10
+ '##gff-version 3',
11
+ ...annotations.map(annotation => {
12
+ const { accession, name, description, featureType } = annotation;
13
+ const { id, start, end, strand } = annotation;
14
+ return [
15
+ id,
16
+ 'InterProScan',
17
+ // GFF-sourced annotations carry their original type; writing every
18
+ // feature back out as protein_match would turn an exon overlay into
19
+ // generic domains on the next read, losing the numbered-segment
20
+ // rendering and the gene arrowheads
21
+ featureType ?? 'protein_match',
22
+ start,
23
+ end,
24
+ '.',
25
+ strand === undefined ? '.' : strand > 0 ? '+' : '-',
26
+ '.',
27
+ [
28
+ `Name=${encodeURIComponent(accession)}`,
29
+ `signature_desc=${encodeURIComponent(name)}`,
30
+ `description=${encodeURIComponent(description)}`,
31
+ ].join(';'),
32
+ ].join('\t');
33
+ }),
34
+ ].join('\n');
35
+ }
36
+ //# sourceMappingURL=annotationsToGFF.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"annotationsToGFF.js","sourceRoot":"","sources":["../../src/gff/annotationsToGFF.ts"],"names":[],"mappings":"AAEA;;;;;;GAMG;AACH,MAAM,UAAU,gBAAgB,CAAC,WAAyB;IACxD,OAAO;QACL,iBAAiB;QACjB,GAAG,WAAW,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE;YAC9B,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,WAAW,EAAE,WAAW,EAAE,GAAG,UAAU,CAAA;YAChE,MAAM,EAAE,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,UAAU,CAAA;YAC7C,OAAO;gBACL,EAAE;gBACF,cAAc;gBACd,mEAAmE;gBACnE,oEAAoE;gBACpE,gEAAgE;gBAChE,oCAAoC;gBACpC,WAAW,IAAI,eAAe;gBAC9B,KAAK;gBACL,GAAG;gBACH,GAAG;gBACH,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG;gBACnD,GAAG;gBACH;oBACE,QAAQ,kBAAkB,CAAC,SAAS,CAAC,EAAE;oBACvC,kBAAkB,kBAAkB,CAAC,IAAI,CAAC,EAAE;oBAC5C,eAAe,kBAAkB,CAAC,WAAW,CAAC,EAAE;iBACjD,CAAC,IAAI,CAAC,GAAG,CAAC;aACZ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QACd,CAAC,CAAC;KACH,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;AACd,CAAC"}
@@ -0,0 +1,9 @@
1
+ import type { Annotation, GFFRecord } from '../types.ts';
2
+ /**
3
+ * Convert GFF records to annotations, one per record, in file order.
4
+ *
5
+ * InterProScan's own GFF3 output falls out of the same mapping: it writes
6
+ * `Name` as the signature accession and `signature_desc` as its human-readable
7
+ * name, with domain positions 1-based.
8
+ */
9
+ export declare function gffToAnnotations(gffRecords: GFFRecord[]): Annotation[];
@@ -0,0 +1,53 @@
1
+ // Feature types that read as a directional "gene" and get an arrowhead in the
2
+ // overlay. Exon/CDS/UTR/domain features deliberately stay rectangular blocks —
3
+ // turning every exon into an arrow is misleading, since exons are segments of a
4
+ // single transcript, not independently-oriented genes.
5
+ const GENE_LEVEL_TYPES = new Set([
6
+ 'gene',
7
+ 'pseudogene',
8
+ 'mRNA',
9
+ 'transcript',
10
+ 'primary_transcript',
11
+ 'ncRNA',
12
+ 'tRNA',
13
+ 'rRNA',
14
+ 'snRNA',
15
+ 'snoRNA',
16
+ 'miRNA',
17
+ 'lnc_RNA',
18
+ ]);
19
+ // +1/-1 for a stranded gene-level feature, undefined otherwise (which the
20
+ // renderer draws as a plain block).
21
+ function geneStrand({ type, strand }) {
22
+ const directional = strand === '+' ? 1 : strand === '-' ? -1 : undefined;
23
+ return GENE_LEVEL_TYPES.has(type) ? directional : undefined;
24
+ }
25
+ /**
26
+ * Convert GFF records to annotations, one per record, in file order.
27
+ *
28
+ * InterProScan's own GFF3 output falls out of the same mapping: it writes
29
+ * `Name` as the signature accession and `signature_desc` as its human-readable
30
+ * name, with domain positions 1-based.
31
+ */
32
+ export function gffToAnnotations(gffRecords) {
33
+ return gffRecords.map(record => {
34
+ const accession = record.Name ||
35
+ record.ID ||
36
+ `${record.source}_${record.start}_${record.end}`;
37
+ const name = record.signature_desc || record.Name || accession;
38
+ return {
39
+ id: record.seq_id,
40
+ accession,
41
+ name,
42
+ description: record.Ontology_term ||
43
+ record.description ||
44
+ record.Note ||
45
+ name,
46
+ featureType: record.type,
47
+ start: record.start,
48
+ end: record.end,
49
+ strand: geneStrand(record),
50
+ };
51
+ });
52
+ }
53
+ //# sourceMappingURL=gffToAnnotations.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gffToAnnotations.js","sourceRoot":"","sources":["../../src/gff/gffToAnnotations.ts"],"names":[],"mappings":"AAEA,8EAA8E;AAC9E,+EAA+E;AAC/E,gFAAgF;AAChF,uDAAuD;AACvD,MAAM,gBAAgB,GAAG,IAAI,GAAG,CAAC;IAC/B,MAAM;IACN,YAAY;IACZ,MAAM;IACN,YAAY;IACZ,oBAAoB;IACpB,OAAO;IACP,MAAM;IACN,MAAM;IACN,OAAO;IACP,QAAQ;IACR,OAAO;IACP,SAAS;CACV,CAAC,CAAA;AAEF,0EAA0E;AAC1E,oCAAoC;AACpC,SAAS,UAAU,CAAC,EAAE,IAAI,EAAE,MAAM,EAAa;IAC7C,MAAM,WAAW,GAAG,MAAM,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAA;IACxE,OAAO,gBAAgB,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,SAAS,CAAA;AAC7D,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,gBAAgB,CAAC,UAAuB;IACtD,OAAO,UAAU,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE;QAC7B,MAAM,SAAS,GACZ,MAAM,CAAC,IAAe;YACtB,MAAM,CAAC,EAAa;YACrB,GAAG,MAAM,CAAC,MAAM,IAAI,MAAM,CAAC,KAAK,IAAI,MAAM,CAAC,GAAG,EAAE,CAAA;QAClD,MAAM,IAAI,GACP,MAAM,CAAC,cAAyB,IAAK,MAAM,CAAC,IAAe,IAAI,SAAS,CAAA;QAC3E,OAAO;YACL,EAAE,EAAE,MAAM,CAAC,MAAM;YACjB,SAAS;YACT,IAAI;YACJ,WAAW,EACR,MAAM,CAAC,aAAwB;gBAC/B,MAAM,CAAC,WAAsB;gBAC7B,MAAM,CAAC,IAAe;gBACvB,IAAI;YACN,WAAW,EAAE,MAAM,CAAC,IAAI;YACxB,KAAK,EAAE,MAAM,CAAC,KAAK;YACnB,GAAG,EAAE,MAAM,CAAC,GAAG;YACf,MAAM,EAAE,UAAU,CAAC,MAAM,CAAC;SAC3B,CAAA;IACH,CAAC,CAAC,CAAA;AACJ,CAAC"}
@@ -0,0 +1,71 @@
1
+ import { expect, test } from 'vitest';
2
+ import { gffToAnnotations } from './gffToAnnotations.js';
3
+ function record(fields = {}) {
4
+ return {
5
+ seq_id: 'seq1',
6
+ source: 'Pfam',
7
+ type: 'protein_match',
8
+ start: 10,
9
+ end: 50,
10
+ score: 0,
11
+ strand: '.',
12
+ phase: '.',
13
+ ...fields,
14
+ };
15
+ }
16
+ test('converts empty array', () => {
17
+ expect(gffToAnnotations([])).toEqual([]);
18
+ });
19
+ test('maps a record onto the annotation fields', () => {
20
+ expect(gffToAnnotations([
21
+ record({
22
+ Name: 'PF00001',
23
+ signature_desc: '7tm_1',
24
+ description: 'GPCR family',
25
+ }),
26
+ ])).toEqual([
27
+ {
28
+ id: 'seq1',
29
+ accession: 'PF00001',
30
+ name: '7tm_1',
31
+ description: 'GPCR family',
32
+ featureType: 'protein_match',
33
+ start: 10,
34
+ end: 50,
35
+ strand: undefined,
36
+ },
37
+ ]);
38
+ });
39
+ test('keeps one annotation per record, in file order', () => {
40
+ const annotations = gffToAnnotations([
41
+ record({ Name: 'PF00001', start: 10, end: 50 }),
42
+ record({ Name: 'PF00001', start: 100, end: 150 }),
43
+ record({ seq_id: 'seq2', Name: 'PF00002', start: 5, end: 40 }),
44
+ ]);
45
+ expect(annotations.map(a => [a.id, a.accession, a.start, a.end])).toEqual([
46
+ ['seq1', 'PF00001', 10, 50],
47
+ ['seq1', 'PF00001', 100, 150],
48
+ ['seq2', 'PF00002', 5, 40],
49
+ ]);
50
+ });
51
+ test('gives gene-level features a direction but leaves exons/domains as blocks', () => {
52
+ const annotations = gffToAnnotations([
53
+ record({ type: 'gene', strand: '+', Name: 'GENEA' }),
54
+ record({ type: 'mRNA', strand: '-', Name: 'GENEB' }),
55
+ record({ type: 'exon', strand: '+', Name: 'exon-1' }),
56
+ record({ type: 'protein_match', strand: '+', Name: 'PF00001' }),
57
+ ]);
58
+ expect(Object.fromEntries(annotations.map(a => [a.accession, a.strand]))).toEqual({
59
+ GENEA: 1, // + gene -> arrow right
60
+ GENEB: -1, // - gene -> arrow left
61
+ 'exon-1': undefined, // exon stays a block even though it is stranded
62
+ PF00001: undefined, // protein domain stays a block
63
+ });
64
+ });
65
+ test('falls back from Name to ID to source and positions', () => {
66
+ expect(gffToAnnotations([
67
+ record({ ID: 'domain_123' }),
68
+ record({ source: 'CustomSource' }),
69
+ ]).map(a => a.accession)).toEqual(['domain_123', 'CustomSource_10_50']);
70
+ });
71
+ //# sourceMappingURL=gffToAnnotations.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gffToAnnotations.test.js","sourceRoot":"","sources":["../../src/gff/gffToAnnotations.test.ts"],"names":[],"mappings":"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"}
@@ -1,3 +1,4 @@
1
1
  export { parseGFF } from './parseGFF.ts';
2
- export { gffToInterProResponse, gffToInterProResults } from './gffToInterPro.ts';
2
+ export { gffToAnnotations } from './gffToAnnotations.ts';
3
+ export { annotationsToGFF } from './annotationsToGFF.ts';
3
4
  export { interProResponseToGFF, interProToGFF } from './interProToGFF.ts';
package/dist/gff/index.js CHANGED
@@ -1,4 +1,5 @@
1
1
  export { parseGFF } from './parseGFF.js';
2
- export { gffToInterProResponse, gffToInterProResults } from './gffToInterPro.js';
2
+ export { gffToAnnotations } from './gffToAnnotations.js';
3
+ export { annotationsToGFF } from './annotationsToGFF.js';
3
4
  export { interProResponseToGFF, interProToGFF } from './interProToGFF.js';
4
5
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/gff/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;AACxC,OAAO,EAAE,qBAAqB,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAA;AAChF,OAAO,EAAE,qBAAqB,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/gff/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;AACxC,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAA;AACxD,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAA;AACxD,OAAO,EAAE,qBAAqB,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAA"}
@@ -1,9 +1,10 @@
1
1
  import type { InterProScanResults } from '../types.ts';
2
2
  /**
3
- * Convert InterProScan results to GFF3 format
3
+ * Convert InterProScan results, keyed by the row name they attach to, to GFF3.
4
4
  */
5
5
  export declare function interProToGFF(results: Record<string, InterProScanResults>): string;
6
6
  /**
7
- * Convert InterProScan JSON response to GFF3 format
7
+ * Convert a list of InterProScan results to GFF3, taking each one's row name
8
+ * from its xref.
8
9
  */
9
10
  export declare function interProResponseToGFF(results: InterProScanResults[]): string;
@@ -1,52 +1,16 @@
1
+ import { indexResultsByXref, interProScanToAnnotations, } from '../interProScanToAnnotations.js';
2
+ import { annotationsToGFF } from './annotationsToGFF.js';
1
3
  /**
2
- * Convert InterProScan results to GFF3 format
4
+ * Convert InterProScan results, keyed by the row name they attach to, to GFF3.
3
5
  */
4
6
  export function interProToGFF(results) {
5
- const lines = ['##gff-version 3'];
6
- for (const [seqId, data] of Object.entries(results)) {
7
- for (const match of data.matches) {
8
- const entry = match.signature.entry;
9
- if (!entry) {
10
- continue;
11
- }
12
- for (const location of match.locations) {
13
- const attributes = [
14
- `Name=${encodeURIComponent(entry.accession)}`,
15
- `signature_desc=${encodeURIComponent(entry.name)}`,
16
- `description=${encodeURIComponent(entry.description)}`,
17
- ].join(';');
18
- const line = [
19
- seqId,
20
- 'InterProScan',
21
- // GFF-sourced annotations carry their original type; writing every
22
- // feature back out as protein_match would turn an exon overlay into
23
- // generic domains on the next read, losing the numbered-segment
24
- // rendering and the gene arrowheads
25
- entry.featureType ?? 'protein_match',
26
- location.start,
27
- location.end,
28
- '.',
29
- location.strand === undefined ? '.' : location.strand > 0 ? '+' : '-',
30
- '.',
31
- attributes,
32
- ].join('\t');
33
- lines.push(line);
34
- }
35
- }
36
- }
37
- return lines.join('\n');
7
+ return annotationsToGFF(interProScanToAnnotations(results));
38
8
  }
39
9
  /**
40
- * Convert InterProScan JSON response to GFF3 format
10
+ * Convert a list of InterProScan results to GFF3, taking each one's row name
11
+ * from its xref.
41
12
  */
42
13
  export function interProResponseToGFF(results) {
43
- const resultsMap = {};
44
- for (const result of results) {
45
- const seqId = result.xref[0]?.id;
46
- if (seqId) {
47
- resultsMap[seqId] = result;
48
- }
49
- }
50
- return interProToGFF(resultsMap);
14
+ return interProToGFF(indexResultsByXref(results));
51
15
  }
52
16
  //# sourceMappingURL=interProToGFF.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"interProToGFF.js","sourceRoot":"","sources":["../../src/gff/interProToGFF.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,MAAM,UAAU,aAAa,CAC3B,OAA4C;IAE5C,MAAM,KAAK,GAAa,CAAC,iBAAiB,CAAC,CAAA;IAE3C,KAAK,MAAM,CAAC,KAAK,EAAE,IAAI,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;QACpD,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YACjC,MAAM,KAAK,GAAG,KAAK,CAAC,SAAS,CAAC,KAAK,CAAA;YACnC,IAAI,CAAC,KAAK,EAAE,CAAC;gBACX,SAAQ;YACV,CAAC;YAED,KAAK,MAAM,QAAQ,IAAI,KAAK,CAAC,SAAS,EAAE,CAAC;gBACvC,MAAM,UAAU,GAAG;oBACjB,QAAQ,kBAAkB,CAAC,KAAK,CAAC,SAAS,CAAC,EAAE;oBAC7C,kBAAkB,kBAAkB,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE;oBAClD,eAAe,kBAAkB,CAAC,KAAK,CAAC,WAAW,CAAC,EAAE;iBACvD,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;gBAEX,MAAM,IAAI,GAAG;oBACX,KAAK;oBACL,cAAc;oBACd,mEAAmE;oBACnE,oEAAoE;oBACpE,gEAAgE;oBAChE,oCAAoC;oBACpC,KAAK,CAAC,WAAW,IAAI,eAAe;oBACpC,QAAQ,CAAC,KAAK;oBACd,QAAQ,CAAC,GAAG;oBACZ,GAAG;oBACH,QAAQ,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG;oBACrE,GAAG;oBACH,UAAU;iBACX,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;gBAEZ,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;YAClB,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;AACzB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,qBAAqB,CAAC,OAA8B;IAClE,MAAM,UAAU,GAAwC,EAAE,CAAA;IAE1D,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;QAC7B,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAA;QAChC,IAAI,KAAK,EAAE,CAAC;YACV,UAAU,CAAC,KAAK,CAAC,GAAG,MAAM,CAAA;QAC5B,CAAC;IACH,CAAC;IAED,OAAO,aAAa,CAAC,UAAU,CAAC,CAAA;AAClC,CAAC"}
1
+ {"version":3,"file":"interProToGFF.js","sourceRoot":"","sources":["../../src/gff/interProToGFF.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,kBAAkB,EAClB,yBAAyB,GAC1B,MAAM,iCAAiC,CAAA;AACxC,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAA;AAIxD;;GAEG;AACH,MAAM,UAAU,aAAa,CAC3B,OAA4C;IAE5C,OAAO,gBAAgB,CAAC,yBAAyB,CAAC,OAAO,CAAC,CAAC,CAAA;AAC7D,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,qBAAqB,CAAC,OAA8B;IAClE,OAAO,aAAa,CAAC,kBAAkB,CAAC,OAAO,CAAC,CAAC,CAAA;AACnD,CAAC"}
@@ -1,5 +1,6 @@
1
1
  import { describe, expect, test } from 'vitest';
2
- import { gffToInterProResults } from './gffToInterPro.js';
2
+ import { annotationsToGFF } from './annotationsToGFF.js';
3
+ import { gffToAnnotations } from './gffToAnnotations.js';
3
4
  import { interProResponseToGFF, interProToGFF } from './interProToGFF.js';
4
5
  import { parseGFF } from './parseGFF.js';
5
6
  describe('interProToGFF', () => {
@@ -125,7 +126,7 @@ describe('interProToGFF', () => {
125
126
  'seq1\tRefSeq\tmRNA\t1\t99\t.\t+\t.\tName=NM_1',
126
127
  'seq1\tRefSeq\texon\t1\t30\t.\t+\t.\tName=exon-1',
127
128
  ].join('\n');
128
- const rows = interProToGFF(gffToInterProResults(parseGFF(gff)))
129
+ const rows = annotationsToGFF(gffToAnnotations(parseGFF(gff)))
129
130
  .split('\n')
130
131
  .slice(1)
131
132
  .map(l => l.split('\t'));
@@ -1 +1 @@
1
- {"version":3,"file":"interProToGFF.test.js","sourceRoot":"","sources":["../../src/gff/interProToGFF.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAA;AAE/C,OAAO,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAA;AACzD,OAAO,EAAE,qBAAqB,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAA;AACzE,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;AAIxC,QAAQ,CAAC,eAAe,EAAE,GAAG,EAAE;IAC7B,IAAI,CAAC,wBAAwB,EAAE,GAAG,EAAE;QAClC,MAAM,GAAG,GAAG,aAAa,CAAC,EAAE,CAAC,CAAA;QAC7B,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAA;IACrC,CAAC,CAAC,CAAA;IAEF,IAAI,CAAC,wBAAwB,EAAE,GAAG,EAAE;QAClC,MAAM,OAAO,GAAwC;YACnD,IAAI,EAAE;gBACJ,OAAO,EAAE;oBACP;wBACE,SAAS,EAAE;4BACT,KAAK,EAAE;gCACL,SAAS,EAAE,SAAS;gCACpB,IAAI,EAAE,OAAO;gCACb,WAAW,EAAE,aAAa;6BAC3B;yBACF;wBACD,SAAS,EAAE,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,CAAC;qBACpC;iBACF;gBACD,IAAI,EAAE,CAAC,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC;aACvB;SACF,CAAA;QACD,MAAM,GAAG,GAAG,aAAa,CAAC,OAAO,CAAC,CAAA;QAClC,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;QAE7B,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAA;QACxC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,CAAA;QAClC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,cAAc,CAAC,CAAA;QAC1C,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,eAAe,CAAC,CAAA;QAC3C,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,CAAA;QAChC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,CAAA;QAChC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,cAAc,CAAC,CAAA;QAC1C,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,sBAAsB,CAAC,CAAA;QAClD,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,2BAA2B,CAAC,CAAA;IACzD,CAAC,CAAC,CAAA;IAEF,IAAI,CAAC,4BAA4B,EAAE,GAAG,EAAE;QACtC,MAAM,OAAO,GAAwC;YACnD,IAAI,EAAE;gBACJ,OAAO,EAAE;oBACP;wBACE,SAAS,EAAE;4BACT,KAAK,EAAE;gCACL,SAAS,EAAE,SAAS;gCACpB,IAAI,EAAE,QAAQ;gCACd,WAAW,EAAE,MAAM;6BACpB;yBACF;wBACD,SAAS,EAAE;4BACT,EAAE,KAAK,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE;4BACtB,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE;yBACzB;qBACF;iBACF;gBACD,IAAI,EAAE,CAAC,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC;aACvB;SACF,CAAA;QACD,MAAM,GAAG,GAAG,aAAa,CAAC,OAAO,CAAC,CAAA;QAClC,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;QAE7B,MAAM,CAAC,KAAK,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAA;QAC7B,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAA;QACpC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,UAAU,CAAC,CAAA;IACxC,CAAC,CAAC,CAAA;IAEF,IAAI,CAAC,4BAA4B,EAAE,GAAG,EAAE;QACtC,MAAM,OAAO,GAAwC;YACnD,IAAI,EAAE;gBACJ,OAAO,EAAE;oBACP;wBACE,SAAS,EAAE;4BACT,KAAK,EAAE;gCACL,SAAS,EAAE,SAAS;gCACpB,IAAI,EAAE,SAAS;gCACf,WAAW,EAAE,OAAO;6BACrB;yBACF;wBACD,SAAS,EAAE,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,CAAC;qBACpC;iBACF;gBACD,IAAI,EAAE,CAAC,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC;aACvB;YACD,IAAI,EAAE;gBACJ,OAAO,EAAE;oBACP;wBACE,SAAS,EAAE;4BACT,KAAK,EAAE;gCACL,SAAS,EAAE,SAAS;gCACpB,IAAI,EAAE,SAAS;gCACf,WAAW,EAAE,OAAO;6BACrB;yBACF;wBACD,SAAS,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,GAAG,EAAE,EAAE,EAAE,CAAC;qBACnC;iBACF;gBACD,IAAI,EAAE,CAAC,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC;aACvB;SACF,CAAA;QACD,MAAM,GAAG,GAAG,aAAa,CAAC,OAAO,CAAC,CAAA;QAClC,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;QAE7B,MAAM,CAAC,KAAK,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAA;QAC7B,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QACtD,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IACxD,CAAC,CAAC,CAAA;IAEF,IAAI,CAAC,6BAA6B,EAAE,GAAG,EAAE;QACvC,MAAM,OAAO,GAAwC;YACnD,IAAI,EAAE;gBACJ,OAAO,EAAE;oBACP;wBACE,SAAS,EAAE,EAAE;wBACb,SAAS,EAAE,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,CAAC;qBACpC;iBACF;gBACD,IAAI,EAAE,CAAC,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC;aACvB;SACF,CAAA;QACD,MAAM,GAAG,GAAG,aAAa,CAAC,OAAO,CAAC,CAAA;QAClC,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;QAE7B,MAAM,CAAC,KAAK,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAA;QAC7B,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAA;IAC1C,CAAC,CAAC,CAAA;IAEF,IAAI,CAAC,qEAAqE,EAAE,GAAG,EAAE;QAC/E,MAAM,GAAG,GAAG;YACV,+CAA+C;YAC/C,iDAAiD;SAClD,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QACZ,MAAM,IAAI,GAAG,aAAa,CAAC,oBAAoB,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC;aAC5D,KAAK,CAAC,IAAI,CAAC;aACX,KAAK,CAAC,CAAC,CAAC;aACR,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAA;QAE1B,yEAAyE;QACzE,4EAA4E;QAC5E,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC;YAC1C,CAAC,MAAM,EAAE,GAAG,CAAC;YACb,CAAC,MAAM,EAAE,GAAG,CAAC;SACd,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;IAEF,IAAI,CAAC,8CAA8C,EAAE,GAAG,EAAE;QACxD,MAAM,OAAO,GAAwC;YACnD,IAAI,EAAE;gBACJ,OAAO,EAAE;oBACP;wBACE,SAAS,EAAE;4BACT,KAAK,EAAE;gCACL,SAAS,EAAE,SAAS;gCACpB,IAAI,EAAE,iBAAiB;gCACvB,WAAW,EAAE,yBAAyB;6BACvC;yBACF;wBACD,SAAS,EAAE,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,CAAC;qBACpC;iBACF;gBACD,IAAI,EAAE,CAAC,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC;aACvB;SACF,CAAA;QACD,MAAM,GAAG,GAAG,aAAa,CAAC,OAAO,CAAC,CAAA;QAElC,MAAM,CAAC,GAAG,CAAC,CAAC,SAAS,CAAC,oCAAoC,CAAC,CAAA;QAC3D,MAAM,CAAC,GAAG,CAAC,CAAC,SAAS,CAAC,yCAAyC,CAAC,CAAA;IAClE,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA;AAEF,QAAQ,CAAC,uBAAuB,EAAE,GAAG,EAAE;IACrC,IAAI,CAAC,2BAA2B,EAAE,GAAG,EAAE;QACrC,MAAM,OAAO,GAA0B;YACrC;gBACE,OAAO,EAAE;oBACP;wBACE,SAAS,EAAE;4BACT,KAAK,EAAE;gCACL,SAAS,EAAE,SAAS;gCACpB,IAAI,EAAE,QAAQ;gCACd,WAAW,EAAE,MAAM;6BACpB;yBACF;wBACD,SAAS,EAAE,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,CAAC;qBACpC;iBACF;gBACD,IAAI,EAAE,CAAC,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC;aACvB;SACF,CAAA;QACD,MAAM,GAAG,GAAG,qBAAqB,CAAC,OAAO,CAAC,CAAA;QAE1C,MAAM,CAAC,GAAG,CAAC,CAAC,SAAS,CAAC,iBAAiB,CAAC,CAAA;QACxC,MAAM,CAAC,GAAG,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,CAAA;IAC/B,CAAC,CAAC,CAAA;IAEF,IAAI,CAAC,8BAA8B,EAAE,GAAG,EAAE;QACxC,MAAM,OAAO,GAA0B;YACrC;gBACE,OAAO,EAAE;oBACP;wBACE,SAAS,EAAE;4BACT,KAAK,EAAE;gCACL,SAAS,EAAE,SAAS;gCACpB,IAAI,EAAE,QAAQ;gCACd,WAAW,EAAE,MAAM;6BACpB;yBACF;wBACD,SAAS,EAAE,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,CAAC;qBACpC;iBACF;gBACD,IAAI,EAAE,EAAE;aACT;SACF,CAAA;QACD,MAAM,GAAG,GAAG,qBAAqB,CAAC,OAAO,CAAC,CAAA;QAE1C,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAA;IACrC,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA"}
1
+ {"version":3,"file":"interProToGFF.test.js","sourceRoot":"","sources":["../../src/gff/interProToGFF.test.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -2,4 +2,5 @@ export type * from './types.ts';
2
2
  export { generateNodeIds } from './util.ts';
3
3
  export { A3mMSA, ClustalMSA, EmfMSA, FastaMSA, StockholmMSA, getUngappedSequence, parseEmfTree, parseMSA, parseNewick, stockholmSniff, } from './msa/index.ts';
4
4
  export type { MSAFormat, MSAParserType } from './msa/index.ts';
5
- export { gffToInterProResponse, gffToInterProResults, interProResponseToGFF, interProToGFF, parseGFF, } from './gff/index.ts';
5
+ export { indexResultsByXref, interProScanResponseToAnnotations, interProScanToAnnotations, } from './interProScanToAnnotations.ts';
6
+ export { annotationsToGFF, gffToAnnotations, interProResponseToGFF, interProToGFF, parseGFF, } from './gff/index.ts';
package/dist/index.js CHANGED
@@ -2,6 +2,8 @@
2
2
  export { generateNodeIds } from './util.js';
3
3
  // MSA parsers
4
4
  export { A3mMSA, ClustalMSA, EmfMSA, FastaMSA, StockholmMSA, getUngappedSequence, parseEmfTree, parseMSA, parseNewick, stockholmSniff, } from './msa/index.js';
5
+ // Overlay annotations: the canonical shape, and the adapters onto it
6
+ export { indexResultsByXref, interProScanResponseToAnnotations, interProScanToAnnotations, } from './interProScanToAnnotations.js';
5
7
  // GFF parsing
6
- export { gffToInterProResponse, gffToInterProResults, interProResponseToGFF, interProToGFF, parseGFF, } from './gff/index.js';
8
+ export { annotationsToGFF, gffToAnnotations, interProResponseToGFF, interProToGFF, parseGFF, } from './gff/index.js';
7
9
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAGA,YAAY;AACZ,OAAO,EAAE,eAAe,EAAE,MAAM,WAAW,CAAA;AAE3C,cAAc;AACd,OAAO,EACL,MAAM,EACN,UAAU,EACV,MAAM,EACN,QAAQ,EACR,YAAY,EACZ,mBAAmB,EACnB,YAAY,EACZ,QAAQ,EACR,WAAW,EACX,cAAc,GACf,MAAM,gBAAgB,CAAA;AAGvB,cAAc;AACd,OAAO,EACL,qBAAqB,EACrB,oBAAoB,EACpB,qBAAqB,EACrB,aAAa,EACb,QAAQ,GACT,MAAM,gBAAgB,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAGA,YAAY;AACZ,OAAO,EAAE,eAAe,EAAE,MAAM,WAAW,CAAA;AAE3C,cAAc;AACd,OAAO,EACL,MAAM,EACN,UAAU,EACV,MAAM,EACN,QAAQ,EACR,YAAY,EACZ,mBAAmB,EACnB,YAAY,EACZ,QAAQ,EACR,WAAW,EACX,cAAc,GACf,MAAM,gBAAgB,CAAA;AAGvB,qEAAqE;AACrE,OAAO,EACL,kBAAkB,EAClB,iCAAiC,EACjC,yBAAyB,GAC1B,MAAM,gCAAgC,CAAA;AAEvC,cAAc;AACd,OAAO,EACL,gBAAgB,EAChB,gBAAgB,EAChB,qBAAqB,EACrB,aAAa,EACb,QAAQ,GACT,MAAM,gBAAgB,CAAA"}
@@ -0,0 +1,21 @@
1
+ import type { Annotation, InterProScanResponse, InterProScanResults } from './types.ts';
2
+ /**
3
+ * Key each result by its xref id, which is the row name its annotations attach
4
+ * to. A result without one is dropped rather than keyed `undefined`, which
5
+ * would draw a phantom row's worth of annotations (and rather than throwing,
6
+ * which would lose every other result over one malformed one).
7
+ */
8
+ export declare function indexResultsByXref(results: InterProScanResults[]): {
9
+ [k: string]: InterProScanResults;
10
+ };
11
+ /**
12
+ * Flatten InterProScan results, keyed by the row name they attach to, into one
13
+ * annotation per signature location. A signature without an `entry` carries no
14
+ * accession or name to color, filter or label by, so it is dropped.
15
+ */
16
+ export declare function interProScanToAnnotations(results: Record<string, InterProScanResults>): Annotation[];
17
+ /**
18
+ * Flatten a whole InterProScan JSON response, resolving each result's row name
19
+ * from its xref.
20
+ */
21
+ export declare function interProScanResponseToAnnotations(response: InterProScanResponse): Annotation[];
@@ -0,0 +1,38 @@
1
+ /**
2
+ * Key each result by its xref id, which is the row name its annotations attach
3
+ * to. A result without one is dropped rather than keyed `undefined`, which
4
+ * would draw a phantom row's worth of annotations (and rather than throwing,
5
+ * which would lose every other result over one malformed one).
6
+ */
7
+ export function indexResultsByXref(results) {
8
+ return Object.fromEntries(results
9
+ .map(r => [r.xref[0]?.id, r])
10
+ .filter((e) => e[0] !== undefined));
11
+ }
12
+ /**
13
+ * Flatten InterProScan results, keyed by the row name they attach to, into one
14
+ * annotation per signature location. A signature without an `entry` carries no
15
+ * accession or name to color, filter or label by, so it is dropped.
16
+ */
17
+ export function interProScanToAnnotations(results) {
18
+ return Object.entries(results).flatMap(([id, { matches }]) => matches.flatMap(({ signature: { entry }, locations }) => entry
19
+ ? locations.map(({ start, end, strand }) => ({
20
+ id,
21
+ accession: entry.accession,
22
+ name: entry.name,
23
+ description: entry.description,
24
+ featureType: entry.featureType,
25
+ start,
26
+ end,
27
+ strand,
28
+ }))
29
+ : []));
30
+ }
31
+ /**
32
+ * Flatten a whole InterProScan JSON response, resolving each result's row name
33
+ * from its xref.
34
+ */
35
+ export function interProScanResponseToAnnotations(response) {
36
+ return interProScanToAnnotations(indexResultsByXref(response.results));
37
+ }
38
+ //# sourceMappingURL=interProScanToAnnotations.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"interProScanToAnnotations.js","sourceRoot":"","sources":["../src/interProScanToAnnotations.ts"],"names":[],"mappings":"AAMA;;;;;GAKG;AACH,MAAM,UAAU,kBAAkB,CAAC,OAA8B;IAC/D,OAAO,MAAM,CAAC,WAAW,CACvB,OAAO;SACJ,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAU,CAAC;SACrC,MAAM,CAAC,CAAC,CAAC,EAAsC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,SAAS,CAAC,CACzE,CAAA;AACH,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,yBAAyB,CACvC,OAA4C;IAE5C,OAAO,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,OAAO,EAAE,CAAC,EAAE,EAAE,CAC3D,OAAO,CAAC,OAAO,CAAC,CAAC,EAAE,SAAS,EAAE,EAAE,KAAK,EAAE,EAAE,SAAS,EAAE,EAAE,EAAE,CACtD,KAAK;QACH,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,CAAC;YACzC,EAAE;YACF,SAAS,EAAE,KAAK,CAAC,SAAS;YAC1B,IAAI,EAAE,KAAK,CAAC,IAAI;YAChB,WAAW,EAAE,KAAK,CAAC,WAAW;YAC9B,WAAW,EAAE,KAAK,CAAC,WAAW;YAC9B,KAAK;YACL,GAAG;YACH,MAAM;SACP,CAAC,CAAC;QACL,CAAC,CAAC,EAAE,CACP,CACF,CAAA;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,iCAAiC,CAC/C,QAA8B;IAE9B,OAAO,yBAAyB,CAAC,kBAAkB,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAA;AACxE,CAAC"}
package/dist/types.d.ts CHANGED
@@ -28,6 +28,30 @@ export interface GFFRecord {
28
28
  phase: string;
29
29
  [key: string]: string | number;
30
30
  }
31
+ /**
32
+ * One annotation interval attached to an alignment row: a protein domain, an
33
+ * exon, a gene. This is the canonical overlay shape -- every source
34
+ * (InterProScan, GFF, a user upload) converts to a flat list of these, and the
35
+ * viewer renders nothing else.
36
+ */
37
+ export interface Annotation {
38
+ /** name of the alignment row the interval attaches to */
39
+ id: string;
40
+ /** stable key deciding color, legend membership and filter state */
41
+ accession: string;
42
+ name: string;
43
+ description: string;
44
+ /**
45
+ * original GFF feature type (exon, CDS, gene, ...) when sourced from GFF;
46
+ * lets the viewer treat ordinal segments (exons) differently from
47
+ * categorical domains
48
+ */
49
+ featureType?: string;
50
+ /** 1-based, inclusive of both ends */
51
+ start: number;
52
+ end: number;
53
+ strand?: number;
54
+ }
31
55
  export interface InterProScanMatch {
32
56
  signature: {
33
57
  entry?: {
package/dist/util.d.ts CHANGED
@@ -1,2 +1,12 @@
1
1
  import type { Node, NodeWithIds } from './types.ts';
2
+ /**
3
+ * Copy a parsed tree, giving every node a stable id derived from its path, and
4
+ * falling back to that id for an unnamed node.
5
+ *
6
+ * Iterative, like the traversals in @gmod/newick and the Newick emitter in the
7
+ * viewer's neighbor joining: a phylogeny can be a caterpillar whose depth equals
8
+ * its leaf count, and the recursive form of this overflowed the stack somewhere
9
+ * past 5000 deep -- which every tree reaches, since this is the last step of
10
+ * parsing one.
11
+ */
2
12
  export declare function generateNodeIds(tree: Node, parent?: string, depth?: number): NodeWithIds;
package/dist/util.js CHANGED
@@ -1,10 +1,31 @@
1
+ /**
2
+ * Copy a parsed tree, giving every node a stable id derived from its path, and
3
+ * falling back to that id for an unnamed node.
4
+ *
5
+ * Iterative, like the traversals in @gmod/newick and the Newick emitter in the
6
+ * viewer's neighbor joining: a phylogeny can be a caterpillar whose depth equals
7
+ * its leaf count, and the recursive form of this overflowed the stack somewhere
8
+ * past 5000 deep -- which every tree reaches, since this is the last step of
9
+ * parsing one.
10
+ */
1
11
  export function generateNodeIds(tree, parent = 'node', depth = 0) {
2
- const id = `${parent}-${depth}`;
3
- return {
4
- ...tree,
12
+ const withId = (node, id) => ({
13
+ ...node,
5
14
  id,
6
- name: tree.name || id,
7
- children: tree.children?.map((b, i) => generateNodeIds(b, `${id}-${i}`, depth + 1)) || [],
8
- };
15
+ name: node.name || id,
16
+ children: [],
17
+ });
18
+ const root = withId(tree, `${parent}-${depth}`);
19
+ const stack = [{ src: tree, out: root, depth }];
20
+ while (stack.length > 0) {
21
+ const { src, out, depth: d } = stack.pop();
22
+ if (src.children) {
23
+ out.children = src.children.map((child, i) => withId(child, `${out.id}-${i}-${d + 1}`));
24
+ for (const [i, child] of src.children.entries()) {
25
+ stack.push({ src: child, out: out.children[i], depth: d + 1 });
26
+ }
27
+ }
28
+ }
29
+ return root;
9
30
  }
10
31
  //# sourceMappingURL=util.js.map
package/dist/util.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"util.js","sourceRoot":"","sources":["../src/util.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,eAAe,CAC7B,IAAU,EACV,MAAM,GAAG,MAAM,EACf,KAAK,GAAG,CAAC;IAET,MAAM,EAAE,GAAG,GAAG,MAAM,IAAI,KAAK,EAAE,CAAA;IAE/B,OAAO;QACL,GAAG,IAAI;QACP,EAAE;QACF,IAAI,EAAE,IAAI,CAAC,IAAI,IAAI,EAAE;QACrB,QAAQ,EACN,IAAI,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAC1B,eAAe,CAAC,CAAC,EAAE,GAAG,EAAE,IAAI,CAAC,EAAE,EAAE,KAAK,GAAG,CAAC,CAAC,CAC5C,IAAI,EAAE;KACV,CAAA;AACH,CAAC"}
1
+ {"version":3,"file":"util.js","sourceRoot":"","sources":["../src/util.ts"],"names":[],"mappings":"AAEA;;;;;;;;;GASG;AACH,MAAM,UAAU,eAAe,CAC7B,IAAU,EACV,MAAM,GAAG,MAAM,EACf,KAAK,GAAG,CAAC;IAET,MAAM,MAAM,GAAG,CAAC,IAAU,EAAE,EAAU,EAAe,EAAE,CAAC,CAAC;QACvD,GAAG,IAAI;QACP,EAAE;QACF,IAAI,EAAE,IAAI,CAAC,IAAI,IAAI,EAAE;QACrB,QAAQ,EAAE,EAAE;KACb,CAAC,CAAA;IAEF,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,EAAE,GAAG,MAAM,IAAI,KAAK,EAAE,CAAC,CAAA;IAC/C,MAAM,KAAK,GAAG,CAAC,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAA;IAC/C,OAAO,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACxB,MAAM,EAAE,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC,EAAE,GAAG,KAAK,CAAC,GAAG,EAAG,CAAA;QAC3C,IAAI,GAAG,CAAC,QAAQ,EAAE,CAAC;YACjB,GAAG,CAAC,QAAQ,GAAG,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,CAAC,EAAE,EAAE,CAC3C,MAAM,CAAC,KAAK,EAAE,GAAG,GAAG,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CACzC,CAAA;YACD,KAAK,MAAM,CAAC,CAAC,EAAE,KAAK,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,OAAO,EAAE,EAAE,CAAC;gBAChD,KAAK,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAE,EAAE,KAAK,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;YACjE,CAAC;QACH,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAA;AACb,CAAC"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,40 @@
1
+ import { expect, test } from 'vitest';
2
+ import parseNewick from './msa/parseNewick.js';
3
+ import { generateNodeIds } from './util.js';
4
+ test('ids encode the path to each node, and name unnamed nodes', () => {
5
+ const tree = generateNodeIds({
6
+ children: [{ name: 'a' }, { name: 'b', children: [{ name: 'c' }] }],
7
+ });
8
+ expect(tree.id).toBe('node-0');
9
+ // an unnamed node takes its id as its name
10
+ expect(tree.name).toBe('node-0');
11
+ expect(tree.children.map(c => [c.name, c.id])).toEqual([
12
+ ['a', 'node-0-0-1'],
13
+ ['b', 'node-0-1-1'],
14
+ ]);
15
+ expect(tree.children[1].children.map(c => c.id)).toEqual(['node-0-1-1-0-2']);
16
+ });
17
+ test('a leaf gets an empty children array, not undefined', () => {
18
+ expect(generateNodeIds({ name: 'solo' }).children).toEqual([]);
19
+ });
20
+ // a phylogeny can be a caterpillar whose depth equals its leaf count. The
21
+ // recursive form of generateNodeIds threw "Maximum call stack size exceeded"
22
+ // somewhere past 5000 deep -- and every parsed tree goes through it, so a deep
23
+ // newick took the whole viewer down.
24
+ test('a caterpillar tree far past the recursion limit still gets ids', () => {
25
+ const depth = 50_000;
26
+ let newick = 'leaf0:0.1';
27
+ for (let i = 1; i <= depth; i++) {
28
+ newick = `(${newick},leaf${i}:0.1)`;
29
+ }
30
+ const tree = generateNodeIds(parseNewick(`${newick};`));
31
+ let node = tree;
32
+ let seen = 0;
33
+ while (node.children.length > 1) {
34
+ seen++;
35
+ node = node.children[0];
36
+ }
37
+ expect(seen).toBe(depth);
38
+ expect(node.name).toBe('leaf0');
39
+ });
40
+ //# sourceMappingURL=util.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"util.test.js","sourceRoot":"","sources":["../src/util.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAA;AAErC,OAAO,WAAW,MAAM,sBAAsB,CAAA;AAC9C,OAAO,EAAE,eAAe,EAAE,MAAM,WAAW,CAAA;AAI3C,IAAI,CAAC,0DAA0D,EAAE,GAAG,EAAE;IACpE,MAAM,IAAI,GAAG,eAAe,CAAC;QAC3B,QAAQ,EAAE,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,EAAE,EAAE,IAAI,EAAE,GAAG,EAAE,QAAQ,EAAE,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC;KACpE,CAAC,CAAA;IACF,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAA;IAC9B,2CAA2C;IAC3C,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAA;IAChC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC;QACrD,CAAC,GAAG,EAAE,YAAY,CAAC;QACnB,CAAC,GAAG,EAAE,YAAY,CAAC;KACpB,CAAC,CAAA;IACF,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAA;AAC/E,CAAC,CAAC,CAAA;AAEF,IAAI,CAAC,oDAAoD,EAAE,GAAG,EAAE;IAC9D,MAAM,CAAC,eAAe,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAA;AAChE,CAAC,CAAC,CAAA;AAEF,0EAA0E;AAC1E,6EAA6E;AAC7E,+EAA+E;AAC/E,qCAAqC;AACrC,IAAI,CAAC,gEAAgE,EAAE,GAAG,EAAE;IAC1E,MAAM,KAAK,GAAG,MAAM,CAAA;IACpB,IAAI,MAAM,GAAG,WAAW,CAAA;IACxB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,KAAK,EAAE,CAAC,EAAE,EAAE,CAAC;QAChC,MAAM,GAAG,IAAI,MAAM,QAAQ,CAAC,OAAO,CAAA;IACrC,CAAC;IAED,MAAM,IAAI,GAAG,eAAe,CAAC,WAAW,CAAC,GAAG,MAAM,GAAG,CAAC,CAAC,CAAA;IAEvD,IAAI,IAAI,GAAgB,IAAI,CAAA;IAC5B,IAAI,IAAI,GAAG,CAAC,CAAA;IACZ,OAAO,IAAI,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAChC,IAAI,EAAE,CAAA;QACN,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAE,CAAA;IAC1B,CAAC;IACD,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;IACxB,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;AACjC,CAAC,CAAC,CAAA"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "msa-parsers",
3
- "version": "5.10.0",
3
+ "version": "6.0.0",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "repository": {