@genspectrum/dashboard-components 0.6.18 → 0.7.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 (118) hide show
  1. package/README.md +5 -12
  2. package/custom-elements.json +22 -22
  3. package/dist/assets/mutationOverTimeWorker-BOCXtKzd.js.map +1 -0
  4. package/dist/dashboard-components.js +301 -302
  5. package/dist/dashboard-components.js.map +1 -1
  6. package/dist/genspectrum-components.d.ts +60 -10
  7. package/dist/style.css +3 -2
  8. package/package.json +13 -4
  9. package/src/index.ts +1 -0
  10. package/src/operator/FetchInsertionsOperator.ts +2 -2
  11. package/src/operator/FetchSubstitutionsOrDeletionsOperator.ts +3 -3
  12. package/src/preact/dateRangeSelector/computeInitialValues.spec.ts +53 -38
  13. package/src/preact/dateRangeSelector/computeInitialValues.ts +17 -23
  14. package/src/preact/dateRangeSelector/date-range-selector.stories.tsx +46 -32
  15. package/src/preact/dateRangeSelector/date-range-selector.tsx +24 -26
  16. package/src/preact/dateRangeSelector/dateRangeOption.ts +65 -0
  17. package/src/preact/dateRangeSelector/selectableOptions.ts +17 -66
  18. package/src/preact/mutationComparison/fetchMutationData.spec.ts +3 -3
  19. package/src/preact/mutationComparison/getMutationComparisonTableData.spec.ts +11 -11
  20. package/src/preact/mutationComparison/getMutationComparisonTableData.ts +4 -4
  21. package/src/preact/mutationComparison/mutation-comparison-table.tsx +2 -2
  22. package/src/preact/mutationFilter/mutation-filter.tsx +27 -18
  23. package/src/preact/mutationFilter/parseAndValidateMutation.ts +4 -4
  24. package/src/preact/mutationFilter/parseMutation.spec.ts +17 -17
  25. package/src/preact/mutations/getInsertionsTableData.spec.ts +3 -3
  26. package/src/preact/mutations/getMutationsGridData.spec.ts +9 -9
  27. package/src/preact/mutations/getMutationsTableData.spec.ts +7 -7
  28. package/src/preact/mutations/mutations-insertions-table.tsx +3 -3
  29. package/src/preact/mutations/mutations-table.tsx +3 -3
  30. package/src/preact/mutationsOverTime/MutationOverTimeData.ts +20 -0
  31. package/src/preact/mutationsOverTime/__mockData__/aminoAcidMutationsByDay.ts +45686 -0
  32. package/src/preact/mutationsOverTime/__mockData__/byWeek.ts +58989 -0
  33. package/src/preact/mutationsOverTime/__mockData__/defaultMockData.ts +103991 -0
  34. package/src/preact/mutationsOverTime/__mockData__/mockConversion.ts +54 -0
  35. package/src/preact/mutationsOverTime/__mockData__/showsMessageWhenTooManyMutations.ts +63690 -0
  36. package/src/preact/mutationsOverTime/getFilteredMutationsOverTime.spec.ts +177 -161
  37. package/src/preact/mutationsOverTime/getFilteredMutationsOverTimeData.ts +17 -59
  38. package/src/preact/mutationsOverTime/mutationOverTimeWorker.mock.ts +27 -0
  39. package/src/preact/mutationsOverTime/mutationOverTimeWorker.ts +29 -0
  40. package/src/preact/mutationsOverTime/mutations-over-time-grid.tsx +13 -14
  41. package/src/preact/mutationsOverTime/mutations-over-time.stories.tsx +9 -334
  42. package/src/preact/mutationsOverTime/mutations-over-time.tsx +59 -54
  43. package/src/preact/numberSequencesOverTime/getNumberOfSequencesOverTimeTableData.ts +3 -3
  44. package/src/preact/prevalenceOverTime/getPrevalenceOverTimeTableData.spec.ts +5 -5
  45. package/src/preact/prevalenceOverTime/prevalence-over-time-bubble-chart.tsx +1 -1
  46. package/src/preact/relativeGrowthAdvantage/relative-growth-advantage-chart.tsx +2 -2
  47. package/src/preact/shared/sort/sortInsertions.spec.ts +11 -11
  48. package/src/preact/shared/sort/sortInsertions.ts +2 -2
  49. package/src/preact/shared/sort/sortSubstitutionsAndDeletions.spec.ts +13 -13
  50. package/src/preact/shared/sort/sortSubstitutionsAndDeletions.ts +7 -4
  51. package/src/preact/webWorkers/useWebWorker.ts +51 -0
  52. package/src/preact/webWorkers/workerFunction.ts +14 -0
  53. package/src/query/queryAggregatedDataOverTime.ts +3 -3
  54. package/src/query/queryMutationsOverTime.spec.ts +272 -51
  55. package/src/query/queryMutationsOverTime.ts +114 -47
  56. package/src/query/queryPrevalenceOverTime.ts +2 -2
  57. package/src/query/queryRelativeGrowthAdvantage.ts +3 -3
  58. package/src/types.ts +25 -5
  59. package/src/utils/map2d.spec.ts +79 -12
  60. package/src/utils/map2d.ts +25 -5
  61. package/src/utils/mutations.spec.ts +20 -20
  62. package/src/utils/mutations.ts +80 -17
  63. package/src/utils/sort.ts +5 -2
  64. package/src/utils/temporal.spec.ts +27 -24
  65. package/src/utils/{temporal.ts → temporalClass.ts} +170 -72
  66. package/src/utils/temporalTestHelpers.ts +3 -3
  67. package/src/web-components/input/gs-date-range-selector.stories.ts +16 -28
  68. package/src/web-components/input/gs-date-range-selector.tsx +17 -32
  69. package/src/web-components/introduction.mdx +46 -0
  70. package/src/web-components/visualization/gs-mutations-over-time.stories.ts +6 -699
  71. package/src/web-components/visualization/gs-mutations-over-time.tsx +2 -2
  72. package/standalone-bundle/dashboard-components.js +12011 -12778
  73. package/standalone-bundle/dashboard-components.js.map +1 -1
  74. package/src/preact/mutationsOverTime/__mockData__/aggregated_2024_01.json +0 -13
  75. package/src/preact/mutationsOverTime/__mockData__/aggregated_2024_02.json +0 -13
  76. package/src/preact/mutationsOverTime/__mockData__/aggregated_2024_03.json +0 -13
  77. package/src/preact/mutationsOverTime/__mockData__/aggregated_2024_04.json +0 -13
  78. package/src/preact/mutationsOverTime/__mockData__/aggregated_2024_05.json +0 -13
  79. package/src/preact/mutationsOverTime/__mockData__/aggregated_2024_06.json +0 -13
  80. package/src/preact/mutationsOverTime/__mockData__/aggregated_2024_07.json +0 -13
  81. package/src/preact/mutationsOverTime/__mockData__/aggregated_20_01_2024.json +0 -13
  82. package/src/preact/mutationsOverTime/__mockData__/aggregated_21_01_2024.json +0 -13
  83. package/src/preact/mutationsOverTime/__mockData__/aggregated_22_01_2024.json +0 -13
  84. package/src/preact/mutationsOverTime/__mockData__/aggregated_23_01_2024.json +0 -13
  85. package/src/preact/mutationsOverTime/__mockData__/aggregated_24_01_2024.json +0 -13
  86. package/src/preact/mutationsOverTime/__mockData__/aggregated_25_01_2024.json +0 -13
  87. package/src/preact/mutationsOverTime/__mockData__/aggregated_26_01_2024.json +0 -13
  88. package/src/preact/mutationsOverTime/__mockData__/aggregated_byDay.json +0 -38
  89. package/src/preact/mutationsOverTime/__mockData__/aggregated_byWeek.json +0 -122
  90. package/src/preact/mutationsOverTime/__mockData__/aggregated_date.json +0 -642
  91. package/src/preact/mutationsOverTime/__mockData__/aggregated_tooManyMutations.json +0 -1470
  92. package/src/preact/mutationsOverTime/__mockData__/aggregated_tooManyMutations_total.json +0 -13
  93. package/src/preact/mutationsOverTime/__mockData__/aggregated_week3_2024.json +0 -13
  94. package/src/preact/mutationsOverTime/__mockData__/aggregated_week4_2024.json +0 -13
  95. package/src/preact/mutationsOverTime/__mockData__/aggregated_week5_2024.json +0 -13
  96. package/src/preact/mutationsOverTime/__mockData__/aggregated_week6_2024.json +0 -13
  97. package/src/preact/mutationsOverTime/__mockData__/aminoAcidMutations_20_01_2024.json +0 -6778
  98. package/src/preact/mutationsOverTime/__mockData__/aminoAcidMutations_21_01_2024.json +0 -7129
  99. package/src/preact/mutationsOverTime/__mockData__/aminoAcidMutations_22_01_2024.json +0 -4681
  100. package/src/preact/mutationsOverTime/__mockData__/aminoAcidMutations_23_01_2024.json +0 -10738
  101. package/src/preact/mutationsOverTime/__mockData__/aminoAcidMutations_24_01_2024.json +0 -11710
  102. package/src/preact/mutationsOverTime/__mockData__/aminoAcidMutations_25_01_2024.json +0 -11557
  103. package/src/preact/mutationsOverTime/__mockData__/aminoAcidMutations_26_01_2024.json +0 -8596
  104. package/src/preact/mutationsOverTime/__mockData__/aminoAcidMutations_byDayOverall.json +0 -4726
  105. package/src/preact/mutationsOverTime/__mockData__/nucleotideMutations_2024_01.json +0 -1747
  106. package/src/preact/mutationsOverTime/__mockData__/nucleotideMutations_2024_02.json +0 -1774
  107. package/src/preact/mutationsOverTime/__mockData__/nucleotideMutations_2024_03.json +0 -1819
  108. package/src/preact/mutationsOverTime/__mockData__/nucleotideMutations_2024_04.json +0 -1864
  109. package/src/preact/mutationsOverTime/__mockData__/nucleotideMutations_2024_05.json +0 -1927
  110. package/src/preact/mutationsOverTime/__mockData__/nucleotideMutations_2024_06.json +0 -1864
  111. package/src/preact/mutationsOverTime/__mockData__/nucleotideMutations_2024_07.json +0 -9
  112. package/src/preact/mutationsOverTime/__mockData__/nucleotideMutations_byMonthOverall.json +0 -11143
  113. package/src/preact/mutationsOverTime/__mockData__/nucleotideMutations_byWeekOverall.json +0 -9154
  114. package/src/preact/mutationsOverTime/__mockData__/nucleotideMutations_tooManyMutations.json +0 -16453
  115. package/src/preact/mutationsOverTime/__mockData__/nucleotideMutations_week3_2024.json +0 -8812
  116. package/src/preact/mutationsOverTime/__mockData__/nucleotideMutations_week4_2024.json +0 -9730
  117. package/src/preact/mutationsOverTime/__mockData__/nucleotideMutations_week5_2024.json +0 -9865
  118. package/src/preact/mutationsOverTime/__mockData__/nucleotideMutations_week6_2024.json +0 -11314
