jbrowse-plugin-mafviewer 1.4.5 → 1.4.6
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/BigMafAdapter/BigMafAdapter.js +4 -5
- package/dist/BigMafAdapter/BigMafAdapter.js.map +1 -1
- package/dist/BigMafAdapter/configSchema.d.ts +2 -2
- package/dist/LinearMafDisplay/components/LinearMafDisplayComponent.js +38 -108
- package/dist/LinearMafDisplay/components/LinearMafDisplayComponent.js.map +1 -1
- package/dist/LinearMafDisplay/components/MAFTooltip.d.ts +0 -3
- package/dist/LinearMafDisplay/components/MAFTooltip.js.map +1 -1
- package/dist/LinearMafDisplay/components/MsaHighlightOverlay.d.ts +9 -0
- package/dist/LinearMafDisplay/components/MsaHighlightOverlay.js +34 -0
- package/dist/LinearMafDisplay/components/MsaHighlightOverlay.js.map +1 -0
- package/dist/LinearMafDisplay/components/Sidebar/SvgWrapper.js +1 -1
- package/dist/LinearMafDisplay/components/Sidebar/SvgWrapper.js.map +1 -1
- package/dist/LinearMafDisplay/components/useDragSelection.d.ts +25 -0
- package/dist/LinearMafDisplay/components/useDragSelection.js +103 -0
- package/dist/LinearMafDisplay/components/useDragSelection.js.map +1 -0
- package/dist/LinearMafDisplay/configSchema.d.ts +3 -30
- package/dist/LinearMafDisplay/stateModel.d.ts +1043 -121
- package/dist/LinearMafDisplay/stateModel.js +85 -41
- package/dist/LinearMafDisplay/stateModel.js.map +1 -1
- package/dist/LinearMafDisplay/types.d.ts +2 -2
- package/dist/LinearMafDisplay/util.d.ts +5 -0
- package/dist/LinearMafDisplay/util.js +25 -4
- package/dist/LinearMafDisplay/util.js.map +1 -1
- package/dist/LinearMafRenderer/LinearMafRenderer.d.ts +41 -5
- package/dist/LinearMafRenderer/LinearMafRenderer.js +1 -1
- package/dist/LinearMafRenderer/LinearMafRenderer.js.map +1 -1
- package/dist/LinearMafRenderer/components/LinearMafRendering.d.ts +14 -5
- package/dist/LinearMafRenderer/components/LinearMafRendering.js +21 -19
- package/dist/LinearMafRenderer/components/LinearMafRendering.js.map +1 -1
- package/dist/LinearMafRenderer/configSchema.d.ts +1 -6
- package/dist/LinearMafRenderer/configSchema.js +1 -6
- package/dist/LinearMafRenderer/configSchema.js.map +1 -1
- package/dist/LinearMafRenderer/rendering/insertions.d.ts +1 -1
- package/dist/LinearMafRenderer/rendering/insertions.js +2 -2
- package/dist/LinearMafRenderer/rendering/mismatches.d.ts +1 -1
- package/dist/LinearMafRenderer/rendering/mismatches.js +3 -3
- package/dist/LinearMafRenderer/rendering/types.d.ts +1 -1
- package/dist/MafAddTrackWorkflow/AddTrackWorkflow.js +1 -1
- package/dist/MafAddTrackWorkflow/AddTrackWorkflow.js.map +1 -1
- package/dist/MafAddTrackWorkflow/index.js +1 -1
- package/dist/MafAddTrackWorkflow/index.js.map +1 -1
- package/dist/MafGetSequences/MafGetSequences.d.ts +1 -0
- package/dist/MafGetSequences/MafGetSequences.js +2 -1
- package/dist/MafGetSequences/MafGetSequences.js.map +1 -1
- package/dist/MafSequenceWidget/LabelsCanvas.d.ts +8 -0
- package/dist/MafSequenceWidget/LabelsCanvas.js +37 -0
- package/dist/MafSequenceWidget/LabelsCanvas.js.map +1 -0
- package/dist/MafSequenceWidget/MafSequenceHoverHighlight.d.ts +6 -0
- package/dist/MafSequenceWidget/MafSequenceHoverHighlight.js +52 -0
- package/dist/MafSequenceWidget/MafSequenceHoverHighlight.js.map +1 -0
- package/dist/MafSequenceWidget/MafSequenceHoverHighlightExtension.d.ts +2 -0
- package/dist/MafSequenceWidget/MafSequenceHoverHighlightExtension.js +12 -0
- package/dist/MafSequenceWidget/MafSequenceHoverHighlightExtension.js.map +1 -0
- package/dist/MafSequenceWidget/MafSequenceWidget.d.ts +6 -0
- package/dist/MafSequenceWidget/MafSequenceWidget.js +189 -0
- package/dist/MafSequenceWidget/MafSequenceWidget.js.map +1 -0
- package/dist/MafSequenceWidget/SequenceCanvas.d.ts +12 -0
- package/dist/MafSequenceWidget/SequenceCanvas.js +86 -0
- package/dist/MafSequenceWidget/SequenceCanvas.js.map +1 -0
- package/dist/MafSequenceWidget/SequenceDisplay.d.ts +12 -0
- package/dist/MafSequenceWidget/SequenceDisplay.js +117 -0
- package/dist/MafSequenceWidget/SequenceDisplay.js.map +1 -0
- package/dist/MafSequenceWidget/SequenceTooltip.d.ts +11 -0
- package/dist/MafSequenceWidget/SequenceTooltip.js +39 -0
- package/dist/MafSequenceWidget/SequenceTooltip.js.map +1 -0
- package/dist/MafSequenceWidget/baseColors.d.ts +3 -0
- package/dist/MafSequenceWidget/baseColors.js +64 -0
- package/dist/MafSequenceWidget/baseColors.js.map +1 -0
- package/dist/MafSequenceWidget/colToGenomePos.d.ts +13 -0
- package/dist/MafSequenceWidget/colToGenomePos.js +32 -0
- package/dist/MafSequenceWidget/colToGenomePos.js.map +1 -0
- package/dist/MafSequenceWidget/colToGenomePos.test.d.ts +1 -0
- package/dist/MafSequenceWidget/colToGenomePos.test.js +136 -0
- package/dist/MafSequenceWidget/colToGenomePos.test.js.map +1 -0
- package/dist/MafSequenceWidget/configSchema.d.ts +1 -0
- package/dist/MafSequenceWidget/configSchema.js +3 -0
- package/dist/MafSequenceWidget/configSchema.js.map +1 -0
- package/dist/MafSequenceWidget/constants.d.ts +4 -0
- package/dist/MafSequenceWidget/constants.js +5 -0
- package/dist/MafSequenceWidget/constants.js.map +1 -0
- package/dist/MafSequenceWidget/index.d.ts +2 -0
- package/dist/MafSequenceWidget/index.js +16 -0
- package/dist/MafSequenceWidget/index.js.map +1 -0
- package/dist/MafSequenceWidget/stateModelFactory.d.ts +67 -0
- package/dist/MafSequenceWidget/stateModelFactory.js +21 -0
- package/dist/MafSequenceWidget/stateModelFactory.js.map +1 -0
- package/dist/MafTabixAdapter/MafTabixAdapter.js +4 -35
- package/dist/MafTabixAdapter/MafTabixAdapter.js.map +1 -1
- package/dist/MafTabixAdapter/configSchema.d.ts +4 -4
- package/dist/MafTrack/configSchema.d.ts +16 -11
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/jbrowse-plugin-mafviewer.umd.production.min.js +12 -24
- package/dist/jbrowse-plugin-mafviewer.umd.production.min.js.map +4 -4
- package/dist/util/clipboard.d.ts +2 -0
- package/dist/util/clipboard.js +28 -0
- package/dist/util/clipboard.js.map +1 -0
- package/dist/util/fastaUtils.d.ts +2 -1
- package/dist/util/fastaUtils.js +72 -2
- package/dist/util/fastaUtils.js.map +1 -1
- package/dist/util/fastaUtils.test.js +190 -0
- package/dist/util/fastaUtils.test.js.map +1 -1
- package/dist/util/parseAssemblyName.d.ts +32 -0
- package/dist/util/parseAssemblyName.js +87 -0
- package/dist/util/parseAssemblyName.js.map +1 -0
- package/dist/util/parseAssemblyName.test.d.ts +1 -0
- package/dist/util/parseAssemblyName.test.js +269 -0
- package/dist/util/parseAssemblyName.test.js.map +1 -0
- package/package.json +7 -7
- package/src/BigMafAdapter/BigMafAdapter.ts +5 -5
- package/src/LinearMafDisplay/components/LinearMafDisplayComponent.tsx +62 -144
- package/src/LinearMafDisplay/components/MAFTooltip.tsx +0 -3
- package/src/LinearMafDisplay/components/MsaHighlightOverlay.tsx +62 -0
- package/src/LinearMafDisplay/components/Sidebar/SvgWrapper.tsx +1 -1
- package/src/LinearMafDisplay/components/useDragSelection.ts +159 -0
- package/src/LinearMafDisplay/stateModel.ts +135 -48
- package/src/LinearMafDisplay/types.ts +2 -2
- package/src/LinearMafDisplay/util.ts +31 -5
- package/src/LinearMafRenderer/LinearMafRenderer.ts +1 -1
- package/src/LinearMafRenderer/components/LinearMafRendering.tsx +38 -24
- package/src/LinearMafRenderer/configSchema.ts +1 -6
- package/src/LinearMafRenderer/rendering/insertions.ts +2 -2
- package/src/LinearMafRenderer/rendering/mismatches.ts +3 -3
- package/src/LinearMafRenderer/rendering/types.ts +1 -1
- package/src/MafAddTrackWorkflow/AddTrackWorkflow.tsx +1 -1
- package/src/MafAddTrackWorkflow/index.ts +1 -1
- package/src/MafGetSequences/MafGetSequences.ts +10 -2
- package/src/MafSequenceWidget/LabelsCanvas.tsx +58 -0
- package/src/MafSequenceWidget/MafSequenceHoverHighlight.tsx +83 -0
- package/src/MafSequenceWidget/MafSequenceHoverHighlightExtension.tsx +24 -0
- package/src/MafSequenceWidget/MafSequenceWidget.tsx +294 -0
- package/src/MafSequenceWidget/SequenceCanvas.tsx +136 -0
- package/src/MafSequenceWidget/SequenceDisplay.tsx +188 -0
- package/src/MafSequenceWidget/SequenceTooltip.tsx +70 -0
- package/src/MafSequenceWidget/baseColors.ts +76 -0
- package/src/MafSequenceWidget/colToGenomePos.test.ts +166 -0
- package/src/MafSequenceWidget/colToGenomePos.ts +40 -0
- package/src/MafSequenceWidget/configSchema.ts +3 -0
- package/src/MafSequenceWidget/constants.ts +4 -0
- package/src/MafSequenceWidget/index.ts +24 -0
- package/src/MafSequenceWidget/stateModelFactory.ts +43 -0
- package/src/MafTabixAdapter/MafTabixAdapter.ts +12 -51
- package/src/index.ts +2 -0
- package/src/util/__snapshots__/fastaUtils.test.ts.snap +35 -0
- package/src/util/clipboard.ts +35 -0
- package/src/util/fastaUtils.test.ts +199 -0
- package/src/util/fastaUtils.ts +94 -1
- package/src/util/parseAssemblyName.test.ts +350 -0
- package/src/util/parseAssemblyName.ts +106 -0
- package/dist/LinearMafDisplay/components/GetSequenceDialog/GetSequenceDialog.d.ts +0 -11
- package/dist/LinearMafDisplay/components/GetSequenceDialog/GetSequenceDialog.js +0 -97
- package/dist/LinearMafDisplay/components/GetSequenceDialog/GetSequenceDialog.js.map +0 -1
- package/dist/LinearMafDisplay/components/InsertionSequenceDialog/InsertionSequenceDialog.d.ts +0 -14
- package/dist/LinearMafDisplay/components/InsertionSequenceDialog/InsertionSequenceDialog.js +0 -69
- package/dist/LinearMafDisplay/components/InsertionSequenceDialog/InsertionSequenceDialog.js.map +0 -1
- package/dist/LinearMafDisplay/components/util.d.ts +0 -1
- package/dist/LinearMafDisplay/components/util.js +0 -8
- package/dist/LinearMafDisplay/components/util.js.map +0 -1
- package/dist/util/fetchSequences.d.ts +0 -18
- package/dist/util/fetchSequences.js +0 -39
- package/dist/util/fetchSequences.js.map +0 -1
- package/dist/util/useSequences.d.ts +0 -21
- package/dist/util/useSequences.js +0 -64
- package/dist/util/useSequences.js.map +0 -1
- package/src/LinearMafDisplay/components/GetSequenceDialog/GetSequenceDialog.tsx +0 -175
- package/src/LinearMafDisplay/components/InsertionSequenceDialog/InsertionSequenceDialog.tsx +0 -105
- package/src/LinearMafDisplay/components/util.ts +0 -7
- package/src/util/fetchSequences.ts +0 -57
- package/src/util/useSequences.ts +0 -90
|
@@ -0,0 +1,269 @@
|
|
|
1
|
+
import { describe, expect, test } from 'vitest';
|
|
2
|
+
import { parseAssemblyAndChr, parseAssemblyAndChrSimple, selectReferenceSequence, } from './parseAssemblyName';
|
|
3
|
+
describe('parseAssemblyAndChr (MafTabix format)', () => {
|
|
4
|
+
test('no dot - entire string is assembly name', () => {
|
|
5
|
+
const result = parseAssemblyAndChr('hg38');
|
|
6
|
+
expect(result).toEqual({
|
|
7
|
+
assemblyName: 'hg38',
|
|
8
|
+
chr: '',
|
|
9
|
+
});
|
|
10
|
+
});
|
|
11
|
+
test('single dot - simple assembly.chr format', () => {
|
|
12
|
+
const result = parseAssemblyAndChr('hg38.chr1');
|
|
13
|
+
expect(result).toEqual({
|
|
14
|
+
assemblyName: 'hg38',
|
|
15
|
+
chr: 'chr1',
|
|
16
|
+
});
|
|
17
|
+
});
|
|
18
|
+
test('single dot - assembly.refName format with non-chr name', () => {
|
|
19
|
+
const result = parseAssemblyAndChr('mm10.scaffold_1');
|
|
20
|
+
expect(result).toEqual({
|
|
21
|
+
assemblyName: 'mm10',
|
|
22
|
+
chr: 'scaffold_1',
|
|
23
|
+
});
|
|
24
|
+
});
|
|
25
|
+
test('two dots with numeric version - assembly.version.chr format', () => {
|
|
26
|
+
const result = parseAssemblyAndChr('hg38.1.chr1');
|
|
27
|
+
expect(result).toEqual({
|
|
28
|
+
assemblyName: 'hg38.1',
|
|
29
|
+
chr: 'chr1',
|
|
30
|
+
});
|
|
31
|
+
});
|
|
32
|
+
test('two dots with multi-digit numeric version', () => {
|
|
33
|
+
const result = parseAssemblyAndChr('GRCh38.123.chrX');
|
|
34
|
+
expect(result).toEqual({
|
|
35
|
+
assemblyName: 'GRCh38.123',
|
|
36
|
+
chr: 'chrX',
|
|
37
|
+
});
|
|
38
|
+
});
|
|
39
|
+
test('two dots with non-numeric middle - assembly.chr.more format', () => {
|
|
40
|
+
const result = parseAssemblyAndChr('mm10.chr1.random');
|
|
41
|
+
expect(result).toEqual({
|
|
42
|
+
assemblyName: 'mm10',
|
|
43
|
+
chr: 'chr1.random',
|
|
44
|
+
});
|
|
45
|
+
});
|
|
46
|
+
test('two dots with non-numeric middle - chr_Un type naming', () => {
|
|
47
|
+
const result = parseAssemblyAndChr('hg38.chrUn_gl000220');
|
|
48
|
+
expect(result).toEqual({
|
|
49
|
+
assemblyName: 'hg38',
|
|
50
|
+
chr: 'chrUn_gl000220',
|
|
51
|
+
});
|
|
52
|
+
});
|
|
53
|
+
test('three dots with numeric version - assembly.version.chr.more format', () => {
|
|
54
|
+
const result = parseAssemblyAndChr('GRCh38.1.chr1.random');
|
|
55
|
+
expect(result).toEqual({
|
|
56
|
+
assemblyName: 'GRCh38.1',
|
|
57
|
+
chr: 'chr1.random',
|
|
58
|
+
});
|
|
59
|
+
});
|
|
60
|
+
test('empty string', () => {
|
|
61
|
+
const result = parseAssemblyAndChr('');
|
|
62
|
+
expect(result).toEqual({
|
|
63
|
+
assemblyName: '',
|
|
64
|
+
chr: '',
|
|
65
|
+
});
|
|
66
|
+
});
|
|
67
|
+
test('just a dot', () => {
|
|
68
|
+
const result = parseAssemblyAndChr('.');
|
|
69
|
+
expect(result).toEqual({
|
|
70
|
+
assemblyName: '',
|
|
71
|
+
chr: '',
|
|
72
|
+
});
|
|
73
|
+
});
|
|
74
|
+
test('leading dot', () => {
|
|
75
|
+
const result = parseAssemblyAndChr('.chr1');
|
|
76
|
+
expect(result).toEqual({
|
|
77
|
+
assemblyName: '',
|
|
78
|
+
chr: 'chr1',
|
|
79
|
+
});
|
|
80
|
+
});
|
|
81
|
+
test('trailing dot', () => {
|
|
82
|
+
const result = parseAssemblyAndChr('hg38.');
|
|
83
|
+
expect(result).toEqual({
|
|
84
|
+
assemblyName: 'hg38',
|
|
85
|
+
chr: '',
|
|
86
|
+
});
|
|
87
|
+
});
|
|
88
|
+
test('real world example - UCSC style', () => {
|
|
89
|
+
const result = parseAssemblyAndChr('hg19.chr6_ssto_hap7');
|
|
90
|
+
expect(result).toEqual({
|
|
91
|
+
assemblyName: 'hg19',
|
|
92
|
+
chr: 'chr6_ssto_hap7',
|
|
93
|
+
});
|
|
94
|
+
});
|
|
95
|
+
test('real world example - Ensembl style with numeric', () => {
|
|
96
|
+
const result = parseAssemblyAndChr('GRCh37.1.1');
|
|
97
|
+
expect(result).toEqual({
|
|
98
|
+
assemblyName: 'GRCh37.1',
|
|
99
|
+
chr: '1',
|
|
100
|
+
});
|
|
101
|
+
});
|
|
102
|
+
});
|
|
103
|
+
describe('parseAssemblyAndChrSimple (BigMaf format)', () => {
|
|
104
|
+
test('no dot - entire string is assembly name', () => {
|
|
105
|
+
const result = parseAssemblyAndChrSimple('hg38');
|
|
106
|
+
expect(result).toEqual({
|
|
107
|
+
assemblyName: 'hg38',
|
|
108
|
+
chr: '',
|
|
109
|
+
});
|
|
110
|
+
});
|
|
111
|
+
test('single dot - simple org.chr format', () => {
|
|
112
|
+
const result = parseAssemblyAndChrSimple('hg38.chr1');
|
|
113
|
+
expect(result).toEqual({
|
|
114
|
+
assemblyName: 'hg38',
|
|
115
|
+
chr: 'chr1',
|
|
116
|
+
});
|
|
117
|
+
});
|
|
118
|
+
test('multiple dots - only splits on first dot', () => {
|
|
119
|
+
const result = parseAssemblyAndChrSimple('mm10.chr1.random');
|
|
120
|
+
expect(result).toEqual({
|
|
121
|
+
assemblyName: 'mm10',
|
|
122
|
+
chr: 'chr1.random',
|
|
123
|
+
});
|
|
124
|
+
});
|
|
125
|
+
test('empty string', () => {
|
|
126
|
+
const result = parseAssemblyAndChrSimple('');
|
|
127
|
+
expect(result).toEqual({
|
|
128
|
+
assemblyName: '',
|
|
129
|
+
chr: '',
|
|
130
|
+
});
|
|
131
|
+
});
|
|
132
|
+
});
|
|
133
|
+
describe('selectReferenceSequence', () => {
|
|
134
|
+
const alignments = {
|
|
135
|
+
hg38: { seq: 'ACGTACGT' },
|
|
136
|
+
mm10: { seq: 'TGCATGCA' },
|
|
137
|
+
panTro6: { seq: 'GGGGGGGG' },
|
|
138
|
+
};
|
|
139
|
+
test('uses refAssemblyName when provided and exists', () => {
|
|
140
|
+
const result = selectReferenceSequence(alignments, 'mm10', 'hg38', 'panTro6');
|
|
141
|
+
expect(result).toBe('TGCATGCA');
|
|
142
|
+
});
|
|
143
|
+
test('falls back to queryAssemblyName when refAssemblyName is empty', () => {
|
|
144
|
+
const result = selectReferenceSequence(alignments, '', 'hg38', 'panTro6');
|
|
145
|
+
expect(result).toBe('ACGTACGT');
|
|
146
|
+
});
|
|
147
|
+
test('falls back to queryAssemblyName when refAssemblyName is undefined', () => {
|
|
148
|
+
const result = selectReferenceSequence(alignments, undefined, 'hg38', 'panTro6');
|
|
149
|
+
expect(result).toBe('ACGTACGT');
|
|
150
|
+
});
|
|
151
|
+
test('falls back to firstAssemblyNameFound when queryAssemblyName does not match', () => {
|
|
152
|
+
const result = selectReferenceSequence(alignments, undefined, 'galGal6', // not in alignments
|
|
153
|
+
'hg38');
|
|
154
|
+
expect(result).toBe('ACGTACGT');
|
|
155
|
+
});
|
|
156
|
+
test('falls back to firstAssemblyNameFound when both config values are empty', () => {
|
|
157
|
+
const result = selectReferenceSequence(alignments, '', '', 'panTro6');
|
|
158
|
+
expect(result).toBe('GGGGGGGG');
|
|
159
|
+
});
|
|
160
|
+
test('returns undefined when refAssemblyName does not exist in alignments', () => {
|
|
161
|
+
const result = selectReferenceSequence(alignments, 'nonexistent', undefined, undefined);
|
|
162
|
+
expect(result).toBeUndefined();
|
|
163
|
+
});
|
|
164
|
+
test('returns undefined when no matches and all params undefined', () => {
|
|
165
|
+
const result = selectReferenceSequence(alignments, undefined, undefined, undefined);
|
|
166
|
+
expect(result).toBeUndefined();
|
|
167
|
+
});
|
|
168
|
+
test('returns undefined for empty alignments object', () => {
|
|
169
|
+
const result = selectReferenceSequence({}, 'hg38', 'mm10', 'panTro6');
|
|
170
|
+
expect(result).toBeUndefined();
|
|
171
|
+
});
|
|
172
|
+
test('skips refAssemblyName when it does not exist and uses queryAssemblyName', () => {
|
|
173
|
+
const result = selectReferenceSequence(alignments, 'galGal6', // not in alignments
|
|
174
|
+
'hg38', 'panTro6');
|
|
175
|
+
expect(result).toBe('ACGTACGT');
|
|
176
|
+
});
|
|
177
|
+
test('skips both refAssemblyName and queryAssemblyName when neither exists', () => {
|
|
178
|
+
const result = selectReferenceSequence(alignments, 'galGal6', // not in alignments
|
|
179
|
+
'rn6', // not in alignments
|
|
180
|
+
'mm10');
|
|
181
|
+
expect(result).toBe('TGCATGCA');
|
|
182
|
+
});
|
|
183
|
+
});
|
|
184
|
+
describe('assembly name lookup integration scenarios', () => {
|
|
185
|
+
test('refAssemblyName config takes precedence over query.assemblyName', () => {
|
|
186
|
+
const alignments = {
|
|
187
|
+
hg38: { seq: 'REFERENCE_SEQ' },
|
|
188
|
+
mm10: { seq: 'QUERY_SEQ' },
|
|
189
|
+
};
|
|
190
|
+
const result = selectReferenceSequence(alignments, 'hg38', 'mm10', 'mm10');
|
|
191
|
+
expect(result).toBe('REFERENCE_SEQ');
|
|
192
|
+
});
|
|
193
|
+
test('query.assemblyName works when refAssemblyName not configured', () => {
|
|
194
|
+
const alignments = {
|
|
195
|
+
hg38: { seq: 'QUERY_SEQ' },
|
|
196
|
+
mm10: { seq: 'OTHER_SEQ' },
|
|
197
|
+
};
|
|
198
|
+
const result = selectReferenceSequence(alignments, '', 'hg38', 'mm10');
|
|
199
|
+
expect(result).toBe('QUERY_SEQ');
|
|
200
|
+
});
|
|
201
|
+
test('firstAssemblyNameFound is used as last resort fallback', () => {
|
|
202
|
+
const alignments = {
|
|
203
|
+
panTro6: { seq: 'FIRST_FOUND' },
|
|
204
|
+
mm10: { seq: 'OTHER_SEQ' },
|
|
205
|
+
};
|
|
206
|
+
// When query assemblyName does not match any alignment
|
|
207
|
+
const result = selectReferenceSequence(alignments, '', 'hg38', 'panTro6');
|
|
208
|
+
expect(result).toBe('FIRST_FOUND');
|
|
209
|
+
});
|
|
210
|
+
});
|
|
211
|
+
describe('real-world MAF format parsing', () => {
|
|
212
|
+
test('ce10.chrI from UCSC 7-way alignment', () => {
|
|
213
|
+
const result = parseAssemblyAndChr('ce10.chrI');
|
|
214
|
+
expect(result).toEqual({
|
|
215
|
+
assemblyName: 'ce10',
|
|
216
|
+
chr: 'chrI',
|
|
217
|
+
});
|
|
218
|
+
});
|
|
219
|
+
test('caePb3.Scfld02_18 scaffold format', () => {
|
|
220
|
+
const result = parseAssemblyAndChr('caePb3.Scfld02_18');
|
|
221
|
+
expect(result).toEqual({
|
|
222
|
+
assemblyName: 'caePb3',
|
|
223
|
+
chr: 'Scfld02_18',
|
|
224
|
+
});
|
|
225
|
+
});
|
|
226
|
+
test('caeRem4.Crem_Contig16 contig format', () => {
|
|
227
|
+
const result = parseAssemblyAndChr('caeRem4.Crem_Contig16');
|
|
228
|
+
expect(result).toEqual({
|
|
229
|
+
assemblyName: 'caeRem4',
|
|
230
|
+
chr: 'Crem_Contig16',
|
|
231
|
+
});
|
|
232
|
+
});
|
|
233
|
+
test('cb4.chrI C. briggsae format', () => {
|
|
234
|
+
const result = parseAssemblyAndChr('cb4.chrI');
|
|
235
|
+
expect(result).toEqual({
|
|
236
|
+
assemblyName: 'cb4',
|
|
237
|
+
chr: 'chrI',
|
|
238
|
+
});
|
|
239
|
+
});
|
|
240
|
+
test('multiple assemblies from same MAF block produce correct lookup', () => {
|
|
241
|
+
const alignments = {
|
|
242
|
+
ce10: { seq: 'TCTTTTAGTATTTGTAA' },
|
|
243
|
+
caePb3: { seq: 'tcTTTTCGC-TTTATAA' },
|
|
244
|
+
};
|
|
245
|
+
// When querying with ce10 assembly
|
|
246
|
+
expect(selectReferenceSequence(alignments, '', 'ce10', 'ce10')).toBe('TCTTTTAGTATTTGTAA');
|
|
247
|
+
// When refAssemblyName is configured to override
|
|
248
|
+
expect(selectReferenceSequence(alignments, 'caePb3', 'ce10', 'ce10')).toBe('tcTTTTCGC-TTTATAA');
|
|
249
|
+
});
|
|
250
|
+
});
|
|
251
|
+
describe('refName renaming compatibility', () => {
|
|
252
|
+
test('parseAssemblyAndChr extracts chr correctly for refName alias matching', () => {
|
|
253
|
+
// When a file uses "chrI" but assembly has alias "I" -> "chrI"
|
|
254
|
+
// The chr portion extracted here should match what renameRegionsIfNeeded expects
|
|
255
|
+
const { chr } = parseAssemblyAndChr('ce10.chrI');
|
|
256
|
+
expect(chr).toBe('chrI');
|
|
257
|
+
});
|
|
258
|
+
test('parseAssemblyAndChrSimple extracts chr correctly for refName alias matching', () => {
|
|
259
|
+
const { chr } = parseAssemblyAndChrSimple('ce10.chrI');
|
|
260
|
+
expect(chr).toBe('chrI');
|
|
261
|
+
});
|
|
262
|
+
test('assembly name is isolated from chr for assembly-based lookups', () => {
|
|
263
|
+
// The assembly name (e.g., "ce10") is used to look up reference sequence
|
|
264
|
+
// It should not include the chr portion
|
|
265
|
+
const { assemblyName } = parseAssemblyAndChr('ce10.chrI');
|
|
266
|
+
expect(assemblyName).toBe('ce10');
|
|
267
|
+
});
|
|
268
|
+
});
|
|
269
|
+
//# sourceMappingURL=parseAssemblyName.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parseAssemblyName.test.js","sourceRoot":"","sources":["../../src/util/parseAssemblyName.test.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "1.4.
|
|
2
|
+
"version": "1.4.6",
|
|
3
3
|
"license": "MIT",
|
|
4
4
|
"name": "jbrowse-plugin-mafviewer",
|
|
5
5
|
"keywords": [
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
],
|
|
16
16
|
"scripts": {
|
|
17
17
|
"clean": "rimraf dist",
|
|
18
|
-
"start": "node esbuild.mjs",
|
|
18
|
+
"start": "node esbuild.mjs --watch",
|
|
19
19
|
"test": "vitest",
|
|
20
20
|
"format": "prettier --write .",
|
|
21
21
|
"prebuild": "yarn clean",
|
|
@@ -29,9 +29,10 @@
|
|
|
29
29
|
"@babel/preset-react": "^7.10.4",
|
|
30
30
|
"@emotion/react": "^11.10.4",
|
|
31
31
|
"@fal-works/esbuild-plugin-global-externals": "^2.1.2",
|
|
32
|
-
"@jbrowse/core": "^
|
|
33
|
-
"@jbrowse/
|
|
34
|
-
"@jbrowse/plugin-
|
|
32
|
+
"@jbrowse/core": "^4.1.1",
|
|
33
|
+
"@jbrowse/mobx-state-tree": "^5.4.1",
|
|
34
|
+
"@jbrowse/plugin-data-management": "^4.1.1",
|
|
35
|
+
"@jbrowse/plugin-linear-genome-view": "^4.1.1",
|
|
35
36
|
"@mui/material": "^7.0.1",
|
|
36
37
|
"@mui/system": "^7.0.1",
|
|
37
38
|
"@mui/x-data-grid": "^8.2.0",
|
|
@@ -48,7 +49,6 @@
|
|
|
48
49
|
"eslint-plugin-unicorn": "^62.0.0",
|
|
49
50
|
"mobx": "^6.0.0",
|
|
50
51
|
"mobx-react": "^9.0.1",
|
|
51
|
-
"mobx-state-tree": "^5.4.1",
|
|
52
52
|
"prettier": "^3.4.2",
|
|
53
53
|
"pretty-bytes": "^7.0.0",
|
|
54
54
|
"react": "^19.0.0",
|
|
@@ -62,7 +62,7 @@
|
|
|
62
62
|
"vitest": "^4.0.5"
|
|
63
63
|
},
|
|
64
64
|
"dependencies": {
|
|
65
|
-
"@gmod/bgzf-filehandle": "^
|
|
65
|
+
"@gmod/bgzf-filehandle": "^6.0.12",
|
|
66
66
|
"abortable-promise-cache": "^1.5.0",
|
|
67
67
|
"buffer": "^6.0.3",
|
|
68
68
|
"d3-array": "^3.2.4",
|
|
@@ -2,11 +2,12 @@ import { BaseFeatureDataAdapter } from '@jbrowse/core/data_adapters/BaseAdapter'
|
|
|
2
2
|
import { SimpleFeature, updateStatus } from '@jbrowse/core/util'
|
|
3
3
|
import { openLocation } from '@jbrowse/core/util/io'
|
|
4
4
|
import { ObservableCreate } from '@jbrowse/core/util/rxjs'
|
|
5
|
-
import { getSnapshot } from 'mobx-state-tree'
|
|
5
|
+
import { getSnapshot } from '@jbrowse/mobx-state-tree'
|
|
6
6
|
import { firstValueFrom, toArray } from 'rxjs'
|
|
7
7
|
|
|
8
8
|
import parseNewick from '../parseNewick'
|
|
9
9
|
import { normalize } from '../util'
|
|
10
|
+
import { parseAssemblyAndChrSimple } from '../util/parseAssemblyName'
|
|
10
11
|
|
|
11
12
|
import type { BaseOptions } from '@jbrowse/core/data_adapters/BaseAdapter'
|
|
12
13
|
import type { Feature, Region } from '@jbrowse/core/util'
|
|
@@ -103,10 +104,9 @@ export default class BigMafAdapter extends BaseFeatureDataAdapter {
|
|
|
103
104
|
referenceSeq = sequence
|
|
104
105
|
}
|
|
105
106
|
|
|
106
|
-
// Parse organism and chromosome
|
|
107
|
-
const
|
|
108
|
-
|
|
109
|
-
const chr = organismChr.slice(Math.max(0, dotIndex + 1))
|
|
107
|
+
// Parse organism and chromosome
|
|
108
|
+
const { assemblyName: org, chr } =
|
|
109
|
+
parseAssemblyAndChrSimple(organismChr)
|
|
110
110
|
|
|
111
111
|
// Create alignment record directly
|
|
112
112
|
alignments[org] = {
|
|
@@ -1,14 +1,20 @@
|
|
|
1
|
-
import React, {
|
|
1
|
+
import React, { useRef } from 'react'
|
|
2
2
|
|
|
3
3
|
import { Menu } from '@jbrowse/core/ui'
|
|
4
|
-
import {
|
|
4
|
+
import {
|
|
5
|
+
getContainingView,
|
|
6
|
+
getEnv,
|
|
7
|
+
getSession,
|
|
8
|
+
isSessionModelWithWidgets,
|
|
9
|
+
} from '@jbrowse/core/util'
|
|
5
10
|
import { useTheme } from '@mui/material'
|
|
6
11
|
import { observer } from 'mobx-react'
|
|
7
12
|
|
|
8
13
|
import Crosshairs from './Crosshairs'
|
|
9
|
-
import SequenceDialog from './GetSequenceDialog/GetSequenceDialog'
|
|
10
14
|
import MAFTooltip from './MAFTooltip'
|
|
15
|
+
import MsaHighlightOverlay from './MsaHighlightOverlay'
|
|
11
16
|
import YScaleBars from './Sidebar/YScaleBars'
|
|
17
|
+
import { useDragSelection } from './useDragSelection'
|
|
12
18
|
|
|
13
19
|
import type { LinearMafDisplayModel } from '../stateModel'
|
|
14
20
|
import type { LinearGenomeViewModel } from '@jbrowse/plugin-linear-genome-view'
|
|
@@ -18,123 +24,34 @@ const LinearMafDisplay = observer(function (props: {
|
|
|
18
24
|
}) {
|
|
19
25
|
const { model } = props
|
|
20
26
|
const { pluginManager } = getEnv(model)
|
|
21
|
-
const {
|
|
27
|
+
const { height, scrollTop, samples: sources } = model
|
|
22
28
|
const ref = useRef<HTMLDivElement>(null)
|
|
23
29
|
const theme = useTheme()
|
|
30
|
+
const session = getSession(model)
|
|
24
31
|
|
|
25
32
|
const LinearGenomePlugin = pluginManager.getPlugin(
|
|
26
33
|
'LinearGenomeViewPlugin',
|
|
27
34
|
) as import('@jbrowse/plugin-linear-genome-view').default
|
|
28
35
|
const { BaseLinearDisplayComponent } = LinearGenomePlugin.exports
|
|
29
36
|
|
|
30
|
-
const
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
>()
|
|
49
|
-
const { width } = getContainingView(model) as LinearGenomeViewModel
|
|
50
|
-
|
|
51
|
-
const handleMouseDown = (event: React.MouseEvent) => {
|
|
52
|
-
const rect = ref.current?.getBoundingClientRect()
|
|
53
|
-
const left = rect?.left || 0
|
|
54
|
-
const clientX = event.clientX - left
|
|
55
|
-
|
|
56
|
-
// Clear the previous selection box when starting a new drag
|
|
57
|
-
setShowSelectionBox(false)
|
|
58
|
-
setIsDragging(true)
|
|
59
|
-
setDragStartX(clientX)
|
|
60
|
-
setDragEndX(clientX)
|
|
61
|
-
event.stopPropagation()
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
const handleMouseMove = (event: React.MouseEvent) => {
|
|
65
|
-
const rect = ref.current?.getBoundingClientRect()
|
|
66
|
-
const top = rect?.top || 0
|
|
67
|
-
const left = rect?.left || 0
|
|
68
|
-
const clientX = event.clientX - left
|
|
69
|
-
const clientY = event.clientY - top
|
|
70
|
-
|
|
71
|
-
setMouseY(clientY)
|
|
72
|
-
setMouseX(clientX)
|
|
73
|
-
|
|
74
|
-
if (isDragging) {
|
|
75
|
-
setDragEndX(clientX)
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
const handleMouseUp = (event: React.MouseEvent) => {
|
|
80
|
-
if (isDragging && dragStartX !== undefined && dragEndX !== undefined) {
|
|
81
|
-
// Calculate the drag distance
|
|
82
|
-
const dragDistanceX = Math.abs(dragEndX - dragStartX)
|
|
83
|
-
|
|
84
|
-
// Only show context menu if the drag distance is at least 2 pixels in either direction
|
|
85
|
-
if (dragDistanceX >= 2) {
|
|
86
|
-
setContextCoord({
|
|
87
|
-
coord: [event.clientX, event.clientY],
|
|
88
|
-
dragEndX: event.clientX,
|
|
89
|
-
dragStartX: dragStartX,
|
|
90
|
-
})
|
|
91
|
-
|
|
92
|
-
// Set showSelectionBox to true to keep the selection visible
|
|
93
|
-
setShowSelectionBox(true)
|
|
94
|
-
} else {
|
|
95
|
-
// For very small drags (less than 2px), don't show selection box or context menu
|
|
96
|
-
clearSelectionBox()
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
// Only set isDragging to false, but keep the coordinates
|
|
101
|
-
setIsDragging(false)
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
// Function to clear the selection box
|
|
105
|
-
const clearSelectionBox = useCallback(() => {
|
|
106
|
-
setShowSelectionBox(false)
|
|
107
|
-
setDragStartX(undefined)
|
|
108
|
-
setDragEndX(undefined)
|
|
109
|
-
}, [])
|
|
110
|
-
|
|
111
|
-
// Add keydown event handler to clear selection box when Escape key is pressed
|
|
112
|
-
useEffect(() => {
|
|
113
|
-
const handleKeyDown = (event: KeyboardEvent) => {
|
|
114
|
-
if (event.key === 'Escape' && showSelectionBox) {
|
|
115
|
-
clearSelectionBox()
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
// Add click handler to clear selection box when clicking outside of it
|
|
120
|
-
const handleClickOutside = (event: MouseEvent) => {
|
|
121
|
-
if (
|
|
122
|
-
ref.current &&
|
|
123
|
-
!ref.current.contains(event.target as Node) &&
|
|
124
|
-
showSelectionBox
|
|
125
|
-
) {
|
|
126
|
-
clearSelectionBox()
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
document.addEventListener('keydown', handleKeyDown)
|
|
131
|
-
document.addEventListener('click', handleClickOutside)
|
|
132
|
-
|
|
133
|
-
return () => {
|
|
134
|
-
document.removeEventListener('keydown', handleKeyDown)
|
|
135
|
-
document.removeEventListener('click', handleClickOutside)
|
|
136
|
-
}
|
|
137
|
-
}, [showSelectionBox, clearSelectionBox])
|
|
37
|
+
const {
|
|
38
|
+
isDragging,
|
|
39
|
+
dragStartX,
|
|
40
|
+
dragEndX,
|
|
41
|
+
showSelectionBox,
|
|
42
|
+
mouseX,
|
|
43
|
+
mouseY,
|
|
44
|
+
contextCoord,
|
|
45
|
+
setContextCoord,
|
|
46
|
+
handleMouseDown,
|
|
47
|
+
handleMouseMove,
|
|
48
|
+
handleMouseUp,
|
|
49
|
+
handleMouseLeave,
|
|
50
|
+
clearSelectionBox,
|
|
51
|
+
} = useDragSelection(ref)
|
|
52
|
+
|
|
53
|
+
const view = getContainingView(model) as LinearGenomeViewModel
|
|
54
|
+
const { width } = view
|
|
138
55
|
|
|
139
56
|
return (
|
|
140
57
|
<div
|
|
@@ -143,20 +60,19 @@ const LinearMafDisplay = observer(function (props: {
|
|
|
143
60
|
onMouseMove={handleMouseMove}
|
|
144
61
|
onMouseUp={handleMouseUp}
|
|
145
62
|
onDoubleClick={() => {
|
|
146
|
-
// Clear selection box on double click
|
|
147
63
|
if (showSelectionBox) {
|
|
148
64
|
clearSelectionBox()
|
|
149
65
|
}
|
|
150
66
|
}}
|
|
151
|
-
onMouseLeave={
|
|
152
|
-
setMouseY(undefined)
|
|
153
|
-
setMouseX(undefined)
|
|
154
|
-
setIsDragging(false)
|
|
155
|
-
}}
|
|
67
|
+
onMouseLeave={handleMouseLeave}
|
|
156
68
|
>
|
|
157
69
|
<BaseLinearDisplayComponent {...props} />
|
|
158
70
|
{model.showSidebar ? <YScaleBars model={model} /> : null}
|
|
159
|
-
{
|
|
71
|
+
<MsaHighlightOverlay model={model} view={view} height={height} />
|
|
72
|
+
{mouseY !== undefined &&
|
|
73
|
+
mouseX !== undefined &&
|
|
74
|
+
sources &&
|
|
75
|
+
!contextCoord ? (
|
|
160
76
|
<div style={{ position: 'relative' }}>
|
|
161
77
|
<Crosshairs
|
|
162
78
|
width={width}
|
|
@@ -168,10 +84,7 @@ const LinearMafDisplay = observer(function (props: {
|
|
|
168
84
|
<MAFTooltip
|
|
169
85
|
model={model}
|
|
170
86
|
mouseX={mouseX}
|
|
171
|
-
|
|
172
|
-
origMouseX={dragStartX}
|
|
173
|
-
rowHeight={rowHeight}
|
|
174
|
-
sources={sources}
|
|
87
|
+
origMouseX={isDragging ? dragStartX : undefined}
|
|
175
88
|
/>
|
|
176
89
|
</div>
|
|
177
90
|
) : null}
|
|
@@ -224,32 +137,37 @@ const LinearMafDisplay = observer(function (props: {
|
|
|
224
137
|
return
|
|
225
138
|
}
|
|
226
139
|
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
dragStartX
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
140
|
+
const { refName, assemblyName } = view.displayedRegions[0]!
|
|
141
|
+
const [s, e] = [
|
|
142
|
+
Math.min(contextCoord.dragStartX, contextCoord.dragEndX),
|
|
143
|
+
Math.max(contextCoord.dragStartX, contextCoord.dragEndX),
|
|
144
|
+
]
|
|
145
|
+
|
|
146
|
+
if (isSessionModelWithWidgets(session)) {
|
|
147
|
+
const widget = session.addWidget(
|
|
148
|
+
'MafSequenceWidget',
|
|
149
|
+
'mafSequence',
|
|
150
|
+
{
|
|
151
|
+
adapterConfig: model.adapterConfig,
|
|
152
|
+
samples: model.samples,
|
|
153
|
+
regions: [
|
|
154
|
+
{
|
|
155
|
+
refName,
|
|
156
|
+
start: view.pxToBp(s).coord - 1,
|
|
157
|
+
end: view.pxToBp(e).coord,
|
|
158
|
+
assemblyName,
|
|
159
|
+
},
|
|
160
|
+
],
|
|
161
|
+
connectedViewId: view.id,
|
|
162
|
+
},
|
|
163
|
+
)
|
|
164
|
+
session.showWidget(widget)
|
|
165
|
+
}
|
|
237
166
|
setContextCoord(undefined)
|
|
238
167
|
},
|
|
239
168
|
},
|
|
240
169
|
]}
|
|
241
170
|
/>
|
|
242
|
-
|
|
243
|
-
{showSequenceDialog ? (
|
|
244
|
-
<SequenceDialog
|
|
245
|
-
model={model}
|
|
246
|
-
selectionCoords={selectionCoords}
|
|
247
|
-
onClose={() => {
|
|
248
|
-
setShowSequenceDialog(false)
|
|
249
|
-
setSelectionCoords(undefined)
|
|
250
|
-
}}
|
|
251
|
-
/>
|
|
252
|
-
) : null}
|
|
253
171
|
</div>
|
|
254
172
|
)
|
|
255
173
|
})
|