@rivm-loculus-tools/common-frontend 0.1.0 → 0.1.4
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/_chunks/FastaDataImportDialog.js +309 -0
- package/dist/_chunks/FastaDataImportDialog.js.map +1 -0
- package/dist/_chunks/react.js +11 -0
- package/dist/_chunks/react.js.map +1 -0
- package/dist/classes/services/FastaDataEventBusService/FastaDataEventBusService.d.ts +10 -0
- package/dist/classes/services/FastaDataEventBusService/index.js +16 -0
- package/dist/classes/services/FastaDataEventBusService/index.js.map +1 -0
- package/dist/components/FastaDataImportDialog/FastaDataImportDialog.d.ts +12 -0
- package/dist/components/FastaDataImportDialog/index.js +2 -0
- package/dist/components/FastaDataImportDialogLoader/FastaDataImportDialogLoader.d.ts +8 -0
- package/dist/components/FastaDataImportDialogLoader/index.js +70 -0
- package/dist/components/FastaDataImportDialogLoader/index.js.map +1 -0
- package/dist/components/FastaNotLoaded/FastaNotLoaded.d.ts +7 -0
- package/dist/components/FastaNotLoaded/index.js +53 -0
- package/dist/components/FastaNotLoaded/index.js.map +1 -0
- package/dist/components/FastaPageHeaderCenterComponent/FastaPageHeaderCenterComponent.d.ts +6 -0
- package/dist/components/FastaPageHeaderCenterComponent/index.js +37 -0
- package/dist/components/FastaPageHeaderCenterComponent/index.js.map +1 -0
- package/dist/components/FastaPageHeaderImportButton/FastaPageHeaderImportButton.d.ts +1 -0
- package/dist/components/FastaPageHeaderImportButton/index.js +26 -0
- package/dist/components/FastaPageHeaderImportButton/index.js.map +1 -0
- package/dist/components/FastaPageHeaderResetButton/FastaPageHeaderResetButton.d.ts +4 -0
- package/dist/components/FastaPageHeaderResetButton/index.js +35 -0
- package/dist/components/FastaPageHeaderResetButton/index.js.map +1 -0
- package/dist/components/I18nWrapper/I18nWrapper.d.ts +4 -0
- package/dist/components/I18nWrapper/index.js +21 -0
- package/dist/components/I18nWrapper/index.js.map +1 -0
- package/dist/components/PageHeaderDocumentationButton/PageHeaderDocumentationButton.d.ts +1 -0
- package/dist/components/PageHeaderDocumentationButton/index.js +24 -0
- package/dist/components/PageHeaderDocumentationButton/index.js.map +1 -0
- package/dist/components/SearchBar/SearchBar.d.ts +10 -0
- package/dist/components/SearchBar/SearchBarNodeCounter.d.ts +4 -0
- package/dist/components/SearchBar/index.js +129 -0
- package/dist/components/SearchBar/index.js.map +1 -0
- package/dist/components/page/ErrorPageCommon.d.ts +4 -0
- package/dist/components/page/PageCommon.d.ts +8 -0
- package/dist/components/page/PageCommonContext.d.ts +7 -0
- package/dist/components/page/PageCommonContextProvider.d.ts +3 -0
- package/dist/components/page/PageCommonDrawer.d.ts +5 -0
- package/dist/components/page/PageCommonHeader.d.ts +8 -0
- package/dist/components/page/index.js +207 -0
- package/dist/components/page/index.js.map +1 -0
- package/dist/constants/page.d.ts +1 -0
- package/dist/constants/page.js +6 -0
- package/dist/constants/page.js.map +1 -0
- package/dist/models/fasta.d.ts +23 -0
- package/dist/models/fasta.js +8 -0
- package/dist/models/fasta.js.map +1 -0
- package/dist/models/metadata.d.ts +9 -0
- package/dist/stores/fastaDataStore/fastaDataStore.d.ts +32 -0
- package/dist/stores/fastaDataStore/index.js +57 -0
- package/dist/stores/fastaDataStore/index.js.map +1 -0
- package/dist/theme/index.js +257 -0
- package/dist/theme/index.js.map +1 -0
- package/dist/theme/theme.d.ts +1 -0
- package/dist/utils/DownloadUtil/DownloadUtil.d.ts +3 -0
- package/dist/utils/DownloadUtil/index.js +10 -0
- package/dist/utils/DownloadUtil/index.js.map +1 -0
- package/dist/utils/ErrorUtil/ErrorUtil.d.ts +3 -0
- package/dist/utils/ErrorUtil/index.js +10 -0
- package/dist/utils/ErrorUtil/index.js.map +1 -0
- package/dist/utils/FastaUtil/FastaUtil.d.ts +6 -0
- package/dist/utils/FastaUtil/index.js +63 -0
- package/dist/utils/FastaUtil/index.js.map +1 -0
- package/dist/utils/MetaDataUtil/MetaDataUtil.d.ts +20 -0
- package/dist/utils/MetaDataUtil/index.js +133 -0
- package/dist/utils/MetaDataUtil/index.js.map +1 -0
- package/dist/utils/UrlUtil/UrlUtil.d.ts +5 -0
- package/dist/utils/UrlUtil/index.js +30 -0
- package/dist/utils/UrlUtil/index.js.map +1 -0
- package/package.json +10 -7
- package/CHANGELOG.md +0 -8
- package/eslint.config.js +0 -16
- package/scripts/update-exports.js +0 -9
- package/src/classes/services/FastaDataEventBusService/FastaDataEventBusService.ts +0 -22
- package/src/components/FastaDataImportDialog/FastaDataImportDialog.tsx +0 -364
- package/src/components/FastaDataImportDialogLoader/FastaDataImportDialogLoader.tsx +0 -124
- package/src/components/FastaNotLoaded/FastaNotLoaded.tsx +0 -62
- package/src/components/FastaPageHeaderCenterComponent/FastaPageHeaderCenterComponent.tsx +0 -50
- package/src/components/FastaPageHeaderImportButton/FastaPageHeaderImportButton.tsx +0 -28
- package/src/components/FastaPageHeaderResetButton/FastaPageHeaderResetButton.tsx +0 -50
- package/src/components/I18nWrapper/I18nWrapper.tsx +0 -39
- package/src/components/PageHeaderDocumentationButton/PageHeaderDocumentationButton.tsx +0 -25
- package/src/components/SearchBar/SearchBar.tsx +0 -207
- package/src/components/SearchBar/SearchBarNodeCounter.tsx +0 -23
- package/src/components/page/ErrorPageCommon.tsx +0 -51
- package/src/components/page/PageCommon.tsx +0 -76
- package/src/components/page/PageCommonContext.ts +0 -15
- package/src/components/page/PageCommonContextProvider.tsx +0 -30
- package/src/components/page/PageCommonDrawer.tsx +0 -35
- package/src/components/page/PageCommonHeader.tsx +0 -99
- package/src/constants/page.ts +0 -1
- package/src/index.ts +0 -21
- package/src/models/fasta.ts +0 -22
- package/src/models/metadata.ts +0 -10
- package/src/stores/fastaDataStore/fastaDataStore.ts +0 -103
- package/src/theme/fonts/RobotoFlex.woff2 +0 -0
- package/src/theme/theme.ts +0 -368
- package/src/utils/DownloadUtil/DownloadUtil.ts +0 -10
- package/src/utils/ErrorUtil/ErrorUtil.ts +0 -5
- package/src/utils/FastaUtil/FastaUtil.ts +0 -109
- package/src/utils/MetaDataUtil/MetaDataUtil.ts +0 -292
- package/src/utils/UrlUtil/UrlUtil.ts +0 -35
- package/tsconfig.build.json +0 -14
- package/tsconfig.json +0 -32
- package/vite.config.ts +0 -137
- /package/{src → dist}/@types/vite-env.d.ts +0 -0
- /package/{src/classes/services/FastaDataEventBusService/index.ts → dist/classes/services/FastaDataEventBusService/index.d.ts} +0 -0
- /package/{src/components/FastaDataImportDialog/index.ts → dist/components/FastaDataImportDialog/index.d.ts} +0 -0
- /package/{src/components/FastaDataImportDialogLoader/index.ts → dist/components/FastaDataImportDialogLoader/index.d.ts} +0 -0
- /package/{src/components/FastaNotLoaded/index.ts → dist/components/FastaNotLoaded/index.d.ts} +0 -0
- /package/{src/components/FastaPageHeaderCenterComponent/index.ts → dist/components/FastaPageHeaderCenterComponent/index.d.ts} +0 -0
- /package/{src/components/FastaPageHeaderImportButton/index.ts → dist/components/FastaPageHeaderImportButton/index.d.ts} +0 -0
- /package/{src/components/FastaPageHeaderResetButton/index.ts → dist/components/FastaPageHeaderResetButton/index.d.ts} +0 -0
- /package/{src/components/I18nWrapper/index.ts → dist/components/I18nWrapper/index.d.ts} +0 -0
- /package/{src/components/PageHeaderDocumentationButton/index.ts → dist/components/PageHeaderDocumentationButton/index.d.ts} +0 -0
- /package/{src/components/SearchBar/index.ts → dist/components/SearchBar/index.d.ts} +0 -0
- /package/{src/components/page/index.ts → dist/components/page/index.d.ts} +0 -0
- /package/{src/.gitkeep → dist/models/metadata.js} +0 -0
- /package/{src/stores/fastaDataStore/index.ts → dist/stores/fastaDataStore/index.d.ts} +0 -0
- /package/{src/theme/index.ts → dist/theme/index.d.ts} +0 -0
- /package/{src/utils/DownloadUtil/index.ts → dist/utils/DownloadUtil/index.d.ts} +0 -0
- /package/{src/utils/ErrorUtil/index.ts → dist/utils/ErrorUtil/index.d.ts} +0 -0
- /package/{src/utils/FastaUtil/index.ts → dist/utils/FastaUtil/index.d.ts} +0 -0
- /package/{src/utils/MetaDataUtil/index.ts → dist/utils/MetaDataUtil/index.d.ts} +0 -0
- /package/{src/utils/UrlUtil/index.ts → dist/utils/UrlUtil/index.d.ts} +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const theme: import('@mui/material').Theme;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
//#region src/utils/DownloadUtil/DownloadUtil.ts
|
|
2
|
+
var e = class {
|
|
3
|
+
static datasetFilename(e) {
|
|
4
|
+
return `${e.trim().replace(/\.[^.]+$/, "").replace(/[^a-zA-Z0-9._-]+/g, "_").replace(/^\.+|\.+$/g, "").slice(0, 80) || "alignment"}.fasta`;
|
|
5
|
+
}
|
|
6
|
+
};
|
|
7
|
+
//#endregion
|
|
8
|
+
export { e as DownloadUtil };
|
|
9
|
+
|
|
10
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../../src/utils/DownloadUtil/DownloadUtil.ts"],"sourcesContent":["export class DownloadUtil {\n public static datasetFilename(label: string): string {\n const withoutExtension = label.trim().replace(/\\.[^.]+$/, '');\n const safeLabel = withoutExtension\n .replace(/[^a-zA-Z0-9._-]+/g, '_')\n .replace(/^\\.+|\\.+$/g, '')\n .slice(0, 80);\n return `${safeLabel || 'alignment'}.fasta`;\n }\n}\n"],"mappings":";AAAA,IAAa,IAAb,MAA0B;CACxB,OAAc,gBAAgB,GAAuB;EAMnD,OAAO,GALkB,EAAM,KAAK,CAAC,CAAC,QAAQ,YAAY,EACxC,CAAA,CACf,QAAQ,qBAAqB,GAAG,CAAC,CACjC,QAAQ,cAAc,EAAE,CAAC,CACzB,MAAM,GAAG,EACF,KAAa,YAAY;CACrC;AACF"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../../src/utils/ErrorUtil/ErrorUtil.ts"],"sourcesContent":["export class ErrorUtil {\n public static getErrorMessage(error: unknown, fallback: string): string {\n return error instanceof Error ? error.message : fallback;\n }\n}\n"],"mappings":";AAAA,IAAa,IAAb,MAAuB;CACrB,OAAc,gBAAgB,GAAgB,GAA0B;EACtE,OAAO,aAAiB,QAAQ,EAAM,UAAU;CAClD;AACF"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
//#region src/utils/FastaUtil/FastaUtil.ts
|
|
2
|
+
var e = class e {
|
|
3
|
+
static parseFasta(t) {
|
|
4
|
+
if (!t?.trim()) return e.createErrorResult("The FASTA input is empty.");
|
|
5
|
+
let n = t.split(/\r?\n/), r = [], i = "", a = [], o = () => {
|
|
6
|
+
if (i) {
|
|
7
|
+
let t = a.join("").replace(/\s/g, "").toUpperCase();
|
|
8
|
+
if (!t.length) return e.createErrorResult(`FASTA record "${i}" has no sequence.`);
|
|
9
|
+
let n = i.split(/[|\t]/)[0].trim().replace(/[():;,']/g, "_");
|
|
10
|
+
r.push({
|
|
11
|
+
accessionVersion: n,
|
|
12
|
+
header: i,
|
|
13
|
+
id: n,
|
|
14
|
+
length: t.length,
|
|
15
|
+
sequence: t
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
return null;
|
|
19
|
+
};
|
|
20
|
+
for (let t of n) {
|
|
21
|
+
let n = t.trim();
|
|
22
|
+
if (n) {
|
|
23
|
+
if (n.startsWith(">")) {
|
|
24
|
+
let t = o();
|
|
25
|
+
if (t) return t;
|
|
26
|
+
if (i = n.slice(1).trim(), !i) return e.createErrorResult("Every FASTA record needs a non-empty header.");
|
|
27
|
+
a = [];
|
|
28
|
+
} else {
|
|
29
|
+
if (!i) return e.createErrorResult("FASTA sequence data appeared before its first header.");
|
|
30
|
+
a.push(n);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
let s = o();
|
|
35
|
+
if (s) return s;
|
|
36
|
+
if (r.length === 0) return e.createErrorResult("No FASTA records were found.");
|
|
37
|
+
let c = r[0].length, l = r.filter((e) => e.length !== c).map((e) => ({
|
|
38
|
+
id: e.id,
|
|
39
|
+
length: e.length
|
|
40
|
+
})), u = l.length === 0;
|
|
41
|
+
return {
|
|
42
|
+
expectedLength: c,
|
|
43
|
+
invalidSequences: u ? void 0 : l,
|
|
44
|
+
isAligned: u,
|
|
45
|
+
sequences: r
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
static stripFastaHeaders(e) {
|
|
49
|
+
return e.split("\n").map((e) => e.startsWith(">") ? `>${e.substring(1).trim().split(/[|\t]/)[0].trim().replace(/[():;,']/g, "_")}` : e).join("\n");
|
|
50
|
+
}
|
|
51
|
+
static createErrorResult(e) {
|
|
52
|
+
return {
|
|
53
|
+
error: e,
|
|
54
|
+
expectedLength: 0,
|
|
55
|
+
isAligned: !1,
|
|
56
|
+
sequences: []
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
//#endregion
|
|
61
|
+
export { e as FastaUtil };
|
|
62
|
+
|
|
63
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../../src/utils/FastaUtil/FastaUtil.ts"],"sourcesContent":["import type {\n FastaParseResult,\n FastaSequence,\n} from '../../models/fasta';\n\nexport class FastaUtil {\n public static parseFasta(content: string): FastaParseResult {\n if (!content?.trim()) {\n return FastaUtil.createErrorResult('The FASTA input is empty.');\n }\n\n const lines = content.split(/\\r?\\n/);\n const sequences: FastaSequence[] = [];\n let currentHeader = '';\n let currentSeqParts: string[] = [];\n\n const commitSequence = (): FastaParseResult | null => {\n if (currentHeader) {\n const fullSeq = currentSeqParts.join('').replace(/\\s/g, '').toUpperCase();\n if (!fullSeq.length) {\n return FastaUtil.createErrorResult(`FASTA record \"${currentHeader}\" has no sequence.`);\n }\n\n // Extract ID: part before pipe or tab, sanitized for Newick compatibility\n const firstPart = currentHeader.split(/[|\\t]/)[0].trim();\n const safeId = firstPart.replace(/[():;,']/g, '_');\n\n sequences.push({\n accessionVersion: safeId,\n header: currentHeader,\n id: safeId,\n length: fullSeq.length,\n sequence: fullSeq,\n });\n }\n return null;\n };\n\n for (const sourceLine of lines) {\n const line = sourceLine.trim();\n if (!line) {\n continue;\n }\n\n if (line.startsWith('>')) {\n const error = commitSequence();\n if (error) {\n return error;\n }\n currentHeader = line.slice(1).trim();\n if (!currentHeader) {\n return FastaUtil.createErrorResult('Every FASTA record needs a non-empty header.');\n }\n currentSeqParts = [];\n } else {\n if (!currentHeader) {\n return FastaUtil.createErrorResult('FASTA sequence data appeared before its first header.');\n }\n currentSeqParts.push(line);\n }\n }\n const error = commitSequence();\n if (error) {\n return error;\n }\n\n if (sequences.length === 0) {\n return FastaUtil.createErrorResult('No FASTA records were found.');\n }\n\n // Pre-alignment validation: verify all sequence lengths are equal\n const firstLength = sequences[0].length;\n const invalidSequences = sequences.filter((s) => s.length !== firstLength).map((s) => ({ id: s.id, length: s.length }));\n\n const isAligned = invalidSequences.length === 0;\n\n return {\n expectedLength: firstLength,\n invalidSequences: isAligned ? undefined : invalidSequences,\n isAligned,\n sequences,\n };\n }\n\n public static stripFastaHeaders(fastaContent: string): string {\n const lines = fastaContent.split('\\n');\n const strippedLines = lines.map((line) => {\n if (line.startsWith('>')) {\n const cleanHeader = line.substring(1).trim();\n const firstPart = cleanHeader.split(/[|\\t]/)[0].trim();\n const safeId = firstPart.replace(/[():;,']/g, '_');\n return `>${safeId}`;\n }\n return line;\n });\n return strippedLines.join('\\n');\n }\n\n\n private static createErrorResult(error: string): FastaParseResult {\n return {\n error,\n expectedLength: 0,\n isAligned: false,\n sequences: [],\n };\n }\n\n}\n"],"mappings":";AAKA,IAAa,IAAb,MAAa,EAAU;CACrB,OAAc,WAAW,GAAmC;EAC1D,IAAI,CAAC,GAAS,KAAK,GACjB,OAAO,EAAU,kBAAkB,2BAA2B;EAGhE,IAAM,IAAQ,EAAQ,MAAM,OAAO,GAC7B,IAA6B,CAAC,GAChC,IAAgB,IAChB,IAA4B,CAAC,GAE3B,UAAgD;GACpD,IAAI,GAAe;IACjB,IAAM,IAAU,EAAgB,KAAK,EAAE,CAAC,CAAC,QAAQ,OAAO,EAAE,CAAC,CAAC,YAAY;IACxE,IAAI,CAAC,EAAQ,QACX,OAAO,EAAU,kBAAkB,iBAAiB,EAAc,mBAAmB;IAKvF,IAAM,IADY,EAAc,MAAM,OAAO,CAAC,CAAC,EAAE,CAAC,KACnC,CAAA,CAAU,QAAQ,aAAa,GAAG;IAEjD,EAAU,KAAK;KACb,kBAAkB;KAClB,QAAQ;KACR,IAAI;KACJ,QAAQ,EAAQ;KAChB,UAAU;IACZ,CAAC;GACH;GACA,OAAO;EACT;EAEA,KAAK,IAAM,KAAc,GAAO;GAC9B,IAAM,IAAO,EAAW,KAAK;GACxB,OAIL;QAAI,EAAK,WAAW,GAAG,GAAG;KACxB,IAAM,IAAQ,EAAe;KAC7B,IAAI,GACF,OAAO;KAGT,IADA,IAAgB,EAAK,MAAM,CAAC,CAAC,CAAC,KAAK,GAC/B,CAAC,GACH,OAAO,EAAU,kBAAkB,8CAA8C;KAEnF,IAAkB,CAAC;IACrB,OAAO;KACL,IAAI,CAAC,GACH,OAAO,EAAU,kBAAkB,uDAAuD;KAE5F,EAAgB,KAAK,CAAI;IAC3B;;EACF;EACA,IAAM,IAAQ,EAAe;EAC7B,IAAI,GACF,OAAO;EAGT,IAAI,EAAU,WAAW,GACvB,OAAO,EAAU,kBAAkB,8BAA8B;EAInE,IAAM,IAAc,EAAU,EAAE,CAAC,QAC3B,IAAmB,EAAU,QAAQ,MAAM,EAAE,WAAW,CAAW,CAAC,CAAC,KAAK,OAAO;GAAE,IAAI,EAAE;GAAI,QAAQ,EAAE;EAAO,EAAE,GAEhH,IAAY,EAAiB,WAAW;EAE9C,OAAO;GACL,gBAAgB;GAChB,kBAAkB,IAAY,KAAA,IAAY;GAC1C;GACA;EACF;CACF;CAEA,OAAc,kBAAkB,GAA8B;EAW5D,OAVc,EAAa,MAAM,IACX,CAAA,CAAM,KAAK,MAC3B,EAAK,WAAW,GAAG,IAId,IAHa,EAAK,UAAU,CAAC,CAAC,CAAC,KACpB,CAAA,CAAY,MAAM,OAAO,CAAC,CAAC,EAAE,CAAC,KACjC,CAAA,CAAU,QAAQ,aAAa,GACnC,MAEN,CAEF,CAAA,CAAc,KAAK,IAAI;CAChC;CAGA,OAAe,kBAAkB,GAAiC;EAChE,OAAO;GACL;GACA,gBAAgB;GAChB,WAAW;GACX,WAAW,CAAC;EACd;CACF;AAEF"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { MetadataParseResult, MetadataRecord } from '../../models/metadata';
|
|
2
|
+
export declare class MetaDataUtil {
|
|
3
|
+
/**
|
|
4
|
+
* Compute the best matching metadata column for the given FASTA sequence IDs.
|
|
5
|
+
*/
|
|
6
|
+
static findBestMatchingColumn: (columns: string[], recordsByColumn: Record<string, Record<string, MetadataRecord>>, fastaIds: string[]) => {
|
|
7
|
+
bestColumn: null | string;
|
|
8
|
+
matchCounts: Record<string, number>;
|
|
9
|
+
};
|
|
10
|
+
static getHighlightedIds(query: string, allAccessions: string[], metadataRecords: MetadataRecord[], matchKeyField?: null | string): string[];
|
|
11
|
+
/**
|
|
12
|
+
* Count FASTA sequence ID matches for each metadata column.
|
|
13
|
+
*/
|
|
14
|
+
static getMatchCounts: (columns: string[], recordsByColumn: Record<string, Record<string, MetadataRecord>>, fastaIds: string[]) => Record<string, number>;
|
|
15
|
+
/**
|
|
16
|
+
* Retrieve metadata record for a given sample/node name with fallback strategies.
|
|
17
|
+
*/
|
|
18
|
+
static readonly getRecordForSample: (metadata: MetadataParseResult | null | undefined, sampleId: string, matchKeyField?: null | string) => MetadataRecord | undefined;
|
|
19
|
+
static parseTsv: (content: string) => MetadataParseResult;
|
|
20
|
+
}
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
//#region src/utils/MetaDataUtil/MetaDataUtil.ts
|
|
2
|
+
var e = class e {
|
|
3
|
+
static findBestMatchingColumn = (t, n, r) => {
|
|
4
|
+
let i = e.getMatchCounts(t, n, r), a = null, o = -1;
|
|
5
|
+
if (!t || !n || !r || r.length === 0) return {
|
|
6
|
+
bestColumn: null,
|
|
7
|
+
matchCounts: {}
|
|
8
|
+
};
|
|
9
|
+
let s = [
|
|
10
|
+
"displayname",
|
|
11
|
+
"accessionversion",
|
|
12
|
+
"accession",
|
|
13
|
+
"sampleid",
|
|
14
|
+
"sample_id",
|
|
15
|
+
"id",
|
|
16
|
+
"strain",
|
|
17
|
+
"isolate",
|
|
18
|
+
"submissionid",
|
|
19
|
+
"name"
|
|
20
|
+
];
|
|
21
|
+
for (let e of t) {
|
|
22
|
+
if (!n[e]) continue;
|
|
23
|
+
let t = i[e];
|
|
24
|
+
if (t > o) o = t, a = e;
|
|
25
|
+
else if (t === o && t > 0 && a) {
|
|
26
|
+
let t = s.indexOf(a.toLowerCase()), n = s.indexOf(e.toLowerCase());
|
|
27
|
+
n !== -1 && (t === -1 || n < t) && (a = e);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
if (o <= 0) {
|
|
31
|
+
for (let e of s) {
|
|
32
|
+
let n = t.find((t) => t.toLowerCase() === e);
|
|
33
|
+
if (n) {
|
|
34
|
+
a = n;
|
|
35
|
+
break;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
!a && t.length > 0 && (a = t[0]);
|
|
39
|
+
}
|
|
40
|
+
return {
|
|
41
|
+
bestColumn: a,
|
|
42
|
+
matchCounts: i
|
|
43
|
+
};
|
|
44
|
+
};
|
|
45
|
+
static getHighlightedIds(e, t, n, r = null) {
|
|
46
|
+
let i = e.trim().toLowerCase();
|
|
47
|
+
if (!i) return [];
|
|
48
|
+
let a = /* @__PURE__ */ new Set();
|
|
49
|
+
return t.forEach((e) => {
|
|
50
|
+
e.toLowerCase().includes(i) && a.add(e);
|
|
51
|
+
}), n.forEach((e) => {
|
|
52
|
+
let t = r && e[r] || e.displayName || e.accessionVersion || e.accession || e.id || e.submissionId || e.SampleID;
|
|
53
|
+
t && Object.values(e).some((e) => typeof e == "string" && e.toLowerCase().includes(i)) && a.add(t);
|
|
54
|
+
}), Array.from(a);
|
|
55
|
+
}
|
|
56
|
+
static getMatchCounts = (e, t, n) => {
|
|
57
|
+
let r = {};
|
|
58
|
+
if (!e || !t || !n || n.length === 0) return r;
|
|
59
|
+
for (let i of e) {
|
|
60
|
+
let e = t[i];
|
|
61
|
+
if (!e) continue;
|
|
62
|
+
let a = 0;
|
|
63
|
+
for (let t of n) e[t] && a++;
|
|
64
|
+
r[i] = a;
|
|
65
|
+
}
|
|
66
|
+
return r;
|
|
67
|
+
};
|
|
68
|
+
static getRecordForSample = (e, t, n) => {
|
|
69
|
+
if (e && t) {
|
|
70
|
+
if (n && e.recordsByColumn?.[n]) {
|
|
71
|
+
let r = e.recordsByColumn[n][t];
|
|
72
|
+
if (r) return r;
|
|
73
|
+
}
|
|
74
|
+
if (e.recordsByColumn?.displayName?.[t]) return e.recordsByColumn.displayName[t];
|
|
75
|
+
if (e.recordsByColumn?.accessionVersion?.[t]) return e.recordsByColumn.accessionVersion[t];
|
|
76
|
+
if (e.recordsByAccession[t]) return e.recordsByAccession[t];
|
|
77
|
+
if (e.recordsBySampleId[t]) return e.recordsBySampleId[t];
|
|
78
|
+
if (e.recordsByColumn) for (let n of Object.keys(e.recordsByColumn)) {
|
|
79
|
+
let r = e.recordsByColumn[n][t];
|
|
80
|
+
if (r) return r;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
};
|
|
84
|
+
static parseTsv = (e) => {
|
|
85
|
+
if (!e?.trim()) return {
|
|
86
|
+
columns: [],
|
|
87
|
+
error: "Empty metadata content provided.",
|
|
88
|
+
records: [],
|
|
89
|
+
recordsByAccession: {},
|
|
90
|
+
recordsByColumn: {},
|
|
91
|
+
recordsBySampleId: {}
|
|
92
|
+
};
|
|
93
|
+
let t = e.trim().split("\n");
|
|
94
|
+
if (t.length < 2) return {
|
|
95
|
+
columns: [],
|
|
96
|
+
error: "Metadata file must contain at least a header row and one data row.",
|
|
97
|
+
records: [],
|
|
98
|
+
recordsByAccession: {},
|
|
99
|
+
recordsByColumn: {},
|
|
100
|
+
recordsBySampleId: {}
|
|
101
|
+
};
|
|
102
|
+
let n = t[0].trim(), r = " ";
|
|
103
|
+
!n.includes(" ") && n.includes(",") && (r = ",");
|
|
104
|
+
let i = n.split(r).map((e) => e.trim().replace(/^["']|["']$/g, "")).filter((e) => e.length > 0), a = [], o = {}, s = {}, c = {};
|
|
105
|
+
i.forEach((e) => {
|
|
106
|
+
c[e] = {};
|
|
107
|
+
});
|
|
108
|
+
for (let e = 1; e < t.length; e++) {
|
|
109
|
+
let n = t[e].trim();
|
|
110
|
+
if (!n) continue;
|
|
111
|
+
let l = n.split(r).map((e) => e.trim().replace(/^["']|["']$/g, "")), u = {};
|
|
112
|
+
i.forEach((e, t) => {
|
|
113
|
+
let n = l[t] ?? "";
|
|
114
|
+
u[e] = n, n && (c[e][n] = u);
|
|
115
|
+
}), a.push(u);
|
|
116
|
+
let d = u.displayName || u.accessionVersion || u.accession || u.id || u.submissionId || u.strain || u.isolate || u.name;
|
|
117
|
+
d && (o[d] = u);
|
|
118
|
+
let f = u.SampleID || u.sampleId || u.sample_id || u.specimenCollectorSampleId || u.id;
|
|
119
|
+
f && (s[f] = u);
|
|
120
|
+
}
|
|
121
|
+
return {
|
|
122
|
+
columns: i,
|
|
123
|
+
records: a,
|
|
124
|
+
recordsByAccession: o,
|
|
125
|
+
recordsByColumn: c,
|
|
126
|
+
recordsBySampleId: s
|
|
127
|
+
};
|
|
128
|
+
};
|
|
129
|
+
};
|
|
130
|
+
//#endregion
|
|
131
|
+
export { e as MetaDataUtil };
|
|
132
|
+
|
|
133
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../../src/utils/MetaDataUtil/MetaDataUtil.ts"],"sourcesContent":["import type {\n MetadataParseResult,\n MetadataRecord,\n} from '../../models/metadata';\n\nexport class MetaDataUtil {\n /**\n * Compute the best matching metadata column for the given FASTA sequence IDs.\n */\n public static findBestMatchingColumn = (\n columns: string[],\n recordsByColumn: Record<string, Record<string, MetadataRecord>>,\n fastaIds: string[],\n ): { bestColumn: null | string; matchCounts: Record<string, number> } => {\n const matchCounts = MetaDataUtil.getMatchCounts(columns, recordsByColumn, fastaIds);\n let bestColumn: null | string = null;\n let maxMatches = -1;\n\n if (!columns || !recordsByColumn || !fastaIds || fastaIds.length === 0) {\n return { bestColumn: null, matchCounts: {} };\n }\n\n const prioritizedKeys = [\n 'displayname',\n 'accessionversion',\n 'accession',\n 'sampleid',\n 'sample_id',\n 'id',\n 'strain',\n 'isolate',\n 'submissionid',\n 'name',\n ];\n\n for (const col of columns) {\n const colDict = recordsByColumn[col];\n if (!colDict) {\n continue;\n }\n\n const count = matchCounts[col];\n\n if (count > maxMatches) {\n maxMatches = count;\n bestColumn = col;\n } else if (count === maxMatches && count > 0 && bestColumn) {\n // Tie-breaker: prioritize standard ID column names\n const currentPriority = prioritizedKeys.indexOf(bestColumn.toLowerCase());\n const newPriority = prioritizedKeys.indexOf(col.toLowerCase());\n if (newPriority !== -1 && (currentPriority === -1 || newPriority < currentPriority)) {\n bestColumn = col;\n }\n }\n }\n\n if (maxMatches <= 0) {\n // If no matches, default to highest priority known ID column if available\n for (const pKey of prioritizedKeys) {\n const found = columns.find((c) => c.toLowerCase() === pKey);\n if (found) {\n bestColumn = found;\n break;\n }\n }\n if (!bestColumn && columns.length > 0) {\n bestColumn = columns[0];\n }\n }\n\n return { bestColumn, matchCounts };\n };\n\n public static getHighlightedIds(query: string, allAccessions: string[], metadataRecords: MetadataRecord[], matchKeyField: null | string = null): string[] {\n const trimmed = query.trim().toLowerCase();\n if (!trimmed) {\n return [];\n }\n\n const matched = new Set<string>();\n\n // Check accession names / fasta IDs\n allAccessions.forEach((acc) => {\n if (acc.toLowerCase().includes(trimmed)) {\n matched.add(acc);\n }\n });\n\n // Check metadata records\n metadataRecords.forEach((rec) => {\n const acc =\n (matchKeyField && rec[matchKeyField]) ||\n rec.displayName ||\n rec.accessionVersion ||\n rec.accession ||\n rec.id ||\n rec.submissionId ||\n rec.SampleID;\n if (acc) {\n const matchesAnyField = Object.values(rec).some(\n (val) => typeof val === 'string' && val.toLowerCase().includes(trimmed),\n );\n if (matchesAnyField) {\n matched.add(acc);\n }\n }\n });\n\n return Array.from(matched);\n }\n /**\n * Count FASTA sequence ID matches for each metadata column.\n */\n public static getMatchCounts = (\n columns: string[],\n recordsByColumn: Record<string, Record<string, MetadataRecord>>,\n fastaIds: string[],\n ): Record<string, number> => {\n const matchCounts: Record<string, number> = {};\n\n if (!columns || !recordsByColumn || !fastaIds || fastaIds.length === 0) {\n return matchCounts;\n }\n\n for (const col of columns) {\n const colDict = recordsByColumn[col];\n if (!colDict) {\n continue;\n }\n\n let count = 0;\n for (const id of fastaIds) {\n if (colDict[id]) {\n count++;\n }\n }\n matchCounts[col] = count;\n }\n\n return matchCounts;\n };\n\n /**\n * Retrieve metadata record for a given sample/node name with fallback strategies.\n */\n public static readonly getRecordForSample = (\n metadata: MetadataParseResult | null | undefined,\n sampleId: string,\n matchKeyField?: null | string,\n ): MetadataRecord | undefined => {\n if (!metadata || !sampleId) {\n return undefined;\n }\n\n // 1. If matchKeyField is specified and exists, check it first\n if (matchKeyField && metadata.recordsByColumn?.[matchKeyField]) {\n const rec = metadata.recordsByColumn[matchKeyField][sampleId];\n if (rec) {\n return rec;\n }\n }\n\n // 2. Check displayName\n if (metadata.recordsByColumn?.['displayName']?.[sampleId]) {\n return metadata.recordsByColumn['displayName'][sampleId];\n }\n\n // 3. Check accessionVersion\n if (metadata.recordsByColumn?.['accessionVersion']?.[sampleId]) {\n return metadata.recordsByColumn['accessionVersion'][sampleId];\n }\n\n // 4. Check accession maps\n if (metadata.recordsByAccession[sampleId]) {\n return metadata.recordsByAccession[sampleId];\n }\n if (metadata.recordsBySampleId[sampleId]) {\n return metadata.recordsBySampleId[sampleId];\n }\n\n // 5. Broad search through all indexed columns\n if (metadata.recordsByColumn) {\n for (const col of Object.keys(metadata.recordsByColumn)) {\n const match = metadata.recordsByColumn[col][sampleId];\n if (match) {\n return match;\n }\n }\n }\n\n return undefined;\n };\n\n public static parseTsv = (content: string): MetadataParseResult => {\n if (!content?.trim()) {\n return {\n columns: [],\n error: 'Empty metadata content provided.',\n records: [],\n recordsByAccession: {},\n recordsByColumn: {},\n recordsBySampleId: {},\n };\n }\n\n const lines = content.trim().split('\\n');\n if (lines.length < 2) {\n return {\n columns: [],\n error: 'Metadata file must contain at least a header row and one data row.',\n records: [],\n recordsByAccession: {},\n recordsByColumn: {},\n recordsBySampleId: {},\n };\n }\n\n // Parse header row\n const headerLine = lines[0].trim();\n let delimiter = '\\t';\n if (!headerLine.includes('\\t') && headerLine.includes(',')) {\n delimiter = ',';\n }\n const columns = headerLine\n .split(delimiter)\n .map((col) => col.trim().replace(/^[\"']|[\"']$/g, ''))\n .filter((c) => c.length > 0);\n\n const records: MetadataRecord[] = [];\n const recordsByAccession: Record<string, MetadataRecord> = {};\n const recordsBySampleId: Record<string, MetadataRecord> = {};\n const recordsByColumn: Record<string, Record<string, MetadataRecord>> = {};\n\n columns.forEach((col) => {\n recordsByColumn[col] = {};\n });\n\n for (let i = 1; i < lines.length; i++) {\n const line = lines[i].trim();\n if (!line) {\n continue;\n }\n\n const values = line.split(delimiter).map((val) => val.trim().replace(/^[\"']|[\"']$/g, ''));\n const record: MetadataRecord = {};\n\n columns.forEach((col, colIdx) => {\n const val = values[colIdx] ?? '';\n record[col] = val;\n if (val) {\n recordsByColumn[col][val] = record;\n }\n });\n\n records.push(record);\n\n // Index by potential ID keys\n const accessionKey =\n record.displayName ||\n record.accessionVersion ||\n record.accession ||\n record.id ||\n record.submissionId ||\n record.strain ||\n record.isolate ||\n record.name;\n\n if (accessionKey) {\n recordsByAccession[accessionKey] = record;\n }\n\n const sampleIdKey =\n record.SampleID ||\n record.sampleId ||\n record.sample_id ||\n record.specimenCollectorSampleId ||\n record.id;\n\n if (sampleIdKey) {\n recordsBySampleId[sampleIdKey] = record;\n }\n }\n\n return {\n columns,\n records,\n recordsByAccession,\n recordsByColumn,\n recordsBySampleId,\n };\n };\n}\n"],"mappings":";AAKA,IAAa,IAAb,MAAa,EAAa;CAIxB,OAAc,0BACZ,GACA,GACA,MACuE;EACvE,IAAM,IAAc,EAAa,eAAe,GAAS,GAAiB,CAAQ,GAC9E,IAA4B,MAC5B,IAAa;EAEjB,IAAI,CAAC,KAAW,CAAC,KAAmB,CAAC,KAAY,EAAS,WAAW,GACnE,OAAO;GAAE,YAAY;GAAM,aAAa,CAAC;EAAE;EAG7C,IAAM,IAAkB;GACtB;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;EACF;EAEA,KAAK,IAAM,KAAO,GAAS;GAEzB,IAAI,CADY,EAAgB,IAE9B;GAGF,IAAM,IAAQ,EAAY;GAE1B,IAAI,IAAQ,GAEV,AADA,IAAa,GACb,IAAa;QACR,IAAI,MAAU,KAAc,IAAQ,KAAK,GAAY;IAE1D,IAAM,IAAkB,EAAgB,QAAQ,EAAW,YAAY,CAAC,GAClE,IAAc,EAAgB,QAAQ,EAAI,YAAY,CAAC;IAC7D,AAAI,MAAgB,OAAO,MAAoB,MAAM,IAAc,OACjE,IAAa;GAEjB;EACF;EAEA,IAAI,KAAc,GAAG;GAEnB,KAAK,IAAM,KAAQ,GAAiB;IAClC,IAAM,IAAQ,EAAQ,MAAM,MAAM,EAAE,YAAY,MAAM,CAAI;IAC1D,IAAI,GAAO;KACT,IAAa;KACb;IACF;GACF;GACA,AAAI,CAAC,KAAc,EAAQ,SAAS,MAClC,IAAa,EAAQ;EAEzB;EAEA,OAAO;GAAE;GAAY;EAAY;CACnC;CAEA,OAAc,kBAAkB,GAAe,GAAyB,GAAmC,IAA+B,MAAgB;EACxJ,IAAM,IAAU,EAAM,KAAK,CAAC,CAAC,YAAY;EACzC,IAAI,CAAC,GACH,OAAO,CAAC;EAGV,IAAM,oBAAU,IAAI,IAAY;EA6BhC,OA1BA,EAAc,SAAS,MAAQ;GAC7B,AAAI,EAAI,YAAY,CAAC,CAAC,SAAS,CAAO,KACpC,EAAQ,IAAI,CAAG;EAEnB,CAAC,GAGD,EAAgB,SAAS,MAAQ;GAC/B,IAAM,IACH,KAAiB,EAAI,MACtB,EAAI,eACJ,EAAI,oBACJ,EAAI,aACJ,EAAI,MACJ,EAAI,gBACJ,EAAI;GACN,AAAI,KACsB,OAAO,OAAO,CAAG,CAAC,CAAC,MACxC,MAAQ,OAAO,KAAQ,YAAY,EAAI,YAAY,CAAC,CAAC,SAAS,CAAO,CAEpE,KACF,EAAQ,IAAI,CAAG;EAGrB,CAAC,GAEM,MAAM,KAAK,CAAO;CAC3B;CAIA,OAAc,kBACZ,GACA,GACA,MAC2B;EAC3B,IAAM,IAAsC,CAAC;EAE7C,IAAI,CAAC,KAAW,CAAC,KAAmB,CAAC,KAAY,EAAS,WAAW,GACnE,OAAO;EAGT,KAAK,IAAM,KAAO,GAAS;GACzB,IAAM,IAAU,EAAgB;GAChC,IAAI,CAAC,GACH;GAGF,IAAI,IAAQ;GACZ,KAAK,IAAM,KAAM,GACf,AAAI,EAAQ,MACV;GAGJ,EAAY,KAAO;EACrB;EAEA,OAAO;CACT;CAKA,OAAuB,sBACrB,GACA,GACA,MAC+B;EAC3B,IAAC,KAAa,GAKlB;OAAI,KAAiB,EAAS,kBAAkB,IAAgB;IAC9D,IAAM,IAAM,EAAS,gBAAgB,EAAc,CAAC;IACpD,IAAI,GACF,OAAO;GAEX;GAGA,IAAI,EAAS,iBAAkB,cAAiB,IAC9C,OAAO,EAAS,gBAAgB,YAAe;GAIjD,IAAI,EAAS,iBAAkB,mBAAsB,IACnD,OAAO,EAAS,gBAAgB,iBAAoB;GAItD,IAAI,EAAS,mBAAmB,IAC9B,OAAO,EAAS,mBAAmB;GAErC,IAAI,EAAS,kBAAkB,IAC7B,OAAO,EAAS,kBAAkB;GAIpC,IAAI,EAAS,iBACX,KAAK,IAAM,KAAO,OAAO,KAAK,EAAS,eAAe,GAAG;IACvD,IAAM,IAAQ,EAAS,gBAAgB,EAAI,CAAC;IAC5C,IAAI,GACF,OAAO;GAEX;EA3BF;CA+BF;CAEA,OAAc,YAAY,MAAyC;EACjE,IAAI,CAAC,GAAS,KAAK,GACjB,OAAO;GACL,SAAS,CAAC;GACV,OAAO;GACP,SAAS,CAAC;GACV,oBAAoB,CAAC;GACrB,iBAAiB,CAAC;GAClB,mBAAmB,CAAC;EACtB;EAGF,IAAM,IAAQ,EAAQ,KAAK,CAAC,CAAC,MAAM,IAAI;EACvC,IAAI,EAAM,SAAS,GACjB,OAAO;GACL,SAAS,CAAC;GACV,OAAO;GACP,SAAS,CAAC;GACV,oBAAoB,CAAC;GACrB,iBAAiB,CAAC;GAClB,mBAAmB,CAAC;EACtB;EAIF,IAAM,IAAa,EAAM,EAAE,CAAC,KAAK,GAC7B,IAAY;EAChB,AAAI,CAAC,EAAW,SAAS,GAAI,KAAK,EAAW,SAAS,GAAG,MACvD,IAAY;EAEd,IAAM,IAAU,EACb,MAAM,CAAS,CAAC,CAChB,KAAK,MAAQ,EAAI,KAAK,CAAC,CAAC,QAAQ,gBAAgB,EAAE,CAAC,CAAC,CACpD,QAAQ,MAAM,EAAE,SAAS,CAAC,GAEvB,IAA4B,CAAC,GAC7B,IAAqD,CAAC,GACtD,IAAoD,CAAC,GACrD,IAAkE,CAAC;EAEzE,EAAQ,SAAS,MAAQ;GACvB,EAAgB,KAAO,CAAC;EAC1B,CAAC;EAED,KAAK,IAAI,IAAI,GAAG,IAAI,EAAM,QAAQ,KAAK;GACrC,IAAM,IAAO,EAAM,EAAE,CAAC,KAAK;GAC3B,IAAI,CAAC,GACH;GAGF,IAAM,IAAS,EAAK,MAAM,CAAS,CAAC,CAAC,KAAK,MAAQ,EAAI,KAAK,CAAC,CAAC,QAAQ,gBAAgB,EAAE,CAAC,GAClF,IAAyB,CAAC;GAUhC,AARA,EAAQ,SAAS,GAAK,MAAW;IAC/B,IAAM,IAAM,EAAO,MAAW;IAE9B,AADA,EAAO,KAAO,GACV,MACF,EAAgB,EAAI,CAAC,KAAO;GAEhC,CAAC,GAED,EAAQ,KAAK,CAAM;GAGnB,IAAM,IACJ,EAAO,eACP,EAAO,oBACP,EAAO,aACP,EAAO,MACP,EAAO,gBACP,EAAO,UACP,EAAO,WACP,EAAO;GAET,AAAI,MACF,EAAmB,KAAgB;GAGrC,IAAM,IACJ,EAAO,YACP,EAAO,YACP,EAAO,aACP,EAAO,6BACP,EAAO;GAET,AAAI,MACF,EAAkB,KAAe;EAErC;EAEA,OAAO;GACL;GACA;GACA;GACA;GACA;EACF;CACF;AACF"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { WindowService as e } from "@gen-epix/ui-core/classes/services/WindowService";
|
|
2
|
+
//#region src/utils/UrlUtil/UrlUtil.ts
|
|
3
|
+
var t = class {
|
|
4
|
+
static clearSearchParams() {
|
|
5
|
+
let t = new URL(e.getInstance().window.location.href);
|
|
6
|
+
t.search = "", e.getInstance().window.history.replaceState(null, "", t.toString());
|
|
7
|
+
}
|
|
8
|
+
static fastaLabelFromUrl(e) {
|
|
9
|
+
try {
|
|
10
|
+
let t = new URL(e), n = t.pathname.split("/").filter(Boolean).pop();
|
|
11
|
+
return n ? decodeURIComponent(n) : `${t.hostname}.fasta`;
|
|
12
|
+
} catch {
|
|
13
|
+
return "remote-alignment.fasta";
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
static validateFastaUrl(e) {
|
|
17
|
+
let t;
|
|
18
|
+
try {
|
|
19
|
+
t = new URL(e.trim());
|
|
20
|
+
} catch {
|
|
21
|
+
throw Error("Enter a valid FASTA URL.");
|
|
22
|
+
}
|
|
23
|
+
if (t.protocol !== "http:" && t.protocol !== "https:") throw Error("FASTA URLs must use HTTP or HTTPS.");
|
|
24
|
+
return t.href;
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
//#endregion
|
|
28
|
+
export { t as UrlUtil };
|
|
29
|
+
|
|
30
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../../src/utils/UrlUtil/UrlUtil.ts"],"sourcesContent":["import { WindowService } from '@gen-epix/ui-core/classes/services/WindowService';\n\nexport class UrlUtil {\n public static clearSearchParams(): void {\n const url = new URL(WindowService.getInstance().window.location.href);\n url.search = '';\n WindowService.getInstance().window.history.replaceState(null, '', url.toString());\n }\n\n public static fastaLabelFromUrl(url: string): string {\n try {\n const urlObject = new URL(url);\n const segment = urlObject.pathname.split('/').filter(Boolean).pop();\n if (segment) {\n return decodeURIComponent(segment);\n }\n return `${urlObject.hostname}.fasta`;\n } catch {\n return 'remote-alignment.fasta';\n }\n }\n\n public static validateFastaUrl(url: string): string {\n let urlObject: URL;\n try {\n urlObject = new URL(url.trim());\n } catch {\n throw new Error('Enter a valid FASTA URL.');\n }\n if (urlObject.protocol !== 'http:' && urlObject.protocol !== 'https:') {\n throw new Error('FASTA URLs must use HTTP or HTTPS.');\n }\n return urlObject.href;\n }\n}\n"],"mappings":";;AAEA,IAAa,IAAb,MAAqB;CACnB,OAAc,oBAA0B;EACtC,IAAM,IAAM,IAAI,IAAI,EAAc,YAAY,CAAC,CAAC,OAAO,SAAS,IAAI;EAEpE,AADA,EAAI,SAAS,IACb,EAAc,YAAY,CAAC,CAAC,OAAO,QAAQ,aAAa,MAAM,IAAI,EAAI,SAAS,CAAC;CAClF;CAEA,OAAc,kBAAkB,GAAqB;EACnD,IAAI;GACF,IAAM,IAAY,IAAI,IAAI,CAAG,GACvB,IAAU,EAAU,SAAS,MAAM,GAAG,CAAC,CAAC,OAAO,OAAO,CAAC,CAAC,IAAI;GAIlE,OAHI,IACK,mBAAmB,CAAO,IAE5B,GAAG,EAAU,SAAS;EAC/B,QAAQ;GACN,OAAO;EACT;CACF;CAEA,OAAc,iBAAiB,GAAqB;EAClD,IAAI;EACJ,IAAI;GACF,IAAY,IAAI,IAAI,EAAI,KAAK,CAAC;EAChC,QAAQ;GACN,MAAU,MAAM,0BAA0B;EAC5C;EACA,IAAI,EAAU,aAAa,WAAW,EAAU,aAAa,UAC3D,MAAU,MAAM,oCAAoC;EAEtD,OAAO,EAAU;CACnB;AACF"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rivm-loculus-tools/common-frontend",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.4",
|
|
4
4
|
"license": "EUPL-1.2",
|
|
5
|
+
"repository": {
|
|
6
|
+
"type": "git",
|
|
7
|
+
"url": "https://github.com/RIVM-bioinformatics/loculus-tools"
|
|
8
|
+
},
|
|
5
9
|
"type": "module",
|
|
6
10
|
"peerDependencies": {
|
|
7
11
|
"@emotion/cache": "*",
|
|
@@ -55,12 +59,10 @@
|
|
|
55
59
|
"vite-plugin-static-copy": "4.1.1",
|
|
56
60
|
"vite": "8.3.0"
|
|
57
61
|
},
|
|
58
|
-
"
|
|
62
|
+
"files": [
|
|
63
|
+
"dist"
|
|
64
|
+
],
|
|
59
65
|
"exports": {
|
|
60
|
-
".": {
|
|
61
|
-
"types": "./dist/index.d.ts",
|
|
62
|
-
"import": "./dist/index.js"
|
|
63
|
-
},
|
|
64
66
|
"./classes/services/FastaDataEventBusService": {
|
|
65
67
|
"types": "./dist/classes/services/FastaDataEventBusService/index.d.ts",
|
|
66
68
|
"import": "./dist/classes/services/FastaDataEventBusService/index.js"
|
|
@@ -155,5 +157,6 @@
|
|
|
155
157
|
"start": "vite",
|
|
156
158
|
"build": "vite build",
|
|
157
159
|
"preview": "vite preview"
|
|
158
|
-
}
|
|
160
|
+
},
|
|
161
|
+
"types": "./dist/index.d.ts"
|
|
159
162
|
}
|
package/CHANGELOG.md
DELETED
package/eslint.config.js
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import baseEslintConfig from '@gen-epix/eslint-config';
|
|
2
|
-
|
|
3
|
-
// Example of adding a custom rule
|
|
4
|
-
// /** @type {import('@typescript-eslint/utils/ts-eslint').FlatConfig.ConfigArray} */
|
|
5
|
-
// const rules = eslintConfig.find(c => c.files && c.files.includes('**/*.ts')).rules;
|
|
6
|
-
// rules['@stylistic/jsx-sort-props'] = ['error', {
|
|
7
|
-
// ignoreCase: true,
|
|
8
|
-
// callbacksLast: true,
|
|
9
|
-
// shorthandFirst: true,
|
|
10
|
-
// reservedFirst: true,
|
|
11
|
-
// noSortAlphabetically: true,
|
|
12
|
-
// multiline: 'ignore',
|
|
13
|
-
// }];
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
export default baseEslintConfig;
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
import { fileURLToPath } from 'url';
|
|
3
|
-
import {
|
|
4
|
-
dirname,
|
|
5
|
-
join,
|
|
6
|
-
} from 'path';
|
|
7
|
-
|
|
8
|
-
// eslint-disable-next-line import-x/dynamic-import-chunkname
|
|
9
|
-
await import(join(dirname(fileURLToPath(import.meta.url)), '../../../../scripts/update-exports.mjs'));
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
import { EventBusAbstract } from '@gen-epix/ui-core/classes/abstracts/EventBusAbstract';
|
|
2
|
-
import { HmrUtil } from '@gen-epix/ui-core/utils/HmrUtil';
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
export type Event = {
|
|
6
|
-
onCloseImportDialog: undefined;
|
|
7
|
-
onShowImportDialog: string | undefined;
|
|
8
|
-
};
|
|
9
|
-
|
|
10
|
-
export class FastaDataEventBusService extends EventBusAbstract<Event> {
|
|
11
|
-
private static __instance: FastaDataEventBusService;
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
private constructor() {
|
|
15
|
-
super();
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
public static getInstance(): FastaDataEventBusService {
|
|
19
|
-
FastaDataEventBusService.__instance = HmrUtil.getHmrSingleton('fastaDataEventBusService', FastaDataEventBusService.__instance, () => new FastaDataEventBusService());
|
|
20
|
-
return FastaDataEventBusService.__instance;
|
|
21
|
-
}
|
|
22
|
-
}
|