@@ -1,20 +1,20 @@
1
1
  import { describe, expect, test } from 'vitest';
2
2
 
3
3
  import { sortInsertions } from './sortInsertions';
4
- import { Insertion } from '../../../utils/mutations';
4
+ import { InsertionClass } from '../../../utils/mutations';
5
5
 
6
6
  describe('sortInsertions with no segments', () => {
7
7
  test('should sort for positions first', () => {
8
- const a = new Insertion(undefined, 1, 'A');
9
- const b = new Insertion(undefined, 2, 'A');
8
+ const a = new InsertionClass(undefined, 1, 'A');
9
+ const b = new InsertionClass(undefined, 2, 'A');
10
10
 
11
11
  expect(sortInsertions(a, b)).toBeLessThan(0);
12
12
  expect(sortInsertions(b, a)).toBeGreaterThan(0);
13
13
  });
14
14
 
15
15
  test('should sort for symbols second', () => {
16
- const a = new Insertion(undefined, 1, 'A');
17
- const b = new Insertion(undefined, 1, 'B');
16
+ const a = new InsertionClass(undefined, 1, 'A');
17
+ const b = new InsertionClass(undefined, 1, 'B');
18
18
 
19
19
  expect(sortInsertions(a, b)).toBeLessThan(0);
20
20
  expect(sortInsertions(b, a)).toBeGreaterThan(0);
@@ -23,24 +23,24 @@ describe('sortInsertions with no segments', () => {
23
23
 
24
24
  describe('sortInsertions with segments', () => {
25
25
  test('should sort for segments first', () => {
26
- const a = new Insertion('AA1', 1, 'A');
27
- const b = new Insertion('BB1', 1, 'A');
26
+ const a = new InsertionClass('AA1', 1, 'A');
27
+ const b = new InsertionClass('BB1', 1, 'A');
28
28
 
29
29
  expect(sortInsertions(a, b)).toBeLessThan(0);
30
30
  expect(sortInsertions(b, a)).toBeGreaterThan(0);
31
31
  });
32
32
 
33
33
  test('should sort for positions second', () => {
34
- const a = new Insertion('AA1', 1, 'A');
35
- const b = new Insertion('AA1', 2, 'A');
34
+ const a = new InsertionClass('AA1', 1, 'A');
35
+ const b = new InsertionClass('AA1', 2, 'A');
36
36
 
37
37
  expect(sortInsertions(a, b)).toBeLessThan(0);
38
38
  expect(sortInsertions(b, a)).toBeGreaterThan(0);
39
39
  });
40
40
 
41
41
  test('should sort for symbols third', () => {
42
- const a = new Insertion('AA1', 1, 'A');
43
- const b = new Insertion('AA1', 1, 'B');
42
+ const a = new InsertionClass('AA1', 1, 'A');
43
+ const b = new InsertionClass('AA1', 1, 'B');
44
44
 
45
45
  expect(sortInsertions(a, b)).toBeLessThan(0);
46
46
  expect(sortInsertions(b, a)).toBeGreaterThan(0);
@@ -1,7 +1,7 @@
1
1
  import { comparePositions, compareSegments } from './sortSubstitutionsAndDeletions';
2
- import { type Insertion } from '../../../utils/mutations';
2
+ import { type InsertionClass } from '../../../utils/mutations';
3
3
 
4
- export const sortInsertions = (a: Insertion, b: Insertion) => {
4
+ export const sortInsertions = (a: InsertionClass, b: InsertionClass) => {
5
5
  if (a.segment !== b.segment) {
6
6
  return compareSegments(a.segment, b.segment);
7
7
  }
@@ -1,28 +1,28 @@
1
1
  import { describe, expect, test } from 'vitest';
2
2
 
3
3
  import { sortSubstitutionsAndDeletions } from './sortSubstitutionsAndDeletions';
4
- import { Deletion, Substitution } from '../../../utils/mutations';
4
+ import { DeletionClass, SubstitutionClass } from '../../../utils/mutations';
5
5
 
6
6
  describe('sortSubstitutionsAndDeletions with no segments', () => {
7
7
  test('should sort for positions first', () => {
8
- const a = new Substitution(undefined, 'A', 'B', 123);
9
- const b = new Substitution(undefined, 'A', 'B', 234);
8
+ const a = new SubstitutionClass(undefined, 'A', 'B', 123);
9
+ const b = new SubstitutionClass(undefined, 'A', 'B', 234);
10
10
 
11
11
  expect(sortSubstitutionsAndDeletions(a, b)).toBeLessThan(0);
12
12
  expect(sortSubstitutionsAndDeletions(b, a)).toBeGreaterThan(0);
13
13
  });
14
14
 
15
15
  test('should sort for substitutionValue second', () => {
16
- const a = new Substitution(undefined, 'A', 'A', 123);
17
- const b = new Substitution(undefined, 'A', 'B', 123);
16
+ const a = new SubstitutionClass(undefined, 'A', 'A', 123);
17
+ const b = new SubstitutionClass(undefined, 'A', 'B', 123);
18
18
 
19
19
  expect(sortSubstitutionsAndDeletions(a, b)).toBeLessThan(0);
20
20
  expect(sortSubstitutionsAndDeletions(b, a)).toBeGreaterThan(0);
21
21
  });
22
22
 
23
23
  test('should sort for substitutionValue over deletion', () => {
24
- const a = new Substitution(undefined, 'A', 'A', 123);
25
- const b = new Deletion(undefined, 'A', 123);
24
+ const a = new SubstitutionClass(undefined, 'A', 'A', 123);
25
+ const b = new DeletionClass(undefined, 'A', 123);
26
26
 
27
27
  expect(sortSubstitutionsAndDeletions(a, b)).toBeLessThan(0);
28
28
  expect(sortSubstitutionsAndDeletions(b, a)).toBeGreaterThan(0);
@@ -31,24 +31,24 @@ describe('sortSubstitutionsAndDeletions with no segments', () => {
31
31
 
32
32
  describe('sortSubstitutionsAndDeletions with segments', () => {
33
33
  test('should sort for segment first', () => {
34
- const a = new Substitution('AA1', 'A', 'B', 123);
35
- const b = new Substitution('BB1', 'A', 'B', 123);
34
+ const a = new SubstitutionClass('AA1', 'A', 'B', 123);
35
+ const b = new SubstitutionClass('BB1', 'A', 'B', 123);
36
36
 
37
37
  expect(sortSubstitutionsAndDeletions(a, b)).toBeLessThan(0);
38
38
  expect(sortSubstitutionsAndDeletions(b, a)).toBeGreaterThan(0);
39
39
  });
40
40
 
41
41
  test('should sort for position second', () => {
42
- const a = new Substitution('AA1', 'A', 'B', 123);
43
- const b = new Substitution('AA1', 'A', 'B', 234);
42
+ const a = new SubstitutionClass('AA1', 'A', 'B', 123);
43
+ const b = new SubstitutionClass('AA1', 'A', 'B', 234);
44
44
 
45
45
  expect(sortSubstitutionsAndDeletions(a, b)).toBeLessThan(0);
46
46
  expect(sortSubstitutionsAndDeletions(b, a)).toBeGreaterThan(0);
47
47
  });
48
48
 
49
49
  test('should sort for substitutionValue third', () => {
50
- const a = new Substitution('AA1', 'A', 'A', 123);
51
- const b = new Substitution('AA1', 'A', 'B', 123);
50
+ const a = new SubstitutionClass('AA1', 'A', 'A', 123);
51
+ const b = new SubstitutionClass('AA1', 'A', 'B', 123);
52
52
 
53
53
  expect(sortSubstitutionsAndDeletions(a, b)).toBeLessThan(0);
54
54
  expect(sortSubstitutionsAndDeletions(b, a)).toBeGreaterThan(0);
@@ -1,6 +1,9 @@
1
- import { Deletion, type Substitution } from '../../../utils/mutations';
1
+ import { DeletionClass, type SubstitutionClass } from '../../../utils/mutations';
2
2
 
3
- export const sortSubstitutionsAndDeletions = (a: Substitution | Deletion, b: Substitution | Deletion) => {
3
+ export const sortSubstitutionsAndDeletions = (
4
+ a: SubstitutionClass | DeletionClass,
5
+ b: SubstitutionClass | DeletionClass,
6
+ ) => {
4
7
  if (a.segment !== b.segment) {
5
8
  return compareSegments(a.segment, b.segment);
6
9
  }
@@ -9,8 +12,8 @@ export const sortSubstitutionsAndDeletions = (a: Substitution | Deletion, b: Sub
9
12
  return comparePositions(a.position, b.position);
10
13
  }
11
14
 
12
- const aIsDeletion = a instanceof Deletion;
13
- const bIsDeletion = b instanceof Deletion;
15
+ const aIsDeletion = a instanceof DeletionClass;
16
+ const bIsDeletion = b instanceof DeletionClass;
14
17
 
15
18
  if (aIsDeletion !== bIsDeletion) {
16
19
  return aIsDeletion ? 1 : -1;
@@ -0,0 +1,51 @@
1
+ import { useEffect, useMemo, useState } from 'preact/hooks';
2
+
3
+ export function useWebWorker<Request, Response>(messageToWorker: Request, worker: Worker) {
4
+ const [data, setData] = useState<Response | undefined>(undefined);
5
+ const [error, setError] = useState<Error | undefined>(undefined);
6
+ const [isLoading, setIsLoading] = useState(true);
7
+
8
+ useEffect(() => {
9
+ worker.onmessage = (
10
+ event: MessageEvent<{
11
+ status: 'loading' | 'success' | 'error';
12
+ data?: Response;
13
+ error?: Error;
14
+ }>,
15
+ ) => {
16
+ const { status, data, error } = event.data;
17
+
18
+ switch (status) {
19
+ case 'loading':
20
+ setIsLoading(true);
21
+ break;
22
+ case 'success':
23
+ setData(data);
24
+ setError(undefined);
25
+ setIsLoading(false);
26
+ break;
27
+ case 'error':
28
+ setError(error);
29
+ setIsLoading(false);
30
+ break;
31
+ default:
32
+ throw new Error(`Unknown status: ${status}`);
33
+ }
34
+ };
35
+
36
+ worker.onmessageerror = (event: MessageEvent) => {
37
+ setError(new Error(`Worker received a message that it cannot deserialize: ${event.data}`));
38
+ setIsLoading(false);
39
+ };
40
+
41
+ return () => {
42
+ worker.terminate();
43
+ };
44
+ }, []);
45
+
46
+ useMemo(() => {
47
+ worker.postMessage(messageToWorker);
48
+ }, [messageToWorker]);
49
+
50
+ return { data, error, isLoading };
51
+ }
@@ -0,0 +1,14 @@
1
+ export async function workerFunction<R>(queryFunction: () => R) {
2
+ try {
3
+ postMessage({ status: 'loading' });
4
+
5
+ const workerResponse = await queryFunction();
6
+
7
+ postMessage({
8
+ status: 'success',
9
+ data: workerResponse,
10
+ });
11
+ } catch (error) {
12
+ postMessage({ status: 'error', error });
13
+ }
14
+ }
@@ -11,8 +11,8 @@ import {
11
11
  generateAllInRange,
12
12
  getMinMaxTemporal,
13
13
  parseDateStringToTemporal,
14
- type Temporal,
15
- } from '../utils/temporal';
14
+ type TemporalClass,
15
+ } from '../utils/temporalClass';
16
16
 
17
17
  export function queryAggregatedDataOverTime<LapisDateField extends string>(
18
18
  filter: LapisFilter,
@@ -46,7 +46,7 @@ export function mapDateToGranularityRange(
46
46
  };
47
47
  }
48
48
 
49
- function averageSmoothing(slidingWindow: { dateRange: Temporal | null; count: number }[]) {
49
+ function averageSmoothing(slidingWindow: { dateRange: TemporalClass | null; count: number }[]) {
50
50
  const average = slidingWindow.reduce((acc, curr) => acc + curr.count, 0) / slidingWindow.length;
51
51
  const centerIndex = Math.floor(slidingWindow.length / 2);
52
52
  return { dateRange: slidingWindow[centerIndex].dateRange, count: average };