@jbrowse/plugin-linear-genome-view 4.3.0 → 5.0.0-beta.2

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 (357) hide show
  1. package/esm/FeatureTrack/configSchema.d.ts +104 -65
  2. package/esm/FeatureTrack/configSchema.js +47 -1
  3. package/esm/FeatureTrack/index.js +1 -1
  4. package/esm/LaunchLinearGenomeView/index.d.ts +14 -0
  5. package/esm/LaunchLinearGenomeView/index.js +6 -12
  6. package/esm/LinearGenomeView/afterAttach.d.ts +20 -2
  7. package/esm/LinearGenomeView/afterAttach.js +250 -121
  8. package/esm/LinearGenomeView/components/CenterLine.d.ts +1 -1
  9. package/esm/LinearGenomeView/components/CenterLine.js +16 -7
  10. package/esm/LinearGenomeView/components/ConnectedHoverHighlight.d.ts +7 -0
  11. package/esm/LinearGenomeView/components/ConnectedHoverHighlight.js +22 -0
  12. package/esm/LinearGenomeView/components/CrisprGuidePanel.d.ts +3 -0
  13. package/esm/LinearGenomeView/components/CrisprGuidePanel.js +144 -0
  14. package/esm/LinearGenomeView/components/Cytobands.d.ts +6 -6
  15. package/esm/LinearGenomeView/components/Cytobands.js +76 -53
  16. package/esm/LinearGenomeView/components/ExportSvgDialog.d.ts +7 -3
  17. package/esm/LinearGenomeView/components/ExportSvgDialog.js +11 -67
  18. package/esm/LinearGenomeView/components/GetSequenceDialog.d.ts +5 -9
  19. package/esm/LinearGenomeView/components/GetSequenceDialog.js +84 -88
  20. package/esm/LinearGenomeView/components/Gridlines.d.ts +1 -1
  21. package/esm/LinearGenomeView/components/Gridlines.js +29 -58
  22. package/esm/LinearGenomeView/components/Header.d.ts +1 -1
  23. package/esm/LinearGenomeView/components/Header.js +32 -16
  24. package/esm/LinearGenomeView/components/HeaderClearHighlightButton.d.ts +21 -0
  25. package/esm/LinearGenomeView/components/HeaderClearHighlightButton.js +35 -0
  26. package/esm/LinearGenomeView/components/HeaderPanControls.d.ts +3 -2
  27. package/esm/LinearGenomeView/components/HeaderPanControls.js +16 -7
  28. package/esm/LinearGenomeView/components/HeaderRegionWidth.d.ts +1 -1
  29. package/esm/LinearGenomeView/components/HeaderRegionWidth.js +9 -6
  30. package/esm/LinearGenomeView/components/HeaderSearchBoxRow.d.ts +6 -0
  31. package/esm/LinearGenomeView/components/HeaderSearchBoxRow.js +27 -0
  32. package/esm/LinearGenomeView/components/HeaderSearchBoxes.d.ts +5 -0
  33. package/esm/LinearGenomeView/components/HeaderSearchBoxes.js +28 -0
  34. package/esm/LinearGenomeView/components/HeaderTrackSelectorButton.d.ts +3 -2
  35. package/esm/LinearGenomeView/components/HeaderTrackSelectorButton.js +11 -4
  36. package/esm/LinearGenomeView/components/HeaderZoomControls.d.ts +3 -2
  37. package/esm/LinearGenomeView/components/HeaderZoomControls.js +67 -51
  38. package/esm/LinearGenomeView/components/Highlight.d.ts +1 -1
  39. package/esm/LinearGenomeView/components/Highlight.js +19 -23
  40. package/esm/LinearGenomeView/components/HighlightBand.d.ts +3 -2
  41. package/esm/LinearGenomeView/components/HighlightBand.js +25 -8
  42. package/esm/LinearGenomeView/components/HighlightChip.d.ts +9 -0
  43. package/esm/LinearGenomeView/components/HighlightChip.js +15 -0
  44. package/esm/LinearGenomeView/components/HoverPositionHighlight.d.ts +12 -0
  45. package/esm/LinearGenomeView/components/HoverPositionHighlight.js +25 -0
  46. package/esm/LinearGenomeView/components/ImportForm.d.ts +3 -4
  47. package/esm/LinearGenomeView/components/ImportForm.js +95 -61
  48. package/esm/LinearGenomeView/components/LinearGenomeView.d.ts +1 -1
  49. package/esm/LinearGenomeView/components/LinearGenomeView.js +6 -5
  50. package/esm/LinearGenomeView/components/LinearGenomeViewContainer.d.ts +1 -1
  51. package/esm/LinearGenomeView/components/LinearGenomeViewContainer.js +89 -30
  52. package/esm/LinearGenomeView/components/MiniControls.d.ts +1 -1
  53. package/esm/LinearGenomeView/components/MiniControls.js +13 -10
  54. package/esm/LinearGenomeView/components/MotifListPanel.d.ts +3 -0
  55. package/esm/LinearGenomeView/components/MotifListPanel.js +59 -0
  56. package/esm/LinearGenomeView/components/NavigationAnnouncer.d.ts +32 -0
  57. package/esm/LinearGenomeView/components/NavigationAnnouncer.js +51 -0
  58. package/esm/LinearGenomeView/components/NoTracksActiveButton.d.ts +1 -1
  59. package/esm/LinearGenomeView/components/NoTracksActiveButton.js +1 -1
  60. package/esm/LinearGenomeView/components/OverviewHighlight.d.ts +2 -4
  61. package/esm/LinearGenomeView/components/OverviewHighlight.js +23 -44
  62. package/esm/LinearGenomeView/components/OverviewHighlightBand.d.ts +9 -0
  63. package/esm/LinearGenomeView/components/OverviewHighlightBand.js +26 -0
  64. package/esm/LinearGenomeView/components/OverviewRubberband.d.ts +3 -3
  65. package/esm/LinearGenomeView/components/OverviewRubberband.js +44 -57
  66. package/esm/LinearGenomeView/components/OverviewRubberbandHoverTooltip.d.ts +4 -5
  67. package/esm/LinearGenomeView/components/OverviewRubberbandHoverTooltip.js +13 -20
  68. package/esm/LinearGenomeView/components/OverviewScalebar.d.ts +3 -2
  69. package/esm/LinearGenomeView/components/OverviewScalebar.js +84 -79
  70. package/esm/LinearGenomeView/components/OverviewScalebarPolygon.d.ts +19 -5
  71. package/esm/LinearGenomeView/components/OverviewScalebarPolygon.js +55 -32
  72. package/esm/LinearGenomeView/components/OverviewScalebarTickLabels.d.ts +4 -5
  73. package/esm/LinearGenomeView/components/OverviewScalebarTickLabels.js +16 -18
  74. package/esm/LinearGenomeView/components/PaddingBlocks.d.ts +7 -0
  75. package/esm/LinearGenomeView/components/PaddingBlocks.js +61 -0
  76. package/esm/LinearGenomeView/components/RangeSelectOverlay.d.ts +9 -0
  77. package/esm/LinearGenomeView/components/RangeSelectOverlay.js +20 -0
  78. package/esm/LinearGenomeView/components/RegionWidthEditorDialog.d.ts +2 -3
  79. package/esm/LinearGenomeView/components/RegionWidthEditorDialog.js +19 -26
  80. package/esm/LinearGenomeView/components/Rubberband.d.ts +1 -1
  81. package/esm/LinearGenomeView/components/Rubberband.js +13 -16
  82. package/esm/LinearGenomeView/components/SVGHighlightBand.d.ts +10 -0
  83. package/esm/LinearGenomeView/components/SVGHighlightBand.js +9 -0
  84. package/esm/LinearGenomeView/components/Scalebar.d.ts +2 -2
  85. package/esm/LinearGenomeView/components/Scalebar.js +16 -21
  86. package/esm/LinearGenomeView/components/ScalebarCoordinateLabels.d.ts +1 -1
  87. package/esm/LinearGenomeView/components/ScalebarCoordinateLabels.js +54 -35
  88. package/esm/LinearGenomeView/components/ScalebarRefNameLabels.d.ts +1 -1
  89. package/esm/LinearGenomeView/components/ScalebarRefNameLabels.js +142 -126
  90. package/esm/LinearGenomeView/components/SearchBox.d.ts +22 -2
  91. package/esm/LinearGenomeView/components/SearchBox.js +58 -66
  92. package/esm/LinearGenomeView/components/SearchPanelForm.d.ts +9 -0
  93. package/esm/LinearGenomeView/components/SearchPanelForm.js +18 -0
  94. package/esm/LinearGenomeView/components/SearchResultsDialog.d.ts +3 -3
  95. package/esm/LinearGenomeView/components/SearchResultsDialog.js +5 -7
  96. package/esm/LinearGenomeView/components/SearchResultsTable.d.ts +4 -3
  97. package/esm/LinearGenomeView/components/SearchResultsTable.js +45 -53
  98. package/esm/LinearGenomeView/components/SequenceFeatureHoverHighlight.d.ts +5 -0
  99. package/esm/LinearGenomeView/components/SequenceFeatureHoverHighlight.js +37 -0
  100. package/esm/LinearGenomeView/components/SequenceFeatureHoverHighlightExtension.d.ts +2 -0
  101. package/esm/LinearGenomeView/components/SequenceFeatureHoverHighlightExtension.js +5 -0
  102. package/esm/LinearGenomeView/components/SequencePatternPanel.d.ts +3 -0
  103. package/esm/LinearGenomeView/components/SequencePatternPanel.js +42 -0
  104. package/esm/LinearGenomeView/components/SequenceSearchDialog.d.ts +2 -2
  105. package/esm/LinearGenomeView/components/SequenceSearchDialog.js +31 -53
  106. package/esm/LinearGenomeView/components/StrandCheckboxes.d.ts +8 -0
  107. package/esm/LinearGenomeView/components/StrandCheckboxes.js +13 -0
  108. package/esm/LinearGenomeView/components/TrackContainer.d.ts +1 -1
  109. package/esm/LinearGenomeView/components/TrackContainer.js +83 -39
  110. package/esm/LinearGenomeView/components/TrackLabel.d.ts +2 -3
  111. package/esm/LinearGenomeView/components/TrackLabel.js +11 -24
  112. package/esm/LinearGenomeView/components/TrackLabelButtons.d.ts +7 -0
  113. package/esm/LinearGenomeView/components/TrackLabelButtons.js +33 -0
  114. package/esm/LinearGenomeView/components/TrackLabelDragHandle.d.ts +2 -5
  115. package/esm/LinearGenomeView/components/TrackLabelDragHandle.js +6 -2
  116. package/esm/LinearGenomeView/components/TrackLabelMenu.d.ts +1 -1
  117. package/esm/LinearGenomeView/components/TrackLabelMenu.js +32 -85
  118. package/esm/LinearGenomeView/components/TrackLabelRefNameWarning.d.ts +22 -0
  119. package/esm/LinearGenomeView/components/TrackLabelRefNameWarning.js +46 -0
  120. package/esm/LinearGenomeView/components/TrackRenderingContainer.d.ts +1 -1
  121. package/esm/LinearGenomeView/components/TrackRenderingContainer.js +72 -18
  122. package/esm/LinearGenomeView/components/TracksContainer.d.ts +1 -1
  123. package/esm/LinearGenomeView/components/TracksContainer.js +65 -32
  124. package/esm/LinearGenomeView/components/VerticalGuide.d.ts +1 -1
  125. package/esm/LinearGenomeView/components/VerticalGuide.js +6 -13
  126. package/esm/LinearGenomeView/components/ZoomButton.d.ts +7 -0
  127. package/esm/LinearGenomeView/components/ZoomButton.js +27 -0
  128. package/esm/LinearGenomeView/components/ZoomTransform.d.ts +9 -0
  129. package/esm/LinearGenomeView/components/ZoomTransform.js +37 -0
  130. package/esm/LinearGenomeView/components/defaultMotifs.d.ts +1 -0
  131. package/esm/LinearGenomeView/components/defaultMotifs.js +22 -0
  132. package/esm/LinearGenomeView/components/fetchSequence.d.ts +7 -8
  133. package/esm/LinearGenomeView/components/fetchSequence.js +17 -9
  134. package/esm/LinearGenomeView/components/recentLocationsMenu.d.ts +15 -0
  135. package/esm/LinearGenomeView/components/recentLocationsMenu.js +36 -0
  136. package/esm/LinearGenomeView/components/searchModes.d.ts +13 -0
  137. package/esm/LinearGenomeView/components/searchModes.js +22 -0
  138. package/esm/LinearGenomeView/components/trackLabelMenuItems.d.ts +7 -0
  139. package/esm/LinearGenomeView/components/trackLabelMenuItems.js +67 -0
  140. package/esm/LinearGenomeView/components/useRangeSelect.d.ts +11 -66
  141. package/esm/LinearGenomeView/components/useRangeSelect.js +82 -91
  142. package/esm/LinearGenomeView/components/useSearchBoxPrefs.d.ts +26 -0
  143. package/esm/LinearGenomeView/components/useSearchBoxPrefs.js +58 -0
  144. package/esm/LinearGenomeView/components/useSideScroll.d.ts +1 -1
  145. package/esm/LinearGenomeView/components/useSideScroll.js +87 -19
  146. package/esm/LinearGenomeView/components/util.d.ts +20 -6
  147. package/esm/LinearGenomeView/components/util.js +27 -6
  148. package/esm/LinearGenomeView/consts.d.ts +7 -2
  149. package/esm/LinearGenomeView/consts.js +18 -2
  150. package/esm/LinearGenomeView/flyTo.d.ts +38 -0
  151. package/esm/LinearGenomeView/flyTo.js +135 -0
  152. package/esm/LinearGenomeView/headerFit.d.ts +27 -0
  153. package/esm/LinearGenomeView/headerFit.js +59 -0
  154. package/esm/LinearGenomeView/index.d.ts +32 -2
  155. package/esm/LinearGenomeView/index.js +16 -6
  156. package/esm/LinearGenomeView/initKeys.d.ts +12 -0
  157. package/esm/LinearGenomeView/initKeys.js +68 -0
  158. package/esm/LinearGenomeView/keyboardHandler.d.ts +7 -0
  159. package/esm/LinearGenomeView/keyboardHandler.js +10 -0
  160. package/esm/LinearGenomeView/launchKeys.d.ts +2 -0
  161. package/esm/LinearGenomeView/launchKeys.js +23 -0
  162. package/esm/LinearGenomeView/lazyDialogs.d.ts +7 -11
  163. package/esm/LinearGenomeView/lazyDialogs.js +3 -3
  164. package/esm/LinearGenomeView/linkedViewSync.d.ts +20 -0
  165. package/esm/LinearGenomeView/linkedViewSync.js +58 -0
  166. package/esm/LinearGenomeView/menuItems.d.ts +27 -2
  167. package/esm/LinearGenomeView/menuItems.js +137 -101
  168. package/esm/LinearGenomeView/model.d.ts +3238 -136
  169. package/esm/LinearGenomeView/model.js +2425 -528
  170. package/esm/LinearGenomeView/sharedScaleContainer.d.ts +18 -0
  171. package/esm/LinearGenomeView/sharedScaleContainer.js +17 -0
  172. package/esm/LinearGenomeView/showRegionsWithUndo.d.ts +35 -0
  173. package/esm/LinearGenomeView/showRegionsWithUndo.js +44 -0
  174. package/esm/LinearGenomeView/stickyChrome.d.ts +19 -0
  175. package/esm/LinearGenomeView/stickyChrome.js +30 -0
  176. package/esm/LinearGenomeView/svgcomponents/SVGGridlines.d.ts +1 -1
  177. package/esm/LinearGenomeView/svgcomponents/SVGGridlines.js +15 -16
  178. package/esm/LinearGenomeView/svgcomponents/SVGHeader.d.ts +2 -3
  179. package/esm/LinearGenomeView/svgcomponents/SVGHeader.js +45 -33
  180. package/esm/LinearGenomeView/svgcomponents/SVGHighlights.d.ts +5 -0
  181. package/esm/LinearGenomeView/svgcomponents/SVGHighlights.js +26 -0
  182. package/esm/LinearGenomeView/svgcomponents/SVGHighlightsOverlay.d.ts +5 -0
  183. package/esm/LinearGenomeView/svgcomponents/SVGHighlightsOverlay.js +13 -0
  184. package/esm/LinearGenomeView/svgcomponents/SVGLinearGenomeView.d.ts +1 -3
  185. package/esm/LinearGenomeView/svgcomponents/SVGLinearGenomeView.js +77 -41
  186. package/esm/LinearGenomeView/svgcomponents/SVGRegionSeparators.d.ts +1 -1
  187. package/esm/LinearGenomeView/svgcomponents/SVGRegionSeparators.js +23 -3
  188. package/esm/LinearGenomeView/svgcomponents/SVGRowHeader.d.ts +8 -0
  189. package/esm/LinearGenomeView/svgcomponents/SVGRowHeader.js +37 -0
  190. package/esm/LinearGenomeView/svgcomponents/SVGRuler.d.ts +3 -3
  191. package/esm/LinearGenomeView/svgcomponents/SVGRuler.js +64 -36
  192. package/esm/LinearGenomeView/svgcomponents/SVGScalebar.d.ts +1 -1
  193. package/esm/LinearGenomeView/svgcomponents/SVGScalebar.js +7 -5
  194. package/esm/LinearGenomeView/svgcomponents/SVGTrackLabel.d.ts +5 -3
  195. package/esm/LinearGenomeView/svgcomponents/SVGTrackLabel.js +43 -7
  196. package/esm/LinearGenomeView/svgcomponents/SVGTracks.d.ts +8 -14
  197. package/esm/LinearGenomeView/svgcomponents/SVGTracks.js +16 -21
  198. package/esm/LinearGenomeView/svgcomponents/SVGView.d.ts +18 -0
  199. package/esm/LinearGenomeView/svgcomponents/SVGView.js +13 -0
  200. package/esm/LinearGenomeView/svgcomponents/figureContract.d.ts +45 -0
  201. package/esm/LinearGenomeView/svgcomponents/figureContract.js +130 -0
  202. package/esm/LinearGenomeView/svgcomponents/renderViewTracks.d.ts +76 -0
  203. package/esm/LinearGenomeView/svgcomponents/renderViewTracks.js +66 -0
  204. package/esm/LinearGenomeView/svgcomponents/useViewSvgFigure.d.ts +70 -0
  205. package/esm/LinearGenomeView/svgcomponents/useViewSvgFigure.js +263 -0
  206. package/esm/LinearGenomeView/svgcomponents/util.d.ts +92 -5
  207. package/esm/LinearGenomeView/svgcomponents/util.js +236 -3
  208. package/esm/LinearGenomeView/types.d.ts +17 -31
  209. package/esm/LinearGenomeView/types.js +1 -0
  210. package/esm/LinearGenomeView/util.d.ts +332 -12
  211. package/esm/LinearGenomeView/util.js +606 -62
  212. package/esm/MultiLevelRubberband/MultiLevelRubberband.d.ts +6 -0
  213. package/esm/MultiLevelRubberband/MultiLevelRubberband.js +37 -0
  214. package/esm/MultiLevelRubberband/VerticalGuide.d.ts +6 -0
  215. package/esm/MultiLevelRubberband/VerticalGuide.js +21 -0
  216. package/esm/MultiLevelRubberband/index.d.ts +2 -0
  217. package/esm/MultiLevelRubberband/index.js +1 -0
  218. package/esm/MultiLevelRubberband/types.d.ts +6 -0
  219. package/esm/MultiLevelRubberband/useRangeSelect.d.ts +24 -0
  220. package/esm/MultiLevelRubberband/useRangeSelect.js +136 -0
  221. package/esm/displayKitTests/perRegionTestEnv.d.ts +1286 -0
  222. package/esm/displayKitTests/perRegionTestEnv.js +138 -0
  223. package/esm/index.d.ts +122 -1235
  224. package/esm/index.js +101 -24
  225. package/esm/lazyPluginExports.d.ts +23 -0
  226. package/esm/lazyPluginExports.js +36 -0
  227. package/esm/searchUtils.d.ts +55 -11
  228. package/esm/searchUtils.js +342 -45
  229. package/esm/shared/RubberbandSpan.d.ts +15 -0
  230. package/esm/shared/RubberbandSpan.js +33 -0
  231. package/esm/shared/coordLabels.d.ts +40 -0
  232. package/esm/shared/coordLabels.js +119 -0
  233. package/package.json +18 -19
  234. package/esm/BaseLinearDisplay/SVGLegend.d.ts +0 -6
  235. package/esm/BaseLinearDisplay/SVGLegend.js +0 -17
  236. package/esm/BaseLinearDisplay/calculateSvgLegendWidth.d.ts +0 -2
  237. package/esm/BaseLinearDisplay/calculateSvgLegendWidth.js +0 -11
  238. package/esm/BaseLinearDisplay/components/BaseLinearDisplay.d.ts +0 -8
  239. package/esm/BaseLinearDisplay/components/BaseLinearDisplay.js +0 -53
  240. package/esm/BaseLinearDisplay/components/Block.d.ts +0 -14
  241. package/esm/BaseLinearDisplay/components/Block.js +0 -45
  242. package/esm/BaseLinearDisplay/components/BlockErrorMessage.d.ts +0 -7
  243. package/esm/BaseLinearDisplay/components/BlockErrorMessage.js +0 -22
  244. package/esm/BaseLinearDisplay/components/BlockMsg.d.ts +0 -6
  245. package/esm/BaseLinearDisplay/components/BlockMsg.js +0 -26
  246. package/esm/BaseLinearDisplay/components/CollapseIntronsDialog/CollapseIntronsDialog.d.ts +0 -9
  247. package/esm/BaseLinearDisplay/components/CollapseIntronsDialog/CollapseIntronsDialog.js +0 -42
  248. package/esm/BaseLinearDisplay/components/CollapseIntronsDialog/TranscriptTable.d.ts +0 -11
  249. package/esm/BaseLinearDisplay/components/CollapseIntronsDialog/TranscriptTable.js +0 -40
  250. package/esm/BaseLinearDisplay/components/CollapseIntronsDialog/util.d.ts +0 -19
  251. package/esm/BaseLinearDisplay/components/CollapseIntronsDialog/util.js +0 -45
  252. package/esm/BaseLinearDisplay/components/FloatingLabels.d.ts +0 -5
  253. package/esm/BaseLinearDisplay/components/FloatingLabels.js +0 -75
  254. package/esm/BaseLinearDisplay/components/FloatingLegend.d.ts +0 -8
  255. package/esm/BaseLinearDisplay/components/FloatingLegend.js +0 -43
  256. package/esm/BaseLinearDisplay/components/LinearBlocks.d.ts +0 -5
  257. package/esm/BaseLinearDisplay/components/LinearBlocks.js +0 -23
  258. package/esm/BaseLinearDisplay/components/LoadingOverlay.d.ts +0 -5
  259. package/esm/BaseLinearDisplay/components/LoadingOverlay.js +0 -49
  260. package/esm/BaseLinearDisplay/components/MaxHeightReachedIndicator.d.ts +0 -4
  261. package/esm/BaseLinearDisplay/components/MaxHeightReachedIndicator.js +0 -26
  262. package/esm/BaseLinearDisplay/components/MenuPage.d.ts +0 -8
  263. package/esm/BaseLinearDisplay/components/MenuPage.js +0 -24
  264. package/esm/BaseLinearDisplay/components/NonBlockCanvasDisplayComponent.d.ts +0 -21
  265. package/esm/BaseLinearDisplay/components/NonBlockCanvasDisplayComponent.js +0 -52
  266. package/esm/BaseLinearDisplay/components/RenderedBlocks.d.ts +0 -12
  267. package/esm/BaseLinearDisplay/components/RenderedBlocks.js +0 -22
  268. package/esm/BaseLinearDisplay/components/ServerSideRenderedBlockContent.d.ts +0 -12
  269. package/esm/BaseLinearDisplay/components/ServerSideRenderedBlockContent.js +0 -18
  270. package/esm/BaseLinearDisplay/components/TooLargeMessage.d.ts +0 -10
  271. package/esm/BaseLinearDisplay/components/TooLargeMessage.js +0 -20
  272. package/esm/BaseLinearDisplay/components/Tooltip.d.ts +0 -13
  273. package/esm/BaseLinearDisplay/components/Tooltip.js +0 -22
  274. package/esm/BaseLinearDisplay/components/types.d.ts +0 -1
  275. package/esm/BaseLinearDisplay/components/util.d.ts +0 -21
  276. package/esm/BaseLinearDisplay/components/util.js +0 -107
  277. package/esm/BaseLinearDisplay/index.d.ts +0 -17
  278. package/esm/BaseLinearDisplay/index.js +0 -13
  279. package/esm/BaseLinearDisplay/model.d.ts +0 -1197
  280. package/esm/BaseLinearDisplay/model.js +0 -432
  281. package/esm/BaseLinearDisplay/models/FeatureDensityMixin.d.ts +0 -32
  282. package/esm/BaseLinearDisplay/models/FeatureDensityMixin.js +0 -113
  283. package/esm/BaseLinearDisplay/models/NonBlockCanvasDisplayMixin.d.ts +0 -26
  284. package/esm/BaseLinearDisplay/models/NonBlockCanvasDisplayMixin.js +0 -57
  285. package/esm/BaseLinearDisplay/models/SvgFloatingLabels.d.ts +0 -8
  286. package/esm/BaseLinearDisplay/models/SvgFloatingLabels.js +0 -19
  287. package/esm/BaseLinearDisplay/models/TrackHeightMixin.d.ts +0 -11
  288. package/esm/BaseLinearDisplay/models/TrackHeightMixin.js +0 -31
  289. package/esm/BaseLinearDisplay/models/autorunFeatureDensityStats.d.ts +0 -2
  290. package/esm/BaseLinearDisplay/models/autorunFeatureDensityStats.js +0 -29
  291. package/esm/BaseLinearDisplay/models/configSchema.d.ts +0 -29
  292. package/esm/BaseLinearDisplay/models/configSchema.js +0 -33
  293. package/esm/BaseLinearDisplay/models/serverSideRenderedBlock.d.ts +0 -98
  294. package/esm/BaseLinearDisplay/models/serverSideRenderedBlock.js +0 -242
  295. package/esm/BaseLinearDisplay/models/util.d.ts +0 -9
  296. package/esm/BaseLinearDisplay/models/util.js +0 -43
  297. package/esm/BaseLinearDisplay/renderSvg.d.ts +0 -3
  298. package/esm/BaseLinearDisplay/renderSvg.js +0 -63
  299. package/esm/BaseLinearDisplay/types.d.ts +0 -43
  300. package/esm/BaseLinearDisplay/types.js +0 -3
  301. package/esm/BaseLinearDisplay/util.d.ts +0 -16
  302. package/esm/BaseLinearDisplay/util.js +0 -71
  303. package/esm/BasicTrack/configSchema.d.ts +0 -85
  304. package/esm/BasicTrack/configSchema.js +0 -8
  305. package/esm/BasicTrack/index.d.ts +0 -2
  306. package/esm/BasicTrack/index.js +0 -12
  307. package/esm/LinearBareDisplay/configSchema.d.ts +0 -32
  308. package/esm/LinearBareDisplay/configSchema.js +0 -11
  309. package/esm/LinearBareDisplay/index.d.ts +0 -4
  310. package/esm/LinearBareDisplay/index.js +0 -20
  311. package/esm/LinearBareDisplay/model.d.ts +0 -1196
  312. package/esm/LinearBareDisplay/model.js +0 -32
  313. package/esm/LinearBasicDisplay/components/LinearBasicDisplayComponent.d.ts +0 -5
  314. package/esm/LinearBasicDisplay/components/LinearBasicDisplayComponent.js +0 -9
  315. package/esm/LinearBasicDisplay/configSchema.d.ts +0 -32
  316. package/esm/LinearBasicDisplay/configSchema.js +0 -11
  317. package/esm/LinearBasicDisplay/index.d.ts +0 -4
  318. package/esm/LinearBasicDisplay/index.js +0 -20
  319. package/esm/LinearBasicDisplay/model.d.ts +0 -1391
  320. package/esm/LinearBasicDisplay/model.js +0 -158
  321. package/esm/LinearFeatureDisplay/components/AddFiltersDialog.d.ts +0 -9
  322. package/esm/LinearFeatureDisplay/components/AddFiltersDialog.js +0 -58
  323. package/esm/LinearFeatureDisplay/components/SetMaxHeightDialog.d.ts +0 -8
  324. package/esm/LinearFeatureDisplay/components/SetMaxHeightDialog.js +0 -26
  325. package/esm/LinearFeatureDisplay/configSchema.d.ts +0 -32
  326. package/esm/LinearFeatureDisplay/configSchema.js +0 -11
  327. package/esm/LinearFeatureDisplay/index.d.ts +0 -3
  328. package/esm/LinearFeatureDisplay/index.js +0 -2
  329. package/esm/LinearFeatureDisplay/model.d.ts +0 -1443
  330. package/esm/LinearFeatureDisplay/model.js +0 -305
  331. package/esm/LinearGenomeView/SVGErrorBox.d.ts +0 -5
  332. package/esm/LinearGenomeView/SVGErrorBox.js +0 -4
  333. package/esm/LinearGenomeView/components/ImportFormRefNameAutocomplete.d.ts +0 -11
  334. package/esm/LinearGenomeView/components/ImportFormRefNameAutocomplete.js +0 -27
  335. package/esm/LinearGenomeView/components/RefNameAutocomplete/AutocompleteTextField.d.ts +0 -5
  336. package/esm/LinearGenomeView/components/RefNameAutocomplete/AutocompleteTextField.js +0 -13
  337. package/esm/LinearGenomeView/components/RefNameAutocomplete/EndAdornment.d.ts +0 -3
  338. package/esm/LinearGenomeView/components/RefNameAutocomplete/EndAdornment.js +0 -17
  339. package/esm/LinearGenomeView/components/RefNameAutocomplete/HelpDialog.d.ts +0 -3
  340. package/esm/LinearGenomeView/components/RefNameAutocomplete/HelpDialog.js +0 -8
  341. package/esm/LinearGenomeView/components/RefNameAutocomplete/index.d.ts +0 -16
  342. package/esm/LinearGenomeView/components/RefNameAutocomplete/index.js +0 -101
  343. package/esm/LinearGenomeView/components/RefNameAutocomplete/util.d.ts +0 -10
  344. package/esm/LinearGenomeView/components/RefNameAutocomplete/util.js +0 -45
  345. package/esm/LinearGenomeView/components/RubberbandSpan.d.ts +0 -15
  346. package/esm/LinearGenomeView/components/RubberbandSpan.js +0 -32
  347. package/esm/LinearGenomeView/components/RubberbandTooltip.d.ts +0 -5
  348. package/esm/LinearGenomeView/components/RubberbandTooltip.js +0 -17
  349. package/esm/LinearGenomeView/components/TrackLabelContainer.d.ts +0 -8
  350. package/esm/LinearGenomeView/components/TrackLabelContainer.js +0 -25
  351. package/esm/LinearGenomeView/components/useWheelScroll.d.ts +0 -7
  352. package/esm/LinearGenomeView/components/useWheelScroll.js +0 -69
  353. package/esm/LinearGenomeView/svgExportUtil.d.ts +0 -9
  354. package/esm/LinearGenomeView/svgExportUtil.js +0 -6
  355. package/esm/LinearGenomeView/svgcomponents/SVGBackground.d.ts +0 -5
  356. package/esm/LinearGenomeView/svgcomponents/SVGBackground.js +0 -7
  357. /package/esm/{BaseLinearDisplay/components → MultiLevelRubberband}/types.js +0 -0
