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

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