@jbrowse/plugin-alignments 2.16.1 → 2.17.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 (215) hide show
  1. package/dist/AlignmentsFeatureDetail/AlignmentsFeatureDetail.js +1 -2
  2. package/dist/AlignmentsFeatureDetail/getSAFeatures.js +2 -2
  3. package/dist/AlignmentsFeatureDetail/stateModelFactory.d.ts +1 -1
  4. package/dist/BamAdapter/BamAdapter.d.ts +3 -2
  5. package/dist/BamAdapter/BamAdapter.js +34 -11
  6. package/dist/BamAdapter/BamSlightlyLazyFeature.d.ts +3 -17
  7. package/dist/BamAdapter/BamSlightlyLazyFeature.js +42 -72
  8. package/dist/CramAdapter/CramAdapter.d.ts +4 -3
  9. package/dist/CramAdapter/CramAdapter.js +24 -7
  10. package/dist/CramAdapter/CramSlightlyLazyFeature.d.ts +21 -27
  11. package/dist/CramAdapter/CramSlightlyLazyFeature.js +74 -73
  12. package/dist/CramAdapter/util.d.ts +1 -10
  13. package/dist/LinearAlignmentsDisplay/components/AlignmentsDisplay.d.ts +1 -1
  14. package/dist/LinearAlignmentsDisplay/index.js +2 -2
  15. package/dist/LinearAlignmentsDisplay/{models/model.d.ts → model.d.ts} +6 -3
  16. package/dist/LinearAlignmentsDisplay/{models/model.js → model.js} +11 -7
  17. package/dist/LinearPileupDisplay/SharedLinearPileupDisplayMixin.d.ts +6 -27
  18. package/dist/LinearPileupDisplay/SharedLinearPileupDisplayMixin.js +43 -21
  19. package/dist/LinearPileupDisplay/components/ColorByTagDialog.d.ts +5 -4
  20. package/dist/LinearPileupDisplay/components/ColorByTagDialog.js +3 -1
  21. package/dist/LinearPileupDisplay/components/GroupByDialog.js +8 -6
  22. package/dist/LinearPileupDisplay/components/SortByTagDialog.js +6 -4
  23. package/dist/LinearPileupDisplay/model.d.ts +40 -40
  24. package/dist/LinearPileupDisplay/model.js +118 -41
  25. package/dist/LinearReadArcsDisplay/components/ReactComponent.js +1 -1
  26. package/dist/LinearReadArcsDisplay/model.d.ts +22 -21
  27. package/dist/LinearReadArcsDisplay/model.js +13 -14
  28. package/dist/LinearReadCloudDisplay/components/ReactComponent.js +1 -1
  29. package/dist/LinearReadCloudDisplay/model.d.ts +14 -22
  30. package/dist/LinearReadCloudDisplay/model.js +12 -13
  31. package/dist/LinearSNPCoverageDisplay/components/Tooltip.js +49 -19
  32. package/dist/LinearSNPCoverageDisplay/index.js +3 -2
  33. package/dist/LinearSNPCoverageDisplay/{models/model.d.ts → model.d.ts} +3 -13
  34. package/dist/LinearSNPCoverageDisplay/{models/model.js → model.js} +71 -45
  35. package/dist/MismatchParser/cigarToMismatches.d.ts +3 -0
  36. package/dist/MismatchParser/cigarToMismatches.js +94 -0
  37. package/dist/MismatchParser/getNextRefPos.d.ts +4 -0
  38. package/dist/MismatchParser/getNextRefPos.js +40 -0
  39. package/dist/MismatchParser/index.d.ts +4 -29
  40. package/dist/MismatchParser/index.js +10 -327
  41. package/dist/MismatchParser/mdToMismatches.d.ts +3 -0
  42. package/dist/MismatchParser/mdToMismatches.js +80 -0
  43. package/dist/ModificationParser/index.d.ts +19 -0
  44. package/dist/ModificationParser/index.js +144 -0
  45. package/dist/PileupRPC/methods/GetGlobalValueForTag.js +1 -2
  46. package/dist/PileupRPC/methods/GetReducedFeatures.d.ts +1 -1
  47. package/dist/PileupRPC/methods/GetReducedFeatures.js +19 -16
  48. package/dist/PileupRPC/methods/GetVisibleModifications.d.ts +2 -1
  49. package/dist/PileupRPC/methods/GetVisibleModifications.js +9 -6
  50. package/dist/PileupRenderer/PileupLayoutSession.d.ts +8 -7
  51. package/dist/PileupRenderer/PileupRenderer.d.ts +6 -14
  52. package/dist/PileupRenderer/PileupRenderer.js +7 -5
  53. package/dist/PileupRenderer/renderAlignment.js +17 -4
  54. package/dist/PileupRenderer/renderAlignmentShape.js +102 -21
  55. package/dist/PileupRenderer/renderMethylation.d.ts +2 -1
  56. package/dist/PileupRenderer/renderMethylation.js +17 -9
  57. package/dist/PileupRenderer/renderMismatches.js +19 -19
  58. package/dist/PileupRenderer/renderModifications.d.ts +3 -2
  59. package/dist/PileupRenderer/renderModifications.js +31 -34
  60. package/dist/PileupRenderer/renderPerBaseLettering.d.ts +2 -1
  61. package/dist/PileupRenderer/renderPerBaseLettering.js +1 -3
  62. package/dist/PileupRenderer/renderPerBaseQuality.d.ts +2 -1
  63. package/dist/PileupRenderer/renderPerBaseQuality.js +1 -3
  64. package/dist/PileupRenderer/renderSoftClipping.js +6 -6
  65. package/dist/PileupRenderer/sortUtil.d.ts +2 -7
  66. package/dist/PileupRenderer/sortUtil.js +13 -13
  67. package/dist/SNPCoverageAdapter/SNPCoverageAdapter.js +10 -5
  68. package/dist/SNPCoverageAdapter/generateCoverageBins.d.ts +13 -9
  69. package/dist/SNPCoverageAdapter/generateCoverageBins.js +269 -166
  70. package/dist/SNPCoverageRenderer/SNPCoverageRenderer.d.ts +2 -1
  71. package/dist/SNPCoverageRenderer/SNPCoverageRenderer.js +171 -54
  72. package/dist/shared/color.d.ts +0 -10
  73. package/dist/shared/color.js +1 -7
  74. package/{esm/shared → dist/shared/components}/BaseDisplayComponent.d.ts +2 -2
  75. package/{esm/shared → dist/shared/components}/FilterByTagDialog.d.ts +3 -3
  76. package/dist/shared/{FilterByTagDialog.js → components/FilterByTagDialog.js} +5 -1
  77. package/dist/shared/fetchChains.js +1 -2
  78. package/dist/shared/getMaximumModificationAtEachPosition.d.ts +8 -0
  79. package/dist/shared/getMaximumModificationAtEachPosition.js +42 -0
  80. package/dist/shared/getUniqueModifications.d.ts +14 -0
  81. package/dist/shared/getUniqueModifications.js +16 -0
  82. package/dist/shared/getUniqueTags.d.ts +15 -0
  83. package/dist/shared/getUniqueTags.js +18 -0
  84. package/dist/shared/types.d.ts +94 -0
  85. package/dist/shared/util.d.ts +8 -0
  86. package/dist/shared/util.js +26 -0
  87. package/dist/util.d.ts +6 -3
  88. package/dist/util.js +24 -29
  89. package/esm/AlignmentsFeatureDetail/AlignmentsFeatureDetail.js +1 -2
  90. package/esm/AlignmentsFeatureDetail/getSAFeatures.js +2 -2
  91. package/esm/AlignmentsFeatureDetail/stateModelFactory.d.ts +1 -1
  92. package/esm/BamAdapter/BamAdapter.d.ts +3 -2
  93. package/esm/BamAdapter/BamAdapter.js +31 -8
  94. package/esm/BamAdapter/BamSlightlyLazyFeature.d.ts +3 -17
  95. package/esm/BamAdapter/BamSlightlyLazyFeature.js +43 -73
  96. package/esm/CramAdapter/CramAdapter.d.ts +4 -3
  97. package/esm/CramAdapter/CramAdapter.js +22 -5
  98. package/esm/CramAdapter/CramSlightlyLazyFeature.d.ts +21 -27
  99. package/esm/CramAdapter/CramSlightlyLazyFeature.js +74 -73
  100. package/esm/CramAdapter/util.d.ts +1 -10
  101. package/esm/LinearAlignmentsDisplay/components/AlignmentsDisplay.d.ts +1 -1
  102. package/esm/LinearAlignmentsDisplay/index.js +2 -2
  103. package/esm/LinearAlignmentsDisplay/{models/model.d.ts → model.d.ts} +6 -3
  104. package/esm/LinearAlignmentsDisplay/{models/model.js → model.js} +11 -7
  105. package/esm/LinearPileupDisplay/SharedLinearPileupDisplayMixin.d.ts +6 -27
  106. package/esm/LinearPileupDisplay/SharedLinearPileupDisplayMixin.js +45 -23
  107. package/esm/LinearPileupDisplay/components/ColorByTagDialog.d.ts +5 -4
  108. package/esm/LinearPileupDisplay/components/ColorByTagDialog.js +3 -1
  109. package/esm/LinearPileupDisplay/components/GroupByDialog.js +8 -6
  110. package/esm/LinearPileupDisplay/components/SortByTagDialog.js +6 -4
  111. package/esm/LinearPileupDisplay/model.d.ts +40 -40
  112. package/esm/LinearPileupDisplay/model.js +119 -42
  113. package/esm/LinearReadArcsDisplay/components/ReactComponent.js +1 -1
  114. package/esm/LinearReadArcsDisplay/model.d.ts +22 -21
  115. package/esm/LinearReadArcsDisplay/model.js +14 -15
  116. package/esm/LinearReadCloudDisplay/components/ReactComponent.js +1 -1
  117. package/esm/LinearReadCloudDisplay/model.d.ts +14 -22
  118. package/esm/LinearReadCloudDisplay/model.js +13 -14
  119. package/esm/LinearSNPCoverageDisplay/components/Tooltip.js +49 -19
  120. package/esm/LinearSNPCoverageDisplay/index.js +3 -2
  121. package/esm/LinearSNPCoverageDisplay/{models/model.d.ts → model.d.ts} +3 -13
  122. package/esm/LinearSNPCoverageDisplay/{models/model.js → model.js} +72 -46
  123. package/esm/MismatchParser/cigarToMismatches.d.ts +3 -0
  124. package/esm/MismatchParser/cigarToMismatches.js +91 -0
  125. package/esm/MismatchParser/getNextRefPos.d.ts +4 -0
  126. package/esm/MismatchParser/getNextRefPos.js +37 -0
  127. package/esm/MismatchParser/index.d.ts +4 -29
  128. package/esm/MismatchParser/index.js +5 -317
  129. package/esm/MismatchParser/mdToMismatches.d.ts +3 -0
  130. package/esm/MismatchParser/mdToMismatches.js +77 -0
  131. package/esm/ModificationParser/index.d.ts +19 -0
  132. package/esm/ModificationParser/index.js +138 -0
  133. package/esm/PileupRPC/methods/GetGlobalValueForTag.js +1 -2
  134. package/esm/PileupRPC/methods/GetReducedFeatures.d.ts +1 -1
  135. package/esm/PileupRPC/methods/GetReducedFeatures.js +19 -16
  136. package/esm/PileupRPC/methods/GetVisibleModifications.d.ts +2 -1
  137. package/esm/PileupRPC/methods/GetVisibleModifications.js +9 -6
  138. package/esm/PileupRenderer/PileupLayoutSession.d.ts +8 -7
  139. package/esm/PileupRenderer/PileupRenderer.d.ts +6 -14
  140. package/esm/PileupRenderer/PileupRenderer.js +8 -6
  141. package/esm/PileupRenderer/renderAlignment.js +17 -4
  142. package/esm/PileupRenderer/renderAlignmentShape.js +102 -21
  143. package/esm/PileupRenderer/renderMethylation.d.ts +2 -1
  144. package/esm/PileupRenderer/renderMethylation.js +17 -9
  145. package/esm/PileupRenderer/renderMismatches.js +19 -19
  146. package/esm/PileupRenderer/renderModifications.d.ts +3 -2
  147. package/esm/PileupRenderer/renderModifications.js +30 -33
  148. package/esm/PileupRenderer/renderPerBaseLettering.d.ts +2 -1
  149. package/esm/PileupRenderer/renderPerBaseLettering.js +1 -3
  150. package/esm/PileupRenderer/renderPerBaseQuality.d.ts +2 -1
  151. package/esm/PileupRenderer/renderPerBaseQuality.js +1 -3
  152. package/esm/PileupRenderer/renderSoftClipping.js +6 -6
  153. package/esm/PileupRenderer/sortUtil.d.ts +2 -7
  154. package/esm/PileupRenderer/sortUtil.js +13 -13
  155. package/esm/SNPCoverageAdapter/SNPCoverageAdapter.js +10 -5
  156. package/esm/SNPCoverageAdapter/generateCoverageBins.d.ts +13 -9
  157. package/esm/SNPCoverageAdapter/generateCoverageBins.js +269 -166
  158. package/esm/SNPCoverageRenderer/SNPCoverageRenderer.d.ts +2 -1
  159. package/esm/SNPCoverageRenderer/SNPCoverageRenderer.js +171 -54
  160. package/esm/shared/color.d.ts +0 -10
  161. package/esm/shared/color.js +0 -6
  162. package/{dist/shared → esm/shared/components}/BaseDisplayComponent.d.ts +2 -2
  163. package/{dist/shared → esm/shared/components}/FilterByTagDialog.d.ts +3 -3
  164. package/esm/shared/{FilterByTagDialog.js → components/FilterByTagDialog.js} +5 -1
  165. package/esm/shared/fetchChains.js +1 -2
  166. package/esm/shared/getMaximumModificationAtEachPosition.d.ts +8 -0
  167. package/esm/shared/getMaximumModificationAtEachPosition.js +39 -0
  168. package/esm/shared/getUniqueModifications.d.ts +14 -0
  169. package/esm/shared/getUniqueModifications.js +13 -0
  170. package/esm/shared/getUniqueTags.d.ts +15 -0
  171. package/esm/shared/getUniqueTags.js +15 -0
  172. package/esm/shared/types.d.ts +94 -0
  173. package/esm/shared/util.d.ts +8 -0
  174. package/esm/shared/util.js +23 -0
  175. package/esm/util.d.ts +6 -3
  176. package/esm/util.js +22 -26
  177. package/package.json +4 -4
  178. package/dist/LinearPileupDisplay/components/ColorByModificationsDialog.d.ts +0 -15
  179. package/dist/LinearPileupDisplay/components/ColorByModificationsDialog.js +0 -41
  180. package/dist/LinearPileupDisplay/components/ModificationsTable.d.ts +0 -4
  181. package/dist/LinearPileupDisplay/components/ModificationsTable.js +0 -28
  182. package/dist/SNPCoverageAdapter/util.d.ts +0 -25
  183. package/dist/shared/index.d.ts +0 -49
  184. package/dist/shared/index.js +0 -41
  185. package/esm/LinearPileupDisplay/components/ColorByModificationsDialog.d.ts +0 -15
  186. package/esm/LinearPileupDisplay/components/ColorByModificationsDialog.js +0 -36
  187. package/esm/LinearPileupDisplay/components/ModificationsTable.d.ts +0 -4
  188. package/esm/LinearPileupDisplay/components/ModificationsTable.js +0 -22
  189. package/esm/SNPCoverageAdapter/util.d.ts +0 -25
  190. package/esm/shared/index.d.ts +0 -49
  191. package/esm/shared/index.js +0 -36
  192. /package/dist/LinearAlignmentsDisplay/{models/alignmentsModel.d.ts → alignmentsModel.d.ts} +0 -0
  193. /package/dist/LinearAlignmentsDisplay/{models/alignmentsModel.js → alignmentsModel.js} +0 -0
  194. /package/dist/LinearAlignmentsDisplay/{models/configSchema.d.ts → configSchema.d.ts} +0 -0
  195. /package/dist/LinearAlignmentsDisplay/{models/configSchema.js → configSchema.js} +0 -0
  196. /package/dist/LinearAlignmentsDisplay/{models/util.d.ts → util.d.ts} +0 -0
  197. /package/dist/LinearAlignmentsDisplay/{models/util.js → util.js} +0 -0
  198. /package/dist/LinearSNPCoverageDisplay/{models/configSchema.d.ts → configSchema.d.ts} +0 -0
  199. /package/dist/LinearSNPCoverageDisplay/{models/configSchema.js → configSchema.js} +0 -0
  200. /package/dist/shared/{BaseDisplayComponent.js → components/BaseDisplayComponent.js} +0 -0
  201. /package/dist/shared/{renderSvg.d.ts → renderSvgUtil.d.ts} +0 -0
  202. /package/dist/shared/{renderSvg.js → renderSvgUtil.js} +0 -0
  203. /package/dist/{SNPCoverageAdapter/util.js → shared/types.js} +0 -0
  204. /package/esm/LinearAlignmentsDisplay/{models/alignmentsModel.d.ts → alignmentsModel.d.ts} +0 -0
  205. /package/esm/LinearAlignmentsDisplay/{models/alignmentsModel.js → alignmentsModel.js} +0 -0
  206. /package/esm/LinearAlignmentsDisplay/{models/configSchema.d.ts → configSchema.d.ts} +0 -0
  207. /package/esm/LinearAlignmentsDisplay/{models/configSchema.js → configSchema.js} +0 -0
  208. /package/esm/LinearAlignmentsDisplay/{models/util.d.ts → util.d.ts} +0 -0
  209. /package/esm/LinearAlignmentsDisplay/{models/util.js → util.js} +0 -0
  210. /package/esm/LinearSNPCoverageDisplay/{models/configSchema.d.ts → configSchema.d.ts} +0 -0
  211. /package/esm/LinearSNPCoverageDisplay/{models/configSchema.js → configSchema.js} +0 -0
  212. /package/esm/shared/{BaseDisplayComponent.js → components/BaseDisplayComponent.js} +0 -0
  213. /package/esm/shared/{renderSvg.d.ts → renderSvgUtil.d.ts} +0 -0
  214. /package/esm/shared/{renderSvg.js → renderSvgUtil.js} +0 -0
  215. /package/esm/{SNPCoverageAdapter/util.js → shared/types.js} +0 -0
