gramene-search 2.25.0 → 2.27.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/index.js +76 -3
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -11485,6 +11485,70 @@ var $527ebc19dc92444d$export$2e2bcd8739ae039 = (0, $gXNCa$reduxbundlerreact.conn
|
|
|
11485
11485
|
|
|
11486
11486
|
|
|
11487
11487
|
|
|
11488
|
+
/**
|
|
11489
|
+
* Gene models for the primer designer's variant browser.
|
|
11490
|
+
*
|
|
11491
|
+
* `/primers` has no genes-in-region endpoint — it can only fetch a gene by id —
|
|
11492
|
+
* so the designer takes this from its host. Ensembl REST's `overlap/region`
|
|
11493
|
+
* returns genes, transcripts, exons and CDS for a window in one request, all in
|
|
11494
|
+
* genomic coordinates, which is exactly what the browser draws.
|
|
11495
|
+
*
|
|
11496
|
+
* Read from `config.ensemblRest`, which must be the same Ensembl release the
|
|
11497
|
+
* primers API reads variants from (release 115 for sorghum_v11). A different
|
|
11498
|
+
* release would draw gene models that do not line up with the variants beside
|
|
11499
|
+
* them.
|
|
11500
|
+
*/ /**
|
|
11501
|
+
* Beyond this the response runs to thousands of features and the models would
|
|
11502
|
+
* be too small to read, so the track is simply left empty.
|
|
11503
|
+
*/ const $31284fcdc45a1688$var$MAX_SPAN = 1000000;
|
|
11504
|
+
function $31284fcdc45a1688$export$3a249e9030170bda(ensemblRest) {
|
|
11505
|
+
if (!ensemblRest) return undefined;
|
|
11506
|
+
return async ({ system_name: system_name, region: region, start: start, end: end }, options)=>{
|
|
11507
|
+
if (!system_name || !region || end - start + 1 > $31284fcdc45a1688$var$MAX_SPAN) return [];
|
|
11508
|
+
const signal = options && options.signal;
|
|
11509
|
+
const url = `${ensemblRest}/overlap/region/${encodeURIComponent(system_name)}/${encodeURIComponent(region)}:${start}-${end}` + `?feature=gene;feature=transcript;feature=exon;feature=cds;content-type=application/json`;
|
|
11510
|
+
const res = await fetch(url, {
|
|
11511
|
+
headers: {
|
|
11512
|
+
Accept: 'application/json'
|
|
11513
|
+
},
|
|
11514
|
+
signal: signal
|
|
11515
|
+
});
|
|
11516
|
+
if (!res.ok) throw new Error(`HTTP ${res.status}`);
|
|
11517
|
+
const features = await res.json();
|
|
11518
|
+
if (!Array.isArray(features)) return [];
|
|
11519
|
+
const of = (type)=>features.filter((f)=>f && f.feature_type === type);
|
|
11520
|
+
const transcripts = of('transcript');
|
|
11521
|
+
const exons = of('exon');
|
|
11522
|
+
const cds = of('cds');
|
|
11523
|
+
return of('gene').map((gene)=>{
|
|
11524
|
+
// One transcript per gene: the canonical one when Ensembl marks it.
|
|
11525
|
+
const mine = transcripts.filter((t)=>t.Parent === gene.id);
|
|
11526
|
+
const transcript = mine.find((t)=>t.is_canonical) || mine[0];
|
|
11527
|
+
const myExons = transcript ? exons.filter((e)=>e.Parent === transcript.id) : [];
|
|
11528
|
+
const myCds = transcript ? cds.filter((c)=>c.Parent === transcript.id) : [];
|
|
11529
|
+
return {
|
|
11530
|
+
id: gene.id,
|
|
11531
|
+
label: gene.external_name || gene.id,
|
|
11532
|
+
start: gene.start,
|
|
11533
|
+
end: gene.end,
|
|
11534
|
+
strand: gene.strand === -1 ? -1 : 1,
|
|
11535
|
+
// Ensembl returns only the exons overlapping the window, which is all
|
|
11536
|
+
// the browser can show anyway.
|
|
11537
|
+
exons: myExons.map((e)=>({
|
|
11538
|
+
start: e.start,
|
|
11539
|
+
end: e.end
|
|
11540
|
+
})),
|
|
11541
|
+
cds: myCds.length ? {
|
|
11542
|
+
start: Math.min(...myCds.map((c)=>c.start)),
|
|
11543
|
+
end: Math.max(...myCds.map((c)=>c.end))
|
|
11544
|
+
} : null,
|
|
11545
|
+
biotype: gene.biotype
|
|
11546
|
+
};
|
|
11547
|
+
});
|
|
11548
|
+
};
|
|
11549
|
+
}
|
|
11550
|
+
|
|
11551
|
+
|
|
11488
11552
|
// Primers detail: PCR/qPCR primer design, genome specificity and pan-genome
|
|
11489
11553
|
// coverage checks (gramene-primers <PrimerDesigner>, backed by the
|
|
11490
11554
|
// gramene-swagger /primers endpoints).
|
|
@@ -11505,7 +11569,8 @@ const $88d24ae9beb83d5d$var$MODES = [
|
|
|
11505
11569
|
'gene',
|
|
11506
11570
|
'transcript',
|
|
11507
11571
|
'region',
|
|
11508
|
-
'sequence'
|
|
11572
|
+
'sequence',
|
|
11573
|
+
'genotyping'
|
|
11509
11574
|
];
|
|
11510
11575
|
const $88d24ae9beb83d5d$var$geneHref = (id)=>`?idList=${encodeURIComponent(id)}`;
|
|
11511
11576
|
// Plain left clicks on gene links in check results open a new tab, so the
|
|
@@ -11515,9 +11580,15 @@ const $88d24ae9beb83d5d$var$Primers = (props)=>{
|
|
|
11515
11580
|
const geneId = props.searchResult.id;
|
|
11516
11581
|
const gene = props.geneDocs[geneId] // Gene.ensureGene() guarantees it is loaded
|
|
11517
11582
|
;
|
|
11518
|
-
const conf = props.config.details.primers // true | { apiBase?, pangenome? }
|
|
11583
|
+
const conf = props.config.details.primers // true | { apiBase?, pangenome?, genotyping? }
|
|
11519
11584
|
;
|
|
11520
11585
|
const apiBase = conf && typeof conf === 'object' && conf.apiBase || props.grameneAPI;
|
|
11586
|
+
// Gene models for the variant browser come from Ensembl REST, which must be
|
|
11587
|
+
// the same release the primers API reads variants from.
|
|
11588
|
+
const ensemblRest = props.config && props.config.ensemblRest;
|
|
11589
|
+
const genesInRegion = (0, $gXNCa$react.useMemo)(()=>(0, $31284fcdc45a1688$export$3a249e9030170bda)(ensemblRest), [
|
|
11590
|
+
ensemblRest
|
|
11591
|
+
]);
|
|
11521
11592
|
const byGene = props.uiViewState && props.uiViewState.byGene && props.uiViewState.byGene[geneId];
|
|
11522
11593
|
const saved = byGene && byGene.primers;
|
|
11523
11594
|
const { doSetPrimersState: doSetPrimersState } = props;
|
|
@@ -11538,13 +11609,15 @@ const $88d24ae9beb83d5d$var$Primers = (props)=>{
|
|
|
11538
11609
|
gene: gene,
|
|
11539
11610
|
systemName: gene.system_name,
|
|
11540
11611
|
modes: $88d24ae9beb83d5d$var$MODES,
|
|
11612
|
+
genesInRegion: genesInRegion,
|
|
11541
11613
|
defaultMode: "gene",
|
|
11542
11614
|
// an empty slice (never visited, or a snapshot without primers) leaves
|
|
11543
11615
|
// the designer uncontrolled until its first change is stored
|
|
11544
11616
|
state: saved && Object.keys(saved).length ? saved : undefined,
|
|
11545
11617
|
onStateChange: onStateChange,
|
|
11546
11618
|
features: {
|
|
11547
|
-
pangenome: !(conf && conf.pangenome === false)
|
|
11619
|
+
pangenome: !(conf && conf.pangenome === false),
|
|
11620
|
+
genotyping: !(conf && conf.genotyping === false)
|
|
11548
11621
|
},
|
|
11549
11622
|
geneHref: $88d24ae9beb83d5d$var$geneHref,
|
|
11550
11623
|
onGeneClick: $88d24ae9beb83d5d$var$openGene,
|