@@ -1,77 +1,374 @@
1
- import BaseResult from '@jbrowse/core/TextSearch/BaseResults';
2
- import { dedupe, getEnv, getSession } from '@jbrowse/core/util';
3
- export async function navToOption({ option, model, assemblyName, }) {
4
- const location = option.getLocation();
5
- const trackId = option.getTrackId();
6
- if (location) {
7
- await model.navToLocString(location, assemblyName, 0.2);
8
- if (trackId) {
9
- model.showTrack(trackId);
1
+ import { RefSequenceResult } from '@jbrowse/core/TextSearch/BaseResults';
2
+ import { assembleLocString, dedupe, getEnv, getNotificationSink, getSession, matchRefNames, MAX_GLOB_REGIONS, parseLocString, UnknownRefNameError, } from '@jbrowse/core/util';
3
+ import { isAlive } from '@jbrowse/mobx-state-tree';
4
+ import { parseLocStrings } from './LinearGenomeView/util.js';
5
+ // Budget for refName suggestions from a query. Deliberately far below the
6
+ // autocomplete's ~100-row display cap: refNames are returned ahead of the text
7
+ // search hits, so a scaffold-heavy assembly would otherwise fill every row with
8
+ // scaffolds and push the gene hits out of the list entirely. Raising this to
9
+ // match the display cap looks like a consistency fix and is not one.
10
+ const MAX_REFNAME_HITS = 10;
11
+ // shared dispatch used by SearchBox.onSelect and the LGV ImportForm submit:
12
+ // route a chosen result to a direct nav, a multi-result dialog, or a generic
13
+ // locstring/refname resolution
14
+ export async function navigateToSelectedOption({ option, model, assemblyName, }) {
15
+ if (option.hasLocation()) {
16
+ await navToOption({ option, model, assemblyName });
17
+ }
18
+ else if (option.results?.length) {
19
+ await showSearchResults({
20
+ results: option.results,
21
+ query: option.getLabel(),
22
+ model,
23
+ assemblyName,
24
+ });
25
+ }
26
+ else {
27
+ await handleSelectedRegion({
28
+ input: option.getLabel(),
29
+ assemblyName,
30
+ model,
31
+ });
32
+ }
33
+ }
34
+ // Whether the view already has the track this hit came from on screen.
35
+ export function isOpenInView(result, model) {
36
+ const trackId = result.getTrackId();
37
+ return trackId !== undefined && !!model.getTrack(trackId);
38
+ }
39
+ // One spelling of a locstring, so two indexes that answer `chr1:1-100` and
40
+ // `1:1..100` are recognised as one place. An unparseable string is compared
41
+ // raw, which can only ever split a group that would otherwise have merged —
42
+ // the safe direction, since the picker is what an unprovable match falls back
43
+ // to.
44
+ function canonicalLocString(locString, assembly) {
45
+ try {
46
+ const loc = parseLocString(locString, refName => assembly.isValidRefName(refName));
47
+ return assembleLocString({
48
+ ...loc,
49
+ refName: assembly.getCanonicalRefName2(loc.refName),
50
+ });
51
+ }
52
+ catch (e) {
53
+ console.warn('failed to parse location string', locString, e);
54
+ return locString;
55
+ }
56
+ }
57
+ // What a hit means as a destination: the name it shows and the place it goes.
58
+ // A hit with no location has no destination and can never join a group.
59
+ function destination(result, assembly) {
60
+ const locString = result.getLocation();
61
+ return locString
62
+ ? [
63
+ result.getDisplayString(),
64
+ assembly?.initialized
65
+ ? canonicalLocString(locString, assembly)
66
+ : locString,
67
+ ].join('\u0000')
68
+ : undefined;
69
+ }
70
+ // Which hit of an agreeing group to travel through, best rung first: a track
71
+ // the view already has on screen, then one the session could open if asked,
72
+ // then whatever the ranking put first. The middle rung is not hypothetical —
73
+ // a JBrowse 1 names index stores JBrowse 1 track *names*, and volvox's has
74
+ // four EDEN.1 entries of which two name nothing any JBrowse 2 config claims.
75
+ // Travelling through one of those navigates correctly and then drops a
76
+ // "could not resolve identifier" snackbar on top of it.
77
+ function trackRank(result, model, session) {
78
+ const trackId = result.getTrackId();
79
+ if (trackId === undefined) {
80
+ return 2;
81
+ }
82
+ else if (model.getTrack(trackId)) {
83
+ return 0;
84
+ }
85
+ else {
86
+ return session.getTrackById(trackId) ? 1 : 3;
87
+ }
88
+ }
89
+ // The pick is a stable minimum, so a linear scan rather than a sort: only the
90
+ // best rung is taken, and keeping the first strictly-lowest one is what leaves
91
+ // an agreeing group with nothing to choose between in the order the ranking
92
+ // handed it. Ranked once per hit for the reason `destinations` above it is:
93
+ // `trackRank` reaches `session.getTrackById`, and a comparator asks O(n log n)
94
+ // times for an answer that does not vary.
95
+ function bestRanked(results, model, session) {
96
+ let best = results[0];
97
+ let bestRank = trackRank(best, model, session);
98
+ for (let i = 1; i < results.length; i++) {
99
+ const rank = trackRank(results[i], model, session);
100
+ if (rank < bestRank) {
101
+ best = results[i];
102
+ bestRank = rank;
10
103
  }
11
104
  }
105
+ return best;
106
+ }
107
+ // The picker exists to disambiguate, and hits that name one feature at one
108
+ // place are not ambiguous — they are several indexes having found it. An
109
+ // instance carrying a handful of gene tracks turns every gene search into a
110
+ // table whose only varying column is Track, which is issues #4302 and #5068.
111
+ // When the hits agree there is nothing to ask, so navigate instead.
112
+ export function unanimousResult({ results, model, session, assembly, }) {
113
+ // computed once per hit rather than once per comparison: a broad query can
114
+ // carry a hundred results, and each one costs a locstring parse
115
+ const destinations = results.map(r => destination(r, assembly));
116
+ const agree = destinations[0] !== undefined &&
117
+ destinations.every(d => d === destinations[0]);
118
+ return agree ? bestRanked(results, model, session) : undefined;
119
+ }
120
+ // Every multi-hit result set reaches the picker through here, so the two
121
+ // search surfaces cannot disagree about when one is worth raising. Returns
122
+ // whether the view moved.
123
+ export async function showSearchResults({ results, query, model, assemblyName, grow, showHitTrack, }) {
124
+ const session = getSession(model);
125
+ const unanimous = unanimousResult({
126
+ results,
127
+ model,
128
+ session,
129
+ assembly: session.assemblyManager.get(assemblyName),
130
+ });
131
+ if (unanimous) {
132
+ await navToOption({
133
+ option: unanimous,
134
+ model,
135
+ assemblyName,
136
+ grow,
137
+ showHitTrack,
138
+ });
139
+ return true;
140
+ }
141
+ else {
142
+ model.setSearchResults(results, query, assemblyName);
143
+ return false;
144
+ }
145
+ }
146
+ // A search hit lands with context around it rather than flush to the feature's
147
+ // own edges, which is what this default is; a caller that asked for a specific
148
+ // padding gets that instead.
149
+ const SEARCH_HIT_GROW = 0.2;
150
+ // A hit lands with the track its index came from shown, which is what a name
151
+ // typed into the search box wants. A session spec that named its own tracks
152
+ // passes false: it asked for those tracks, and a hosted config's full RefSeq
153
+ // appearing beside the curated one it listed read as a bug.
154
+ export async function navToOption({ option, model, assemblyName, grow, showHitTrack = true, }) {
155
+ // getLocation() can be an empty string when a result reports hasLocation()
156
+ // but carries no coordinates; treat that as "no location" and fall back to
157
+ // the label rather than forwarding '' into an empty, view-blanking parse
158
+ const location = option.getLocation() || option.getLabel();
159
+ const trackId = option.getTrackId();
12
160
  const session = getSession(model);
13
- const { pluginManager } = getEnv(session);
14
- await pluginManager.evaluateAsyncExtensionPoint('LinearGenomeView-searchResultSelected', undefined, { session, result: option, model, assemblyName });
161
+ const { assemblyManager } = session;
162
+ await model.navToLocations(parseLocStrings(location, assemblyName, (ref, asm) => assemblyManager.isValidRefName(ref, asm)), assemblyName, grow ?? SEARCH_HIT_GROW);
163
+ if (showHitTrack && trackId && isAlive(model)) {
164
+ await model.launchTrack(trackId);
165
+ }
166
+ // same detach hazard as showTrack above: navToLocations awaits, and handlers
167
+ // read off the view (the canvas one calls getSession(model) and model.tracks),
168
+ // which throws once it has left the tree. Deliberately not the Strict runner —
169
+ // this fires after the navigation has already succeeded, so a plugin's
170
+ // post-nav side effect failing must not turn a completed search into an error
171
+ if (isAlive(model)) {
172
+ const { pluginManager } = getEnv(session);
173
+ await pluginManager.evaluateAsyncExtensionPoint(
174
+ /** #extensionPoint LinearGenomeView-searchResultSelected | async | Invoked when a search result is selected */
175
+ 'LinearGenomeView-searchResultSelected', undefined, { session, result: option, model, assemblyName });
176
+ }
177
+ }
178
+ // Thrown when a name search yields no hits and the input isn't coordinate-shaped.
179
+ // Typed (rather than a bare Error) so callers can render it as a soft "not found"
180
+ // warning instead of an error — string-matching the message would be brittle.
181
+ export class SearchResultsNotFoundError extends Error {
182
+ name = 'SearchResultsNotFoundError';
183
+ }
184
+ // How every search surface reports a failed navigation. A miss is the ordinary
185
+ // outcome of typing a name that isn't there, so it shows its own sentence
186
+ // rather than `${e}`, which would prefix it with the class name. Shared so the
187
+ // import form and the header box can't drift apart on it again.
188
+ export function notifySearchFailure(session, e) {
189
+ console.error(e);
190
+ session.notify(e instanceof SearchResultsNotFoundError ? e.message : `${e}`, 'warning');
15
191
  }
16
- export async function handleSelectedRegion({ input, model, assembly, }) {
17
- const allRefs = assembly.allRefNamesWithLowerCase || [];
18
- const assemblyName = assembly.name;
19
- if (input.split(' ').every(entry => checkRef(entry, allRefs))) {
20
- await model.navToLocString(input, assembly.name);
192
+ // if input is a known ref or locstring, navigate directly;
193
+ // otherwise search and: pop a dialog for multiple results, navigate for one,
194
+ // or fall back to treating input as a locstring
195
+ //
196
+ // Returns whether the view actually moved. Three branches deliberately do not
197
+ // navigate — a glob too wide to open, a multi-hit search whose hits disagree
198
+ // about where to go and so raise the picker, and a view detached while the
199
+ // search RPC ran — and each of them resolves, so a caller awaiting this cannot
200
+ // otherwise tell "showing it" from "asked you which one".
201
+ export async function handleSelectedRegion({ input, model, assemblyName, grow, showHitTrack, }) {
202
+ const { assemblyManager, textSearchManager } = getSession(model);
203
+ // resolves only once regions/aliases are loaded, which isValidRefName needs
204
+ // (it throws otherwise). A load failure is not this function's to report:
205
+ // swallow it and let the input fall through to the text-search path below
206
+ // rather than surfacing as a nav error
207
+ const assembly = await assemblyManager
208
+ .waitForAssembly(assemblyName)
209
+ .catch(() => undefined);
210
+ // the same predicate navToLocstrings hands parseLocStrings, so a locstring
211
+ // that passes here is one the parse below will accept
212
+ const isRef = (ref) => !!assembly && assemblyManager.isValidRefName(ref, assemblyName);
213
+ // navigate treating input as one or more whitespace-separated locstrings
214
+ const navToLocstrings = () => model.navToLocations(parseLocStrings(input, assemblyName, (ref, asm) => assemblyManager.isValidRefName(ref, asm)), assemblyName, grow);
215
+ if (input
216
+ .split(/\s+/)
217
+ .filter(Boolean)
218
+ .every(entry => checkRef(entry, isRef))) {
219
+ await navToLocstrings();
220
+ return true;
221
+ }
222
+ else if (input.includes('*') && !!assembly) {
223
+ // Enter does what the dropdown's "Show all N regions matching …" row does,
224
+ // for the same text. It is NOT a blind resolution: that row, and the matches
225
+ // under it, have been on screen the whole time the pattern was being typed,
226
+ // which is the reason a glob belongs in the picker at all. What would be
227
+ // indefensible is the two disagreeing — Enter reporting no results over a
228
+ // list the box is showing is the same failure the exact-first search pass
229
+ // was written to end, and a glob is precisely the query the text index can
230
+ // never answer, since nothing PREFIX-matches the literal `chr*`.
231
+ //
232
+ // Ordered after the refName check, so a contig whose name really contains
233
+ // `*` — GRCh38's HLA decoys — navigates to itself rather than being read as
234
+ // a pattern. Same literal-first rule as selectNamedRegions.
235
+ const names = matchRefNames(assembly, input, MAX_GLOB_REGIONS);
236
+ if (names.length > MAX_GLOB_REGIONS) {
237
+ // Refused rather than truncated, and said out loud. Opening the first
238
+ // thousand of a wider match is the one outcome that would look like it
239
+ // worked.
240
+ getNotificationSink(model).notify(`"${input}" matches more than ${MAX_GLOB_REGIONS} regions — narrow the pattern`, 'warning');
241
+ return false;
242
+ }
243
+ else if (names.length) {
244
+ await model.navToLocations(parseLocStrings(names.join(' '), assemblyName, (ref, asm) => assemblyManager.isValidRefName(ref, asm)), assemblyName);
245
+ return true;
246
+ }
247
+ else {
248
+ // matched nothing: a pattern is not a feature name, so there is no index
249
+ // to fall through to, and the miss is the whole answer
250
+ throw new SearchResultsNotFoundError(`No results found for "${input}"`);
251
+ }
21
252
  }
22
253
  else {
23
- const searchScope = model.searchScope(assemblyName);
24
- const { textSearchManager } = getSession(model);
25
- const results = await fetchResults({
254
+ // Ask once, unrestricted, and read exactness off the hits. Prefer the
255
+ // exact ones so a precise name navigates straight to its feature instead
256
+ // of opening a picker of everything it prefixes ("EDEN" must not pop a
257
+ // dialog for EDEN.1/.2/.3) — but an exact miss is not a no-result, since
258
+ // the autocomplete dropdown searched unrestricted and anything it just
259
+ // listed has to be reachable here too (typing "apple" and pressing enter
260
+ // once reported `No results found for "apple"` for a query the dropdown
261
+ // had two hits for).
262
+ //
263
+ // This used to be two searches, an exact one and then a broad one on the
264
+ // miss, which is two reads of the same index for the same query — the
265
+ // adapters answer 'exact' by filtering exactly this list. An adapter that
266
+ // tags nothing simply never wins the exact pass, which is the behaviour it
267
+ // had when it returned nothing for searchType: 'exact'.
268
+ const allResults = await fetchResults({
26
269
  queryString: input,
27
- searchType: 'exact',
28
- searchScope,
29
- rankSearchResults: model.rankSearchResults,
270
+ assemblyName,
30
271
  textSearchManager,
31
272
  assembly,
32
273
  });
274
+ const exactResults = allResults.filter(r => r.isExact());
275
+ const results = exactResults.length ? exactResults : allResults;
276
+ // the view may have been closed/detached while the text-search RPC ran
277
+ if (!isAlive(model)) {
278
+ return false;
279
+ }
33
280
  if (results.length > 1) {
34
- model.setSearchResults(results, input.toLowerCase(), assemblyName);
281
+ return await showSearchResults({
282
+ results,
283
+ query: input,
284
+ model,
285
+ assemblyName,
286
+ grow,
287
+ showHitTrack,
288
+ });
35
289
  }
36
290
  else if (results.length === 1) {
291
+ // `grow` reached the locstring branch above but not this one, so a
292
+ // caller's padding — a session spec's `grow`, sv-core's navToLoc — was
293
+ // honoured or silently replaced by 0.2 depending on whether the input
294
+ // happened to parse as a locstring rather than resolve to a feature
37
295
  await navToOption({
38
296
  option: results[0],
39
297
  model,
40
298
  assemblyName,
299
+ grow,
300
+ showHitTrack,
41
301
  });
302
+ return true;
42
303
  }
43
304
  else {
44
- await model.navToLocString(input, assemblyName);
305
+ // no search hits: still try to resolve the input as a locstring (bare
306
+ // refname, "ref start end" triplet, etc). if that also can't find a
307
+ // refname AND the input is a single bare token (a plausible gene name),
308
+ // reframe the unknown-ref error as a clean "no results" message; keep the
309
+ // specific ref error for coordinate/multi-part queries
310
+ try {
311
+ await navToLocstrings();
312
+ return true;
313
+ }
314
+ catch (e) {
315
+ const isPlainName = !input.includes(':') && !input.includes(' ');
316
+ if (e instanceof UnknownRefNameError && isPlainName) {
317
+ throw new SearchResultsNotFoundError(`No results found for "${input}"`);
318
+ }
319
+ else {
320
+ throw e;
321
+ }
322
+ }
45
323
  }
46
324
  }
47
325
  }
48
- export function checkRef(str, allRefs) {
326
+ export function checkRef(str, isRef) {
49
327
  const [ref, rest] = splitLast(str, ':');
50
- return (allRefs.includes(str) ||
51
- (allRefs.includes(ref) && !Number.isNaN(Number.parseInt(rest, 10))));
328
+ return isRef(str) || (isRef(ref) && /^\d/.test(rest));
52
329
  }
53
- export async function fetchResults({ queryString, searchType, searchScope, rankSearchResults, textSearchManager, assembly, }) {
54
- if (!textSearchManager) {
55
- console.warn('No text search manager');
56
- }
330
+ export async function fetchResults({ queryString, searchType, assemblyName, textSearchManager, assembly, stopToken, }) {
57
331
  const textSearchResults = await textSearchManager?.search({
58
332
  queryString,
59
333
  searchType,
60
- }, searchScope, rankSearchResults);
61
- const refNameResults = [
62
- ...new Set(assembly?.allRefNames
63
- ?.filter(ref => ref.toLowerCase().startsWith(queryString.toLowerCase()))
64
- .map(ref => assembly.getCanonicalRefName(ref) ?? ref)
65
- .slice(0, 10)),
66
- ].map(r => new BaseResult({ label: r, matchedObject: { refName: r } }));
334
+ stopToken,
335
+ }, assemblyName);
336
+ // ensure aliases are loaded: allRefNames is a pure getter, so reading it does
337
+ // not itself kick off the lazy load. A load failure just leaves allRefNames
338
+ // undefined, so this still returns whatever the text search turned up
339
+ await assembly?.load().catch(() => { });
340
+ const refNameResults = assembly
341
+ ? searchRefNames(assembly, queryString, searchType)
342
+ : [];
67
343
  return dedupe([...refNameResults, ...(textSearchResults ?? [])], elt => elt.getId());
68
344
  }
69
- export function splitLast(str, split) {
70
- const lastIndex = str.lastIndexOf(split);
71
- if (lastIndex === -1) {
72
- return [str, ''];
345
+ // Scan assembly refnames for query matches, resolving aliases (e.g. 'contigB')
346
+ // to the canonical refname ('ctgB') so the dropdown shows the name that matches
347
+ // the FASTA / displayed regions. allRefNames can hold ~10^6 entries, so stop
348
+ // once enough unique canonical hits accumulate rather than lowercasing and
349
+ // scanning the entire list on every keystroke.
350
+ function searchRefNames(assembly, queryString, searchType) {
351
+ const q = queryString.toLowerCase();
352
+ // canonical name -> whether any alias of it matched the query exactly, so
353
+ // "contigb" is an exact hit on ctgB even though the canonical name is not
354
+ // the query. Same collapsing as before, now carrying the flag through it
355
+ const canonicalHits = new Map();
356
+ for (const ref of assembly.allRefNames ?? []) {
357
+ const lower = ref.toLowerCase();
358
+ const exact = lower === q;
359
+ const isMatch = searchType === 'exact' ? exact : lower.startsWith(q);
360
+ if (isMatch) {
361
+ const canonical = assembly.getCanonicalRefName2(ref);
362
+ canonicalHits.set(canonical, exact || !!canonicalHits.get(canonical));
363
+ if (canonicalHits.size >= MAX_REFNAME_HITS) {
364
+ break;
365
+ }
366
+ }
73
367
  }
74
- const before = str.slice(0, lastIndex);
75
- const after = str.slice(lastIndex + 1);
76
- return [before, after];
368
+ return [...canonicalHits].map(([r, exact]) => new RefSequenceResult({ label: r, refName: r, exact }));
369
+ }
370
+ // splits on the last instance of a character
371
+ export function splitLast(str, split) {
372
+ const i = str.lastIndexOf(split);
373
+ return i === -1 ? [str, ''] : [str.slice(0, i), str.slice(i + 1)];
77
374
  }
@@ -0,0 +1,15 @@
1
+ /**
2
+ * The selection band of a rubberband drag, with its bp coordinates at the edges
3
+ * and an optional size in the middle. Callers format their own text, since a
4
+ * single view reads one coordinate per edge and the multi-level rubberband reads
5
+ * one per level.
6
+ */
7
+ export default function RubberbandSpan({ left, width, viewWidth, stickyTop, leftLabel, rightLabel, size, }: {
8
+ left: number;
9
+ width: number;
10
+ viewWidth: number;
11
+ stickyTop: string | undefined;
12
+ leftLabel: React.ReactNode;
13
+ rightLabel: React.ReactNode;
14
+ size?: React.ReactNode;
15
+ }): import("react").JSX.Element;
@@ -0,0 +1,33 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { makeStyles } from '@jbrowse/core/util/tss-react';
3
+ import { Typography, alpha } from '@mui/material';
4
+ import { LABEL_WIDTH, SpanEdgeLabels } from './coordLabels.js';
5
+ const useStyles = makeStyles()(theme => ({
6
+ rubberband: {
7
+ height: '100%',
8
+ background: alpha(theme.palette.tertiary.light, 0.7),
9
+ position: 'absolute',
10
+ left: 0,
11
+ zIndex: 830,
12
+ textAlign: 'center',
13
+ cursor: 'crosshair',
14
+ },
15
+ rubberbandText: {
16
+ color: theme.palette.tertiary.contrastText,
17
+ },
18
+ }));
19
+ /**
20
+ * The selection band of a rubberband drag, with its bp coordinates at the edges
21
+ * and an optional size in the middle. Callers format their own text, since a
22
+ * single view reads one coordinate per edge and the multi-level rubberband reads
23
+ * one per level.
24
+ */
25
+ export default function RubberbandSpan({ left, width, viewWidth, stickyTop, leftLabel, rightLabel, size, }) {
26
+ const { classes } = useStyles();
27
+ // a label only moves inside its edge when the span can hold it, so a sliver of
28
+ // a selection at a view border keeps both labels outside and takes the clip
29
+ const fitsInside = width > LABEL_WIDTH;
30
+ return (_jsxs("div", { className: classes.rubberband, style: { transform: `translateX(${left}px)`, width }, children: [_jsx(SpanEdgeLabels, { stickyTop: stickyTop, left: leftLabel, right: rightLabel, insideLeft: fitsInside && left < LABEL_WIDTH, insideRight: fitsInside && left + width > viewWidth - LABEL_WIDTH }), size ? (_jsx(Typography, { variant: "h6", className: classes.rubberbandText, style: stickyTop === undefined
31
+ ? undefined
32
+ : { position: 'sticky', top: stickyTop }, children: size })) : null] }));
33
+ }
@@ -0,0 +1,40 @@
1
+ export declare const LABEL_WIDTH = 100;
2
+ /**
3
+ * The bp coordinate under a vertical guide, drawn just above the top of the
4
+ * guide line so it covers neither the line nor the cursor hovering the scalebar
5
+ * the line starts at.
6
+ *
7
+ * A zero-height anchor marks that spot in the flow (`stickyTop` pins it to the
8
+ * scalebar it rides once that scrolls away) but the label itself portals to the
9
+ * body: sitting above the guide means sitting above the top of the tracks
10
+ * container, and that container's `contain: layout` traps its children in a
11
+ * stacking context the sticky LGV header (z-index 850, opaque background)
12
+ * paints over. So the anchor's viewport position is measured and the label
13
+ * placed at fixed coordinates outside it.
14
+ *
15
+ * Deliberately not a MUI Tooltip: it is permanently open and re-renders on
16
+ * every pan frame, and an open popper re-runs its whole modifier chain (~17
17
+ * getBoundingClientRect calls) on every render of its parent, since MUI's
18
+ * `BasePopper` calls `forceUpdate()` from a dep-less effect. Here the anchor is
19
+ * measured once per hover, not per mousemove — only `coordX` changes as the
20
+ * mouse moves, and that needs no measurement.
21
+ */
22
+ export declare function GuideLabel({ coordX, viewWidth, stickyTop, children, }: {
23
+ coordX: number;
24
+ viewWidth: number;
25
+ stickyTop: string | undefined;
26
+ children: React.ReactNode;
27
+ }): import("react").JSX.Element;
28
+ /**
29
+ * The bp coordinates of a rubberband selection, one label just outside each edge
30
+ * of the span. Renders inside the span, so the edges are its own box. A label
31
+ * with no room outside its edge flips inside instead, which is why the span it
32
+ * has to fit in is a prop.
33
+ */
34
+ export declare function SpanEdgeLabels({ stickyTop, left, right, insideLeft, insideRight, }: {
35
+ stickyTop: string | undefined;
36
+ left: React.ReactNode;
37
+ right: React.ReactNode;
38
+ insideLeft: boolean;
39
+ insideRight: boolean;
40
+ }): import("react").JSX.Element;
@@ -0,0 +1,119 @@
1
+ import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useEffect, useRef, useState } from 'react';
3
+ import { MUI_TOOLTIP_Z_INDEX } from '@jbrowse/core/ui/zIndexes';
4
+ import { makeStyles } from '@jbrowse/core/util/tss-react';
5
+ import { alpha } from '@mui/material';
6
+ import { createPortal } from 'react-dom';
7
+ // roughly how wide a coordinate label is. the guide clamps itself half of this
8
+ // from either border, and a rubberband label that would hang off a border goes
9
+ // inside its edge instead — the popper's `preventOverflow`, without the popper
10
+ export const LABEL_WIDTH = 100;
11
+ // gap between the bottom of a guide label and the top of the guide it labels
12
+ const LABEL_GAP = 3;
13
+ const useStyles = makeStyles()(theme => ({
14
+ // zero height so it takes no flow space while sticking with the scalebar.
15
+ // sticky positioning makes this a stacking context, so the z-index has to
16
+ // live here rather than on the labels it traps
17
+ anchor: {
18
+ height: 0,
19
+ zIndex: 1002,
20
+ },
21
+ label: {
22
+ background: alpha(theme.palette.grey[700], 0.92),
23
+ color: theme.palette.common.white,
24
+ borderRadius: theme.shape.borderRadius,
25
+ padding: '2px 6px',
26
+ fontSize: theme.typography.pxToRem(11),
27
+ fontWeight: theme.typography.fontWeightMedium,
28
+ lineHeight: 1.2,
29
+ whiteSpace: 'nowrap',
30
+ pointerEvents: 'none',
31
+ },
32
+ spanLabel: {
33
+ position: 'absolute',
34
+ },
35
+ guideLabel: {
36
+ position: 'fixed',
37
+ transform: 'translateX(-50%)',
38
+ zIndex: MUI_TOOLTIP_Z_INDEX,
39
+ },
40
+ leftOfEdge: {
41
+ right: '100%',
42
+ marginRight: 2,
43
+ },
44
+ rightOfEdge: {
45
+ left: '100%',
46
+ marginLeft: 2,
47
+ },
48
+ insideLeftEdge: {
49
+ left: 0,
50
+ },
51
+ insideRightEdge: {
52
+ right: 0,
53
+ },
54
+ }));
55
+ function anchorStyle(stickyTop) {
56
+ return stickyTop === undefined
57
+ ? { position: 'relative' }
58
+ : { position: 'sticky', top: stickyTop };
59
+ }
60
+ /**
61
+ * The bp coordinate under a vertical guide, drawn just above the top of the
62
+ * guide line so it covers neither the line nor the cursor hovering the scalebar
63
+ * the line starts at.
64
+ *
65
+ * A zero-height anchor marks that spot in the flow (`stickyTop` pins it to the
66
+ * scalebar it rides once that scrolls away) but the label itself portals to the
67
+ * body: sitting above the guide means sitting above the top of the tracks
68
+ * container, and that container's `contain: layout` traps its children in a
69
+ * stacking context the sticky LGV header (z-index 850, opaque background)
70
+ * paints over. So the anchor's viewport position is measured and the label
71
+ * placed at fixed coordinates outside it.
72
+ *
73
+ * Deliberately not a MUI Tooltip: it is permanently open and re-renders on
74
+ * every pan frame, and an open popper re-runs its whole modifier chain (~17
75
+ * getBoundingClientRect calls) on every render of its parent, since MUI's
76
+ * `BasePopper` calls `forceUpdate()` from a dep-less effect. Here the anchor is
77
+ * measured once per hover, not per mousemove — only `coordX` changes as the
78
+ * mouse moves, and that needs no measurement.
79
+ */
80
+ export function GuideLabel({ coordX, viewWidth, stickyTop, children, }) {
81
+ const { classes, cx } = useStyles();
82
+ const anchorRef = useRef(null);
83
+ const [anchorPos, setAnchorPos] = useState();
84
+ useEffect(() => {
85
+ const measure = () => {
86
+ const el = anchorRef.current;
87
+ if (el) {
88
+ const { left, top } = el.getBoundingClientRect();
89
+ setAnchorPos({ left, top, viewportHeight: window.innerHeight });
90
+ }
91
+ };
92
+ measure();
93
+ // capture phase: the anchor can ride any scrolling ancestor, not just the
94
+ // window
95
+ window.addEventListener('scroll', measure, true);
96
+ window.addEventListener('resize', measure);
97
+ return () => {
98
+ window.removeEventListener('scroll', measure, true);
99
+ window.removeEventListener('resize', measure);
100
+ };
101
+ }, [stickyTop]);
102
+ const clampedX = Math.min(Math.max(coordX, LABEL_WIDTH / 2), viewWidth - LABEL_WIDTH / 2);
103
+ return (_jsxs(_Fragment, { children: [_jsx("div", { ref: anchorRef, className: classes.anchor, style: anchorStyle(stickyTop) }), anchorPos
104
+ ? createPortal(_jsx("div", { className: cx(classes.label, classes.guideLabel), style: {
105
+ left: anchorPos.left + clampedX,
106
+ bottom: anchorPos.viewportHeight - anchorPos.top + LABEL_GAP,
107
+ }, children: children }), document.body)
108
+ : null] }));
109
+ }
110
+ /**
111
+ * The bp coordinates of a rubberband selection, one label just outside each edge
112
+ * of the span. Renders inside the span, so the edges are its own box. A label
113
+ * with no room outside its edge flips inside instead, which is why the span it
114
+ * has to fit in is a prop.
115
+ */
116
+ export function SpanEdgeLabels({ stickyTop, left, right, insideLeft, insideRight, }) {
117
+ const { classes, cx } = useStyles();
118
+ return (_jsxs("div", { className: classes.anchor, style: anchorStyle(stickyTop), children: [_jsx("div", { className: cx(classes.label, classes.spanLabel, insideLeft ? classes.insideLeftEdge : classes.leftOfEdge), children: left }), _jsx("div", { className: cx(classes.label, classes.spanLabel, insideRight ? classes.insideRightEdge : classes.rightOfEdge), children: right })] }));
119
+ }