@@ -1,4 +1,5 @@
1
1
  import { readFeaturesToCIGAR, readFeaturesToMismatches } from './util';
2
+ import { cacheGetter } from '../shared/util';
2
3
  export default class CramSlightlyLazyFeature {
3
4
  // uses parameter properties to automatically create fields on the class
4
5
  // https://www.typescriptlang.org/docs/handbook/classes.html#parameter-properties
@@ -6,98 +7,80 @@ export default class CramSlightlyLazyFeature {
6
7
  this.record = record;
7
8
  this._store = _store;
8
9
  }
9
- _get_name() {
10
+ get name() {
10
11
  return this.record.readName;
11
12
  }
12
- _get_start() {
13
+ get start() {
13
14
  return this.record.alignmentStart - 1;
14
15
  }
15
- _get_end() {
16
+ get end() {
16
17
  var _a;
17
- return this.record.alignmentStart + ((_a = this.record.lengthOnRef) !== null && _a !== void 0 ? _a : 1) - 1;
18
+ return this.start + ((_a = this.record.lengthOnRef) !== null && _a !== void 0 ? _a : 1);
18
19
  }
19
- _get_cram_read_features() {
20
- return this.record.readFeatures;
21
- }
22
- _get_type() {
23
- return 'match';
24
- }
25
- _get_score() {
20
+ get score() {
26
21
  return this.record.mappingQuality;
27
22
  }
28
- _get_flags() {
23
+ get flags() {
29
24
  return this.record.flags;
30
25
  }
31
- _get_strand() {
26
+ get strand() {
32
27
  return this.record.isReverseComplemented() ? -1 : 1;
33
28
  }
34
- _read_group_id() {
35
- var _a;
36
- return (_a = this._store.samHeader.readGroups) === null || _a === void 0 ? void 0 : _a[this.record.readGroupId];
37
- }
38
- _get_qual() {
29
+ get qual() {
39
30
  return (this.record.qualityScores || []).join(' ');
40
31
  }
41
- qualRaw() {
32
+ get qualRaw() {
42
33
  return this.record.qualityScores;
43
34
  }
44
- _get_refName() {
35
+ get refName() {
45
36
  return this._store.refIdToName(this.record.sequenceId);
46
37
  }
47
- _get_is_paired() {
48
- return !!this.record.mate;
49
- }
50
- _get_pair_orientation() {
38
+ get pair_orientation() {
51
39
  return this.record.isPaired() ? this.record.getPairOrientation() : undefined;
52
40
  }
53
- _get_template_length() {
41
+ get template_length() {
54
42
  return this.record.templateLength || this.record.templateSize;
55
43
  }
56
- _get_next_ref() {
44
+ get next_ref() {
57
45
  return this.record.mate
58
46
  ? this._store.refIdToName(this.record.mate.sequenceId)
59
47
  : undefined;
60
48
  }
61
- _get_next_segment_position() {
49
+ get next_segment_position() {
62
50
  return this.record.mate
63
51
  ? `${this._store.refIdToName(this.record.mate.sequenceId)}:${this.record.mate.alignmentStart}`
64
52
  : undefined;
65
53
  }
66
- _get_next_pos() {
54
+ get is_paired() {
55
+ return !!this.record.mate;
56
+ }
57
+ get next_pos() {
67
58
  var _a;
68
59
  return (_a = this.record.mate) === null || _a === void 0 ? void 0 : _a.alignmentStart;
69
60
  }
70
- _get_tags() {
71
- const RG = this._read_group_id();
72
- const { tags } = this.record;
73
- // avoids a tag copy if no RG, but just copy if there is one
74
- return RG !== undefined ? { ...tags, RG } : tags;
61
+ get tags() {
62
+ var _a;
63
+ const RG = (_a = this._store.samHeader.readGroups) === null || _a === void 0 ? void 0 : _a[this.record.readGroupId];
64
+ return RG !== undefined ? { ...this.record.tags, RG } : this.record.tags;
75
65
  }
76
- _get_seq() {
66
+ get seq() {
77
67
  return this.record.getReadBases();
78
68
  }
79
69
  // generate a CIGAR, based on code from jkbonfield
80
- _get_CIGAR() {
70
+ get CIGAR() {
81
71
  return readFeaturesToCIGAR(this.record.readFeatures, this.record.alignmentStart, this.record.readLength, this.record._refRegion);
82
72
  }
83
- tags() {
84
- return Object.getOwnPropertyNames(CramSlightlyLazyFeature.prototype)
85
- .filter(prop => prop.startsWith('_get_') &&
86
- prop !== '_get_mismatches' &&
87
- prop !== '_get_cram_read_features')
88
- .map(methodName => methodName.replace('_get_', ''));
89
- }
90
73
  id() {
91
74
  return `${this._store.id}-${this.record.uniqueId}`;
92
75
  }
93
76
  get(field) {
94
- const methodName = `_get_${field}`;
95
- // @ts-expect-error
96
- if (this[methodName]) {
97
- // @ts-expect-error
98
- return this[methodName]();
99
- }
100
- return undefined;
77
+ return field === 'mismatches'
78
+ ? this.mismatches
79
+ : field === 'qual'
80
+ ? this.qual
81
+ : field === 'CIGAR'
82
+ ? this.CIGAR
83
+ : this.fields[field];
101
84
  }
102
85
  parent() {
103
86
  return undefined;
@@ -105,33 +88,51 @@ export default class CramSlightlyLazyFeature {
105
88
  children() {
106
89
  return undefined;
107
90
  }
108
- set() { }
109
- pairedFeature() {
110
- return false;
111
- }
112
- _get_clipPos() {
113
- const mismatches = this.get('mismatches');
114
- if (mismatches.length) {
115
- const record = this.get('strand') === -1 ? mismatches.at(-1) : mismatches[0];
116
- const { type, cliplen } = record;
117
- if (type === 'softclip' || type === 'hardclip') {
118
- return cliplen;
119
- }
120
- }
121
- return 0;
122
- }
123
- toJSON() {
91
+ get mismatches() {
92
+ return readFeaturesToMismatches(this.record.readFeatures, this.start, this.qualRaw);
93
+ // this commented code can try to resolve MD tags, xref https://github.com/galaxyproject/tools-iuc/issues/6523#issuecomment-2462927211 but put on hold
94
+ // return this.tags.MD && this.seq
95
+ // ? mismatches.concat(
96
+ // mdToMismatches(
97
+ // this.tags.MD,
98
+ // parseCigar(this.CIGAR),
99
+ // mismatches,
100
+ // this.seq,
101
+ // this.qualRaw,
102
+ // ),
103
+ // )
104
+ // : mismatches
105
+ }
106
+ get fields() {
124
107
  return {
125
- ...Object.fromEntries(this.tags()
126
- .map(t => [t, this.get(t)])
127
- .filter(elt => elt[1] !== undefined)),
108
+ start: this.start,
109
+ name: this.name,
110
+ end: this.end,
111
+ score: this.score,
112
+ strand: this.strand,
113
+ template_length: this.template_length,
114
+ flags: this.flags,
115
+ tags: this.tags,
116
+ refName: this.refName,
117
+ seq: this.seq,
118
+ type: 'match',
119
+ pair_orientation: this.pair_orientation,
120
+ next_ref: this.next_ref,
121
+ next_pos: this.next_pos,
122
+ next_segment_position: this.next_segment_position,
128
123
  uniqueId: this.id(),
129
124
  };
130
125
  }
131
- _get_mismatches() {
132
- const readFeatures = this.record.readFeatures;
133
- const qual = this.qualRaw();
134
- const start = this.get('start');
135
- return readFeaturesToMismatches(readFeatures, start, qual);
126
+ toJSON() {
127
+ return {
128
+ ...this.fields,
129
+ // lazy
130
+ CIGAR: this.CIGAR,
131
+ // lazy
132
+ qual: this.qual,
133
+ };
136
134
  }
137
135
  }
136
+ cacheGetter(CramSlightlyLazyFeature, 'fields');
137
+ cacheGetter(CramSlightlyLazyFeature, 'CIGAR');
138
+ cacheGetter(CramSlightlyLazyFeature, 'mismatches');
@@ -1,15 +1,6 @@
1
1
  import { CramRecord } from '@gmod/cram';
2
+ import { Mismatch } from '../shared/types';
2
3
  type ReadFeatures = CramRecord['readFeatures'];
3
- export interface Mismatch {
4
- qual?: number;
5
- start: number;
6
- length: number;
7
- type: string;
8
- base: string | undefined;
9
- altbase?: string;
10
- seq?: string;
11
- cliplen?: number;
12
- }
13
4
  export declare function readFeaturesToMismatches(readFeatures: ReadFeatures, start: number, qual?: number[] | null): Mismatch[];
14
5
  export declare function readFeaturesToCIGAR(readFeatures: ReadFeatures, alignmentStart: number, readLen: number, refRegion?: {
15
6
  seq: string;
@@ -1,5 +1,5 @@
1
1
  import React from 'react';
2
- import { LinearAlignmentsDisplayModel } from '../models/model';
2
+ import { LinearAlignmentsDisplayModel } from '../model';
3
3
  declare const AlignmentsDisplay: ({ model, }: {
4
4
  model: LinearAlignmentsDisplayModel;
5
5
  }) => React.JSX.Element | null;
@@ -1,7 +1,7 @@
1
1
  import DisplayType from '@jbrowse/core/pluggableElementTypes/DisplayType';
2
2
  // locals
3
- import configSchemaFactory from './models/configSchema';
4
- import modelFactory from './models/model';
3
+ import configSchemaFactory from './configSchema';
4
+ import modelFactory from './model';
5
5
  import ReactComponent from './components/AlignmentsDisplay';
6
6
  export default function LinearAlignmentsDisplayF(pluginManager) {
7
7
  pluginManager.addDisplayType(() => {
@@ -1,10 +1,10 @@
1
1
  import React from 'react';
2
- import { Instance, IStateTreeNode } from 'mobx-state-tree';
2
+ import { Instance } from 'mobx-state-tree';
3
3
  import { AnyConfigurationModel, AnyConfigurationSchemaType } from '@jbrowse/core/configuration';
4
4
  import PluginManager from '@jbrowse/core/PluginManager';
5
5
  import { MenuItem } from '@jbrowse/core/ui';
6
6
  import { FeatureDensityStats } from '@jbrowse/core/data_adapters/BaseAdapter';
7
- import { IFilter } from '../../shared';
7
+ import { FilterBy } from '../shared/types';
8
8
  /**
9
9
  * #stateModel LinearAlignmentsDisplay
10
10
  * extends
@@ -83,6 +83,9 @@ declare function stateModelFactory(pluginManager: PluginManager, configSchema: A
83
83
  setRpcDriverName(rpcDriverName: string): void;
84
84
  reload(): void;
85
85
  } & {
86
+ /**
87
+ * #volatile
88
+ */
86
89
  scrollTop: number;
87
90
  } & {
88
91
  /**
@@ -151,7 +154,7 @@ declare function stateModelFactory(pluginManager: PluginManager, configSchema: A
151
154
  /**
152
155
  * #action
153
156
  */
154
- setFilterBy(filter: IFilter): void;
157
+ setFilterBy(filter: FilterBy): void;
155
158
  /**
156
159
  * #action
157
160
  */
@@ -9,9 +9,6 @@ import { BaseDisplay } from '@jbrowse/core/pluggableElementTypes/models';
9
9
  import { LinearAlignmentsDisplayMixin } from './alignmentsModel';
10
10
  import { getLowerPanelDisplays } from './util';
11
11
  const minDisplayHeight = 20;
12
- function deepSnap(x1, x2) {
13
- return deepEqual(x1 ? getSnapshot(x1) : undefined, x2 ? getSnapshot(x2) : undefined);
14
- }
15
12
  function preCheck(self) {
16
13
  const { PileupDisplay, SNPCoverageDisplay } = self;
17
14
  return (PileupDisplay ||
@@ -24,8 +21,10 @@ function propagateColorBy(self) {
24
21
  if (!preCheck(self) || !PileupDisplay.colorBy) {
25
22
  return;
26
23
  }
27
- if (!deepSnap(PileupDisplay.colorBy, SNPCoverageDisplay.colorBy)) {
28
- SNPCoverageDisplay.setColorBy(getSnapshot(PileupDisplay.colorBy));
24
+ if (!deepEqual(PileupDisplay.colorBy, SNPCoverageDisplay.colorBy)) {
25
+ SNPCoverageDisplay.setColorScheme({
26
+ ...PileupDisplay.colorBy,
27
+ });
29
28
  }
30
29
  }
31
30
  function propagateFilterBy(self) {
@@ -33,8 +32,10 @@ function propagateFilterBy(self) {
33
32
  if (!preCheck(self) || !PileupDisplay.filterBy) {
34
33
  return;
35
34
  }
36
- if (!deepSnap(PileupDisplay.filterBy, SNPCoverageDisplay.filterBy)) {
37
- SNPCoverageDisplay.setFilterBy(getSnapshot(PileupDisplay.filterBy));
35
+ if (!deepEqual(PileupDisplay.filterBy, SNPCoverageDisplay.filterBy)) {
36
+ SNPCoverageDisplay.setFilterBy({
37
+ ...PileupDisplay.filterBy,
38
+ });
38
39
  }
39
40
  }
40
41
  /**
@@ -47,6 +48,9 @@ function stateModelFactory(pluginManager, configSchema) {
47
48
  return types
48
49
  .compose('LinearAlignmentsDisplay', BaseDisplay, LinearAlignmentsDisplayMixin(pluginManager, configSchema))
49
50
  .volatile(() => ({
51
+ /**
52
+ * #volatile
53
+ */
50
54
  scrollTop: 0,
51
55
  }))
52
56
  .actions(self => ({
@@ -2,8 +2,7 @@ import { AnyConfigurationModel, AnyConfigurationSchemaType } from '@jbrowse/core
2
2
  import SerializableFilterChain from '@jbrowse/core/pluggableElementTypes/renderers/util/serializableFilterChain';
3
3
  import { Feature } from '@jbrowse/core/util';
4
4
  import { ContentCopy as ContentCopyIcon } from '@jbrowse/core/ui/Icons';
5
- import { IFilter } from '../shared';
6
- import { ExtraColorBy } from '../shared/color';
5
+ import { ColorBy, FilterBy } from '../shared/types';
7
6
  /**
8
7
  * #stateModel SharedLinearPileupDisplayMixin
9
8
  * #category display
@@ -124,23 +123,11 @@ export declare function SharedLinearPileupDisplayMixin(configSchema: AnyConfigur
124
123
  /**
125
124
  * #property
126
125
  */
127
- colorBy: import("mobx-state-tree").IMaybe<import("mobx-state-tree").IModelType<{
128
- type: import("mobx-state-tree").ISimpleType<string>;
129
- tag: import("mobx-state-tree").IMaybe<import("mobx-state-tree").ISimpleType<string>>;
130
- extra: import("mobx-state-tree").IType<any, any, any>;
131
- }, {}, import("mobx-state-tree")._NotCustomized, import("mobx-state-tree")._NotCustomized>>;
126
+ colorBy: import("mobx-state-tree").IType<ColorBy | undefined, ColorBy | undefined, ColorBy | undefined>;
132
127
  /**
133
128
  * #property
134
129
  */
135
- filterBy: import("mobx-state-tree").IOptionalIType<import("mobx-state-tree").IModelType<{
136
- flagInclude: import("mobx-state-tree").IOptionalIType<import("mobx-state-tree").ISimpleType<number>, [undefined]>;
137
- flagExclude: import("mobx-state-tree").IOptionalIType<import("mobx-state-tree").ISimpleType<number>, [undefined]>;
138
- readName: import("mobx-state-tree").IMaybe<import("mobx-state-tree").ISimpleType<string>>;
139
- tagFilter: import("mobx-state-tree").IMaybe<import("mobx-state-tree").IModelType<{
140
- tag: import("mobx-state-tree").ISimpleType<string>;
141
- value: import("mobx-state-tree").IMaybe<import("mobx-state-tree").ISimpleType<string>>;
142
- }, {}, import("mobx-state-tree")._NotCustomized, import("mobx-state-tree")._NotCustomized>>;
143
- }, {}, import("mobx-state-tree")._NotCustomized, import("mobx-state-tree")._NotCustomized>, [undefined]>;
130
+ filterBy: import("mobx-state-tree").IOptionalIType<import("mobx-state-tree").IType<FilterBy, FilterBy, FilterBy>, [undefined]>;
144
131
  /**
145
132
  * #property
146
133
  */
@@ -296,11 +283,7 @@ export declare function SharedLinearPileupDisplayMixin(configSchema: AnyConfigur
296
283
  /**
297
284
  * #action
298
285
  */
299
- setColorScheme(colorScheme: {
300
- type: string;
301
- tag?: string;
302
- extra?: ExtraColorBy;
303
- }): void;
286
+ setColorScheme(colorScheme: ColorBy): void;
304
287
  /**
305
288
  * #action
306
289
  */
@@ -325,7 +308,7 @@ export declare function SharedLinearPileupDisplayMixin(configSchema: AnyConfigur
325
308
  /**
326
309
  * #action
327
310
  */
328
- setFilterBy(filter: IFilter): void;
311
+ setFilterBy(filter: FilterBy): void;
329
312
  /**
330
313
  * #action
331
314
  */
@@ -343,11 +326,7 @@ export declare function SharedLinearPileupDisplayMixin(configSchema: AnyConfigur
343
326
  setSubschema(slotName: string, data: Record<string, unknown>): Record<string, unknown> | ({
344
327
  [x: string]: any;
345
328
  } & import("mobx-state-tree/dist/internal").NonEmptyObject & any & import("mobx-state-tree").IStateTreeNode<AnyConfigurationSchemaType>);
346
- } & import("mobx-state-tree" /**
347
- * #stateModel SharedLinearPileupDisplayMixin
348
- * #category display
349
- * extends `BaseLinearDisplay`
350
- */).IStateTreeNode<AnyConfigurationSchemaType>);
329
+ } & import("mobx-state-tree").IStateTreeNode<AnyConfigurationSchemaType>);
351
330
  } & import("mobx-state-tree").IStateTreeNode<AnyConfigurationSchemaType>;
352
331
  } & {
353
332
  /**
@@ -1,11 +1,11 @@
1
1
  import { lazy } from 'react';
2
2
  import { autorun, observable } from 'mobx';
3
- import { cast, types, addDisposer, getSnapshot } from 'mobx-state-tree';
3
+ import { cast, types, addDisposer, isAlive } from 'mobx-state-tree';
4
4
  import copy from 'copy-to-clipboard';
5
5
  import { ConfigurationReference, readConfObject, getConf, } from '@jbrowse/core/configuration';
6
6
  import SerializableFilterChain from '@jbrowse/core/pluggableElementTypes/renderers/util/serializableFilterChain';
7
7
  import { getRpcSessionId } from '@jbrowse/core/util/tracks';
8
- import { getEnv, getSession, isSessionModelWithWidgets, getContainingView, SimpleFeature, getContainingTrack, } from '@jbrowse/core/util';
8
+ import { getEnv, getSession, getContainingView, getContainingTrack, isSessionModelWithWidgets, SimpleFeature, } from '@jbrowse/core/util';
9
9
  import { BaseLinearDisplay, } from '@jbrowse/plugin-linear-genome-view';
10
10
  // icons
11
11
  import { ContentCopy as ContentCopyIcon } from '@jbrowse/core/ui/Icons';
@@ -13,11 +13,11 @@ import MenuOpenIcon from '@mui/icons-material/MenuOpen';
13
13
  import FilterListIcon from '@mui/icons-material/ClearAll';
14
14
  // locals
15
15
  import LinearPileupDisplayBlurb from './components/LinearPileupDisplayBlurb';
16
- import { getUniqueTagValues, FilterModel } from '../shared';
17
16
  import { createAutorun } from '../util';
18
- import { ColorByModel } from '../shared/color';
17
+ import { getUniqueTags } from '../shared/getUniqueTags';
18
+ import { defaultFilterFlags } from '../shared/util';
19
19
  // lazies
20
- const FilterByTagDialog = lazy(() => import('../shared/FilterByTagDialog'));
20
+ const FilterByTagDialog = lazy(() => import('../shared/components/FilterByTagDialog'));
21
21
  const ColorByTagDialog = lazy(() => import('./components/ColorByTagDialog'));
22
22
  const SetFeatureHeightDialog = lazy(() => import('./components/SetFeatureHeightDialog'));
23
23
  const SetMaxHeightDialog = lazy(() => import('./components/SetMaxHeightDialog'));
@@ -57,11 +57,11 @@ export function SharedLinearPileupDisplayMixin(configSchema) {
57
57
  /**
58
58
  * #property
59
59
  */
60
- colorBy: ColorByModel,
60
+ colorBy: types.frozen(),
61
61
  /**
62
62
  * #property
63
63
  */
64
- filterBy: types.optional(FilterModel, {}),
64
+ filterBy: types.optional(types.frozen(), defaultFilterFlags),
65
65
  /**
66
66
  * #property
67
67
  */
@@ -109,8 +109,10 @@ export function SharedLinearPileupDisplayMixin(configSchema) {
109
109
  * #action
110
110
  */
111
111
  setColorScheme(colorScheme) {
112
- self.colorTagMap = observable.map({}); // clear existing mapping
113
- self.colorBy = cast(colorScheme);
112
+ self.colorTagMap = observable.map({});
113
+ self.colorBy = {
114
+ ...colorScheme,
115
+ };
114
116
  if (colorScheme.tag) {
115
117
  self.tagsReady = false;
116
118
  }
@@ -182,7 +184,9 @@ export function SharedLinearPileupDisplayMixin(configSchema) {
182
184
  * #action
183
185
  */
184
186
  setFilterBy(filter) {
185
- self.filterBy = cast(filter);
187
+ self.filterBy = {
188
+ ...filter,
189
+ };
186
190
  },
187
191
  /**
188
192
  * #action
@@ -296,8 +300,8 @@ export function SharedLinearPileupDisplayMixin(configSchema) {
296
300
  notReady: superProps.notReady || !self.renderReady(),
297
301
  rpcDriverName,
298
302
  displayModel: self,
299
- colorBy: colorBy ? getSnapshot(colorBy) : undefined,
300
- filterBy: JSON.parse(JSON.stringify(filterBy)),
303
+ colorBy,
304
+ filterBy,
301
305
  filters: self.filters,
302
306
  colorTagMap: Object.fromEntries(colorTagMap.toJSON()),
303
307
  config: self.rendererConfig,
@@ -317,7 +321,7 @@ export function SharedLinearPileupDisplayMixin(configSchema) {
317
321
  layoutId: getContainingView(self).id,
318
322
  rendererType: 'PileupRenderer',
319
323
  }));
320
- if (feature) {
324
+ if (isAlive(self) && feature) {
321
325
  self.selectFeature(new SimpleFeature(feature));
322
326
  }
323
327
  }
@@ -367,37 +371,49 @@ export function SharedLinearPileupDisplayMixin(configSchema) {
367
371
  {
368
372
  label: 'Normal',
369
373
  onClick: () => {
370
- self.setColorScheme({ type: 'normal' });
374
+ self.setColorScheme({
375
+ type: 'normal',
376
+ });
371
377
  },
372
378
  },
373
379
  {
374
380
  label: 'Mapping quality',
375
381
  onClick: () => {
376
- self.setColorScheme({ type: 'mappingQuality' });
382
+ self.setColorScheme({
383
+ type: 'mappingQuality',
384
+ });
377
385
  },
378
386
  },
379
387
  {
380
388
  label: 'Strand',
381
389
  onClick: () => {
382
- self.setColorScheme({ type: 'strand' });
390
+ self.setColorScheme({
391
+ type: 'strand',
392
+ });
383
393
  },
384
394
  },
385
395
  {
386
396
  label: 'Per-base quality',
387
397
  onClick: () => {
388
- self.setColorScheme({ type: 'perBaseQuality' });
398
+ self.setColorScheme({
399
+ type: 'perBaseQuality',
400
+ });
389
401
  },
390
402
  },
391
403
  {
392
404
  label: 'Per-base lettering',
393
405
  onClick: () => {
394
- self.setColorScheme({ type: 'perBaseLettering' });
406
+ self.setColorScheme({
407
+ type: 'perBaseLettering',
408
+ });
395
409
  },
396
410
  },
397
411
  {
398
412
  label: 'First-of-pair strand',
399
413
  onClick: () => {
400
- self.setColorScheme({ type: 'stranded' });
414
+ self.setColorScheme({
415
+ type: 'stranded',
416
+ });
401
417
  },
402
418
  },
403
419
  {
@@ -497,14 +513,19 @@ export function SharedLinearPileupDisplayMixin(configSchema) {
497
513
  const { colorBy, tagsReady } = self;
498
514
  const { staticBlocks } = view;
499
515
  if ((colorBy === null || colorBy === void 0 ? void 0 : colorBy.tag) && !tagsReady) {
500
- const vals = await getUniqueTagValues({
516
+ const vals = await getUniqueTags({
501
517
  self,
502
518
  tag: colorBy.tag,
503
519
  blocks: staticBlocks,
504
520
  });
505
- self.updateColorTagMap(vals);
521
+ if (isAlive(self)) {
522
+ self.updateColorTagMap(vals);
523
+ self.setTagsReady(true);
524
+ }
525
+ }
526
+ else {
527
+ self.setTagsReady(true);
506
528
  }
507
- self.setTagsReady(true);
508
529
  }, { delay: 1000 });
509
530
  // autorun synchronizes featureUnderMouse with featureIdUnderMouse
510
531
  // asynchronously. this is needed due to how we do not serialize all
@@ -531,7 +552,8 @@ export function SharedLinearPileupDisplayMixin(configSchema) {
531
552
  // feature.id that was returned e.g. that the user hasn't
532
553
  // moused over to a new position during the async operation
533
554
  // above
534
- if (feature &&
555
+ if (isAlive(self) &&
556
+ feature &&
535
557
  self.featureIdUnderMouse === feature.uniqueId) {
536
558
  self.setFeatureUnderMouse(new SimpleFeature(feature));
537
559
  }
@@ -1,10 +1,11 @@
1
1
  import React from 'react';
2
+ interface Tag {
3
+ type: string;
4
+ tag: string;
5
+ }
2
6
  declare const ColorByTagDialog: ({ model, handleClose, }: {
3
7
  model: {
4
- setColorScheme: (arg: {
5
- type: string;
6
- tag: string;
7
- }) => void;
8
+ setColorScheme: (arg: Tag) => void;
8
9
  };
9
10
  handleClose: () => void;
10
11
  }) => React.JSX.Element;
@@ -11,7 +11,9 @@ const ColorByTagDialog = observer(function ({ model, handleClose, }) {
11
11
  React.createElement(Typography, { color: "textSecondary" }, "Examples: XS or TS for RNA-seq inferred read strand, ts (lower-case) for minimap2 read strand, HP for haplotype, RG for read group, etc."),
12
12
  React.createElement(TextField, { value: tag, onChange: event => {
13
13
  setTag(event.target.value);
14
- }, placeholder: "Enter tag name", inputProps: { maxLength: 2 }, error: tag.length === 2 && !validTag, helperText: tag.length === 2 && !validTag ? 'Not a valid tag' : '', autoComplete: "off" }),
14
+ }, placeholder: "Enter tag name", error: tag.length === 2 && !validTag, helperText: tag.length === 2 && !validTag ? 'Not a valid tag' : '', autoComplete: "off", slotProps: {
15
+ htmlInput: { maxLength: 2 },
16
+ } }),
15
17
  React.createElement(DialogActions, null,
16
18
  React.createElement(Button, { variant: "contained", color: "primary", onClick: () => {
17
19
  model.setColorScheme({ type: 'tag', tag });
@@ -5,7 +5,7 @@ import { Dialog, ErrorMessage, LoadingEllipses } from '@jbrowse/core/ui';
5
5
  import { getSnapshot } from 'mobx-state-tree';
6
6
  import { getContainingTrack, getContainingView, getSession, useDebounce, } from '@jbrowse/core/util';
7
7
  // locals
8
- import { getUniqueTagValues } from '../../shared';
8
+ import { getUniqueTags } from '../../shared/getUniqueTags';
9
9
  function clone(c) {
10
10
  return JSON.parse(JSON.stringify(c));
11
11
  }
@@ -27,7 +27,7 @@ const GroupByTagDialog = observer(function (props) {
27
27
  if (!isInvalid) {
28
28
  setError(undefined);
29
29
  setLoading(true);
30
- const vals = await getUniqueTagValues({
30
+ const vals = await getUniqueTags({
31
31
  self: model,
32
32
  tag: debouncedTag,
33
33
  blocks: getContainingView(model)
@@ -54,10 +54,12 @@ const GroupByTagDialog = observer(function (props) {
54
54
  } }), label: "Make a new subtrack for undefined values of tag as well?" }),
55
55
  React.createElement(TextField, { value: tag, onChange: event => {
56
56
  setTag(event.target.value);
57
- }, placeholder: "Enter tag name", inputProps: {
58
- maxLength: 2,
59
- 'data-testid': 'group-tag-name-input',
60
- }, error: isInvalid, helperText: isInvalid ? 'Not a valid tag' : '', autoComplete: "off", "data-testid": "group-tag-name" }),
57
+ }, placeholder: "Enter tag name", error: isInvalid, helperText: isInvalid ? 'Not a valid tag' : '', autoComplete: "off", "data-testid": "group-tag-name", slotProps: {
58
+ htmlInput: {
59
+ maxLength: 2,
60
+ 'data-testid': 'group-tag-name-input',
61
+ },
62
+ } }),
61
63
  error ? (React.createElement(ErrorMessage, { error: error })) : loading ? (React.createElement(LoadingEllipses, { title: "Loading unique tags" })) : tagSet ? (React.createElement("div", null,
62
64
  React.createElement("div", null,
63
65
  "Found unique ",
@@ -12,10 +12,12 @@ const SortByTagDialog = observer(function (props) {
12
12
  React.createElement(Typography, { color: "textSecondary" }, "Examples: HP for haplotype, RG for read group, etc."),
13
13
  React.createElement(TextField, { value: tag, onChange: event => {
14
14
  setTag(event.target.value);
15
- }, placeholder: "Enter tag name", inputProps: {
16
- maxLength: 2,
17
- 'data-testid': 'sort-tag-name-input',
18
- }, error: tag.length === 2 && !validTag, helperText: tag.length === 2 && !validTag ? 'Not a valid tag' : '', autoComplete: "off", "data-testid": "sort-tag-name" }),
15
+ }, placeholder: "Enter tag name", error: tag.length === 2 && !validTag, helperText: tag.length === 2 && !validTag ? 'Not a valid tag' : '', autoComplete: "off", "data-testid": "sort-tag-name", slotProps: {
16
+ htmlInput: {
17
+ maxLength: 2,
18
+ 'data-testid': 'sort-tag-name-input',
19
+ },
20
+ } }),
19
21
  React.createElement(DialogActions, null,
20
22
  React.createElement(Button, { variant: "contained", color: "primary", type: "submit", autoFocus: true, onClick: () => {
21
23
  model.setSortedBy('tag', tag);