@genspectrum/dashboard-components 1.8.0 → 1.8.1
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/README.md +22 -2
- package/dist/assets/{mutationOverTimeWorker-DPS3tmOd.js.map → mutationOverTimeWorker-BRPqAM5Z.js.map} +1 -1
- package/dist/components.d.ts +10 -10
- package/dist/components.js +18 -12
- package/dist/components.js.map +1 -1
- package/dist/util.d.ts +10 -10
- package/package.json +1 -1
- package/src/preact/wastewater/mutationsOverTime/__mockData__/detailsAminAcidNonSegmented.json +88 -0
- package/src/preact/wastewater/mutationsOverTime/wastewater-mutations-over-time.stories.tsx +34 -0
- package/src/query/queryWastewaterMutationsOverTime.ts +1 -1
- package/src/utils/mutations.ts +18 -10
- package/standalone-bundle/assets/{mutationOverTimeWorker-Dp-A14AP.js.map → mutationOverTimeWorker-DtFX4Ihx.js.map} +1 -1
- package/standalone-bundle/dashboard-components.js +2009 -2008
- package/standalone-bundle/dashboard-components.js.map +1 -1
package/dist/util.d.ts
CHANGED
|
@@ -1069,7 +1069,7 @@ declare global {
|
|
|
1069
1069
|
|
|
1070
1070
|
declare global {
|
|
1071
1071
|
interface HTMLElementTagNameMap {
|
|
1072
|
-
'gs-
|
|
1072
|
+
'gs-statistics': StatisticsComponent;
|
|
1073
1073
|
}
|
|
1074
1074
|
}
|
|
1075
1075
|
|
|
@@ -1077,7 +1077,7 @@ declare global {
|
|
|
1077
1077
|
declare global {
|
|
1078
1078
|
namespace JSX {
|
|
1079
1079
|
interface IntrinsicElements {
|
|
1080
|
-
'gs-
|
|
1080
|
+
'gs-statistics': DetailedHTMLProps<HTMLAttributes<HTMLElement>, HTMLElement>;
|
|
1081
1081
|
}
|
|
1082
1082
|
}
|
|
1083
1083
|
}
|
|
@@ -1085,7 +1085,7 @@ declare global {
|
|
|
1085
1085
|
|
|
1086
1086
|
declare global {
|
|
1087
1087
|
interface HTMLElementTagNameMap {
|
|
1088
|
-
'gs-
|
|
1088
|
+
'gs-sequences-by-location': SequencesByLocationComponent;
|
|
1089
1089
|
}
|
|
1090
1090
|
}
|
|
1091
1091
|
|
|
@@ -1093,7 +1093,7 @@ declare global {
|
|
|
1093
1093
|
declare global {
|
|
1094
1094
|
namespace JSX {
|
|
1095
1095
|
interface IntrinsicElements {
|
|
1096
|
-
'gs-
|
|
1096
|
+
'gs-sequences-by-location': DetailedHTMLProps<HTMLAttributes<HTMLElement>, HTMLElement>;
|
|
1097
1097
|
}
|
|
1098
1098
|
}
|
|
1099
1099
|
}
|
|
@@ -1137,10 +1137,10 @@ declare global {
|
|
|
1137
1137
|
|
|
1138
1138
|
declare global {
|
|
1139
1139
|
interface HTMLElementTagNameMap {
|
|
1140
|
-
'gs-
|
|
1140
|
+
'gs-location-filter': LocationFilterComponent;
|
|
1141
1141
|
}
|
|
1142
1142
|
interface HTMLElementEventMap {
|
|
1143
|
-
[gsEventNames.
|
|
1143
|
+
[gsEventNames.locationChanged]: LocationChangedEvent;
|
|
1144
1144
|
}
|
|
1145
1145
|
}
|
|
1146
1146
|
|
|
@@ -1148,7 +1148,7 @@ declare global {
|
|
|
1148
1148
|
declare global {
|
|
1149
1149
|
namespace JSX {
|
|
1150
1150
|
interface IntrinsicElements {
|
|
1151
|
-
'gs-
|
|
1151
|
+
'gs-location-filter': DetailedHTMLProps<HTMLAttributes<HTMLElement>, HTMLElement>;
|
|
1152
1152
|
}
|
|
1153
1153
|
}
|
|
1154
1154
|
}
|
|
@@ -1156,10 +1156,10 @@ declare global {
|
|
|
1156
1156
|
|
|
1157
1157
|
declare global {
|
|
1158
1158
|
interface HTMLElementTagNameMap {
|
|
1159
|
-
'gs-
|
|
1159
|
+
'gs-text-filter': TextFilterComponent;
|
|
1160
1160
|
}
|
|
1161
1161
|
interface HTMLElementEventMap {
|
|
1162
|
-
[gsEventNames.
|
|
1162
|
+
[gsEventNames.textFilterChanged]: TextFilterChangedEvent;
|
|
1163
1163
|
}
|
|
1164
1164
|
}
|
|
1165
1165
|
|
|
@@ -1167,7 +1167,7 @@ declare global {
|
|
|
1167
1167
|
declare global {
|
|
1168
1168
|
namespace JSX {
|
|
1169
1169
|
interface IntrinsicElements {
|
|
1170
|
-
'gs-
|
|
1170
|
+
'gs-text-filter': DetailedHTMLProps<HTMLAttributes<HTMLElement>, HTMLElement>;
|
|
1171
1171
|
}
|
|
1172
1172
|
}
|
|
1173
1173
|
}
|
package/package.json
CHANGED
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
{
|
|
2
|
+
"data": [
|
|
3
|
+
{
|
|
4
|
+
"aminoAcidMutationFrequency": null,
|
|
5
|
+
"date": "2024-11-13",
|
|
6
|
+
"location": "Lugano",
|
|
7
|
+
"nucleotideMutationFrequency": "{\"A12183T\": null, \"C2554T\": null, \"C3422A\": 0.9598659873008728, \"A966C\": null, \"G6661A\": 0.5527499914169312, \"G7731A\": 0.9832900166511536, \"T4026G\": 0.9991809725761414, \"T5260C\": null, \"T5287C\": null}",
|
|
8
|
+
"reference": "RSV-B"
|
|
9
|
+
},
|
|
10
|
+
{
|
|
11
|
+
"aminoAcidMutationFrequency": null,
|
|
12
|
+
"date": "2024-11-17",
|
|
13
|
+
"location": "Genève",
|
|
14
|
+
"nucleotideMutationFrequency": "{\"A12183T\": 1.0, \"C2554T\": null, \"C3422A\": 0.0, \"A966C\": null, \"G6661A\": 0.8785049915313721, \"G7731A\": 0.9855599999427795, \"T4026G\": null, \"T5260C\": 1.0, \"T5287C\": 0.9932659864425659}",
|
|
15
|
+
"reference": "RSV-B"
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
"aminoAcidMutationFrequency": "{\"S4286C\": null, \"R346T\": 0.25, \"Q493E\": 0.60, \"G204P\": null}",
|
|
19
|
+
"date": "2024-11-17",
|
|
20
|
+
"location": "Lugano",
|
|
21
|
+
"nucleotideMutationFrequency": "{\"A12183T\": 0.998993992805481, \"C2554T\": null, \"C3422A\": null, \"A966C\": null, \"G6661A\": 0.8917459845542908, \"G7731A\": 0.9770470261573792, \"T4026G\": 0.0, \"T5260C\": null, \"T5287C\": null}",
|
|
22
|
+
"reference": "RSV-B"
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
"aminoAcidMutationFrequency": "{\"S4286C\": 0.42, \"R346T\": 0.22, \"Q493E\": 0.66, \"G204P\": null}",
|
|
26
|
+
"date": "2024-11-16",
|
|
27
|
+
"location": "Lugano",
|
|
28
|
+
"nucleotideMutationFrequency": "{\"A12183T\": null, \"C2554T\": null, \"C3422A\": null, \"A966C\": null, \"G6661A\": 0.9476320147514343, \"G7731A\": 0.9809200167655945, \"T4026G\": 0.9992259740829468, \"T5260C\": null, \"T5287C\": null}",
|
|
29
|
+
"reference": "RSV-B"
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
"aminoAcidMutationFrequency": null,
|
|
33
|
+
"date": "2024-11-18",
|
|
34
|
+
"location": "Genève",
|
|
35
|
+
"nucleotideMutationFrequency": "{\"A12183T\": null, \"C2554T\": 0.9978219866752625, \"C3422A\": null, \"A966C\": 1.0, \"G6661A\": null, \"G7731A\": null, \"T4026G\": null, \"T5260C\": null, \"T5287C\": null}",
|
|
36
|
+
"reference": "RSV-B"
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
"aminoAcidMutationFrequency": null,
|
|
40
|
+
"date": "2024-11-14",
|
|
41
|
+
"location": "Genève",
|
|
42
|
+
"nucleotideMutationFrequency": "{\"A12183T\": null, \"C2554T\": 0.9994590282440186, \"C3422A\": 0.05333299934864044, \"A966C\": 1.0, \"G6661A\": 0.9282640218734741, \"G7731A\": 0.9803630113601685, \"T4026G\": 0.0, \"T5260C\": 0.9970409870147705, \"T5287C\": 0.996694028377533}",
|
|
43
|
+
"reference": "RSV-B"
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
"aminoAcidMutationFrequency": null,
|
|
47
|
+
"date": "2024-11-13",
|
|
48
|
+
"location": "Laupen",
|
|
49
|
+
"nucleotideMutationFrequency": "{\"A12668G\": null, \"A3564G\": null, \"C10862T\": null, \"C12710T\": null, \"C3624T\": null, \"G11123A\": null, \"G3616A\": null, \"G7379A\": 0.9470750093460083, \"T11034A\": null, \"T3483C\": null}",
|
|
50
|
+
"reference": "RSV-A"
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
"aminoAcidMutationFrequency": null,
|
|
54
|
+
"date": "2024-11-13",
|
|
55
|
+
"location": "Zürich",
|
|
56
|
+
"nucleotideMutationFrequency": "{\"A12668G\": 0.9988809823989868, \"A3564G\": null, \"C10862T\": 1.0, \"C12710T\": 0.9991809725761414, \"C3624T\": null, \"G11123A\": 1.0, \"G3616A\": null, \"G7379A\": 0.9414680004119873, \"T11034A\": 0.9988250136375427, \"T3483C\": null}",
|
|
57
|
+
"reference": "RSV-A"
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
"aminoAcidMutationFrequency": null,
|
|
61
|
+
"date": "2024-11-16",
|
|
62
|
+
"location": "Zürich",
|
|
63
|
+
"nucleotideMutationFrequency": "{\"A12668G\": 0.999222993850708, \"A3564G\": 0.9998199939727783, \"C10862T\": 1.0, \"C12710T\": 0.9996299743652344, \"C3624T\": 0.9999099969863892, \"G11123A\": 1.0, \"G3616A\": 0.08799900114536285, \"G7379A\": null, \"T11034A\": 0.9970099925994873, \"T3483C\": 0.9993579983711243}",
|
|
64
|
+
"reference": "RSV-A"
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
"aminoAcidMutationFrequency": null,
|
|
68
|
+
"date": "2024-11-16",
|
|
69
|
+
"location": "Chur",
|
|
70
|
+
"nucleotideMutationFrequency": "{\"A12668G\": null, \"A3564G\": null, \"C10862T\": null, \"C12710T\": null, \"C3624T\": null, \"G11123A\": null, \"G3616A\": null, \"G7379A\": 0.6464089751243591, \"T11034A\": null, \"T3483C\": null}",
|
|
71
|
+
"reference": "RSV-A"
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
"aminoAcidMutationFrequency": null,
|
|
75
|
+
"date": "2024-11-18",
|
|
76
|
+
"location": "Basel",
|
|
77
|
+
"nucleotideMutationFrequency": "{\"A12668G\": null, \"A3564G\": 1.0, \"C10862T\": null, \"C12710T\": null, \"C3624T\": 1.0, \"G11123A\": null, \"G3616A\": 0.08222199976444244, \"G7379A\": null, \"T11034A\": null, \"T3483C\": 0.9998080134391785}",
|
|
78
|
+
"reference": "RSV-A"
|
|
79
|
+
}
|
|
80
|
+
],
|
|
81
|
+
"info": {
|
|
82
|
+
"dataVersion": "1737327031",
|
|
83
|
+
"requestId": "5591b455-3d84-438c-8434-2e57ee2ad569",
|
|
84
|
+
"requestInfo": "RSV on api.wise-loculus.genspectrum.org at 2025-01-20T11:58:03.498206810",
|
|
85
|
+
"reportTo": "Please report to https://github.com/GenSpectrum/LAPIS/issues in case you encounter any unexpected issues. Please include the request ID and the requestInfo in your report.",
|
|
86
|
+
"lapisVersion": "0.3.10"
|
|
87
|
+
}
|
|
88
|
+
}
|
|
@@ -8,6 +8,7 @@ import referenceGenome from '../../../lapisApi/__mockData__/referenceGenome.json
|
|
|
8
8
|
import { LapisUrlContextProvider } from '../../LapisUrlContext';
|
|
9
9
|
import { ReferenceGenomeContext } from '../../ReferenceGenomeContext';
|
|
10
10
|
import details from './__mockData__/details.json';
|
|
11
|
+
import detailsNonSegmented from './__mockData__/detailsAminAcidNonSegmented.json';
|
|
11
12
|
import type { MutationsOverTimeProps } from '../../mutationsOverTime/mutations-over-time';
|
|
12
13
|
import { playThatExpectsFinishedLoadingEvent } from '../../shared/stories/expectFinishedLoadingEvent';
|
|
13
14
|
|
|
@@ -113,6 +114,39 @@ export const AminoAcids: StoryObj<WastewaterMutationsOverTimeProps> = {
|
|
|
113
114
|
},
|
|
114
115
|
};
|
|
115
116
|
|
|
117
|
+
export const AminoAcidsNonSegmented: StoryObj<WastewaterMutationsOverTimeProps> = {
|
|
118
|
+
...Default,
|
|
119
|
+
args: {
|
|
120
|
+
...Default.args,
|
|
121
|
+
sequenceType: 'amino acid',
|
|
122
|
+
},
|
|
123
|
+
parameters: {
|
|
124
|
+
fetchMock: {
|
|
125
|
+
mocks: [
|
|
126
|
+
{
|
|
127
|
+
matcher: {
|
|
128
|
+
name: 'details',
|
|
129
|
+
url: WISE_DETAILS_ENDPOINT,
|
|
130
|
+
body: {
|
|
131
|
+
fields: ['date', 'location', 'nucleotideMutationFrequency', 'aminoAcidMutationFrequency'],
|
|
132
|
+
},
|
|
133
|
+
},
|
|
134
|
+
response: {
|
|
135
|
+
status: 200,
|
|
136
|
+
body: detailsNonSegmented,
|
|
137
|
+
},
|
|
138
|
+
},
|
|
139
|
+
],
|
|
140
|
+
},
|
|
141
|
+
},
|
|
142
|
+
play: async ({ canvas }) => {
|
|
143
|
+
await expectMutationOnPage(canvas, 'G204P');
|
|
144
|
+
await expectMutationOnPage(canvas, 'R346T');
|
|
145
|
+
await expectMutationOnPage(canvas, 'Q493E');
|
|
146
|
+
await expectMutationOnPage(canvas, 'S4286C');
|
|
147
|
+
},
|
|
148
|
+
};
|
|
149
|
+
|
|
116
150
|
export const UsesMutationFilter: StoryObj<MutationsOverTimeProps> = {
|
|
117
151
|
...Default,
|
|
118
152
|
play: async ({ canvas, step }) => {
|
|
@@ -57,7 +57,7 @@ function transformMutations(input: unknown): { mutation: Substitution; proportio
|
|
|
57
57
|
}
|
|
58
58
|
|
|
59
59
|
return Object.entries(mutationFrequency.data).map(([key, value]) => {
|
|
60
|
-
const mutation = SubstitutionClass.parse(key);
|
|
60
|
+
const mutation = SubstitutionClass.parse(key, true);
|
|
61
61
|
if (mutation === null) {
|
|
62
62
|
throw new Error(`Failed to parse mutation: "${key}"`);
|
|
63
63
|
}
|
package/src/utils/mutations.ts
CHANGED
|
@@ -17,15 +17,19 @@ export interface MutationClass extends Mutation {
|
|
|
17
17
|
const nucleotideChars = 'ACGTRYKMSWBDHVN';
|
|
18
18
|
const aminoAcidChars = 'ACDEFGHIKLMNPQRSTVWY';
|
|
19
19
|
|
|
20
|
-
function segmentPart(
|
|
21
|
-
|
|
20
|
+
function segmentPart(isOptional: boolean) {
|
|
21
|
+
const segmentPart = `(?<segment>[A-Z0-9_-]+):`;
|
|
22
|
+
if (isOptional) {
|
|
23
|
+
return `(${segmentPart})?`;
|
|
24
|
+
}
|
|
25
|
+
return segmentPart;
|
|
22
26
|
}
|
|
23
27
|
|
|
24
|
-
function buildSubstitutionRegex(type: 'nucleotide' | 'aminoAcid') {
|
|
28
|
+
function buildSubstitutionRegex(type: 'nucleotide' | 'aminoAcid', segmentPartIsOptional: boolean) {
|
|
25
29
|
const chars = type === 'nucleotide' ? nucleotideChars : aminoAcidChars;
|
|
26
30
|
|
|
27
31
|
return new RegExp(
|
|
28
|
-
`^${segmentPart(
|
|
32
|
+
`^${segmentPart(segmentPartIsOptional)}` +
|
|
29
33
|
`(?<valueAtReference>[${chars}*])?` +
|
|
30
34
|
`(?<position>\\d+)` +
|
|
31
35
|
`(?<substitutionValue>[${chars}.*])?$`,
|
|
@@ -33,8 +37,9 @@ function buildSubstitutionRegex(type: 'nucleotide' | 'aminoAcid') {
|
|
|
33
37
|
);
|
|
34
38
|
}
|
|
35
39
|
|
|
36
|
-
const nucleotideSubstitutionRegex = buildSubstitutionRegex('nucleotide');
|
|
37
|
-
const aminoAcidSubstitutionRegex = buildSubstitutionRegex('aminoAcid');
|
|
40
|
+
const nucleotideSubstitutionRegex = buildSubstitutionRegex('nucleotide', true);
|
|
41
|
+
const aminoAcidSubstitutionRegex = buildSubstitutionRegex('aminoAcid', false);
|
|
42
|
+
const aminoAcidSubstitutionWithoutSegmentRegex = buildSubstitutionRegex('aminoAcid', true);
|
|
38
43
|
|
|
39
44
|
export interface Substitution extends Mutation {
|
|
40
45
|
type: 'substitution';
|
|
@@ -74,10 +79,13 @@ export class SubstitutionClass implements MutationClass, Substitution {
|
|
|
74
79
|
return this.code;
|
|
75
80
|
}
|
|
76
81
|
|
|
77
|
-
static parse(mutationStr: string): SubstitutionClass | null {
|
|
82
|
+
static parse(mutationStr: string, segmentIsOptional: boolean = false): SubstitutionClass | null {
|
|
78
83
|
const matchNucleotide = nucleotideSubstitutionRegex.exec(mutationStr);
|
|
79
84
|
const matchAminoAcid = aminoAcidSubstitutionRegex.exec(mutationStr);
|
|
80
|
-
const
|
|
85
|
+
const matchAminAcidWithoutSegment = segmentIsOptional
|
|
86
|
+
? aminoAcidSubstitutionWithoutSegmentRegex.exec(mutationStr)
|
|
87
|
+
: undefined;
|
|
88
|
+
const match = matchNucleotide ?? matchAminoAcid ?? matchAminAcidWithoutSegment;
|
|
81
89
|
if (match?.groups === undefined) {
|
|
82
90
|
return null;
|
|
83
91
|
}
|
|
@@ -94,7 +102,7 @@ function buildDeletionRegex(type: 'nucleotide' | 'aminoAcid') {
|
|
|
94
102
|
const chars = type === 'nucleotide' ? nucleotideChars : aminoAcidChars;
|
|
95
103
|
|
|
96
104
|
return new RegExp(
|
|
97
|
-
`^${segmentPart(type)}` + `(?<valueAtReference>[${chars}*])?` + `(?<position>\\d+)` + `(-)$`,
|
|
105
|
+
`^${segmentPart(type === 'nucleotide')}` + `(?<valueAtReference>[${chars}*])?` + `(?<position>\\d+)` + `(-)$`,
|
|
98
106
|
'i',
|
|
99
107
|
);
|
|
100
108
|
}
|
|
@@ -158,7 +166,7 @@ function buildInsertionRegex(type: 'nucleotide' | 'aminoAcid') {
|
|
|
158
166
|
const wildcardToken = `(?:\\.\\*)`;
|
|
159
167
|
|
|
160
168
|
return new RegExp(
|
|
161
|
-
`^ins_${segmentPart(type)}(?<position>\\d+):(?<insertedSymbols>(?:[${chars}?*]|${wildcardToken})+)$`,
|
|
169
|
+
`^ins_${segmentPart(type === 'nucleotide')}(?<position>\\d+):(?<insertedSymbols>(?:[${chars}?*]|${wildcardToken})+)$`,
|
|
162
170
|
'i',
|
|
163
171
|
);
|
|
164
172
|
}
|