@jbrowse/core 5.0.0-beta.11 → 5.0.0-beta.14

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 (439) hide show
  1. package/README.md +450 -132
  2. package/esm/BaseFeatureWidget/BaseFeatureDetail/ArrayValue.d.ts +3 -2
  3. package/esm/BaseFeatureWidget/BaseFeatureDetail/ArrayValue.js +4 -2
  4. package/esm/BaseFeatureWidget/BaseFeatureDetail/Attributes.d.ts +6 -2
  5. package/esm/BaseFeatureWidget/BaseFeatureDetail/Attributes.js +18 -3
  6. package/esm/BaseFeatureWidget/BaseFeatureDetail/BaseAttributes.d.ts +2 -1
  7. package/esm/BaseFeatureWidget/BaseFeatureDetail/BaseAttributes.js +4 -2
  8. package/esm/BaseFeatureWidget/BaseFeatureDetail/BaseCard.d.ts +2 -1
  9. package/esm/BaseFeatureWidget/BaseFeatureDetail/BaseCard.js +4 -2
  10. package/esm/BaseFeatureWidget/BaseFeatureDetail/BaseCoreDetails.d.ts +2 -1
  11. package/esm/BaseFeatureWidget/BaseFeatureDetail/BaseCoreDetails.js +4 -2
  12. package/esm/BaseFeatureWidget/BaseFeatureDetail/BasicValue.d.ts +5 -4
  13. package/esm/BaseFeatureWidget/BaseFeatureDetail/BasicValue.js +6 -4
  14. package/esm/BaseFeatureWidget/BaseFeatureDetail/CoreDetails.d.ts +2 -1
  15. package/esm/BaseFeatureWidget/BaseFeatureDetail/CoreDetails.js +4 -2
  16. package/esm/BaseFeatureWidget/BaseFeatureDetail/DataGridDetails.d.ts +3 -2
  17. package/esm/BaseFeatureWidget/BaseFeatureDetail/DataGridDetails.js +4 -2
  18. package/esm/BaseFeatureWidget/BaseFeatureDetail/FeatureDetails.js +2 -2
  19. package/esm/BaseFeatureWidget/BaseFeatureDetail/FeatureWash.d.ts +3 -2
  20. package/esm/BaseFeatureWidget/BaseFeatureDetail/FeatureWash.js +4 -2
  21. package/esm/BaseFeatureWidget/BaseFeatureDetail/FieldActionsButton.d.ts +3 -2
  22. package/esm/BaseFeatureWidget/BaseFeatureDetail/FieldActionsButton.js +4 -2
  23. package/esm/BaseFeatureWidget/BaseFeatureDetail/FieldName.d.ts +3 -2
  24. package/esm/BaseFeatureWidget/BaseFeatureDetail/FieldName.js +4 -2
  25. package/esm/BaseFeatureWidget/BaseFeatureDetail/Formatter.d.ts +3 -2
  26. package/esm/BaseFeatureWidget/BaseFeatureDetail/Formatter.js +4 -2
  27. package/esm/BaseFeatureWidget/BaseFeatureDetail/ParentFeatureLine.d.ts +3 -2
  28. package/esm/BaseFeatureWidget/BaseFeatureDetail/ParentFeatureLine.js +4 -2
  29. package/esm/BaseFeatureWidget/BaseFeatureDetail/SimpleField.d.ts +3 -2
  30. package/esm/BaseFeatureWidget/BaseFeatureDetail/SimpleField.js +4 -2
  31. package/esm/BaseFeatureWidget/BaseFeatureDetail/UriField.d.ts +3 -2
  32. package/esm/BaseFeatureWidget/BaseFeatureDetail/UriField.js +4 -2
  33. package/esm/BaseFeatureWidget/SequenceFeatureDetails/SequenceBody.d.ts +3 -2
  34. package/esm/BaseFeatureWidget/SequenceFeatureDetails/SequenceBody.js +4 -2
  35. package/esm/BaseFeatureWidget/SequenceFeatureDetails/SequenceFeatureDetails.d.ts +3 -1
  36. package/esm/BaseFeatureWidget/SequenceFeatureDetails/SequenceFeatureDetails.js +15 -24
  37. package/esm/BaseFeatureWidget/SequenceFeatureDetails/SequenceFeaturePanel.js +1 -1
  38. package/esm/BaseFeatureWidget/SequenceFeatureDetails/SequenceLegend.d.ts +3 -2
  39. package/esm/BaseFeatureWidget/SequenceFeatureDetails/SequenceLegend.js +4 -2
  40. package/esm/BaseFeatureWidget/SequenceFeatureDetails/SequencePanel.js +4 -4
  41. package/esm/BaseFeatureWidget/SequenceFeatureDetails/dialogs/FeatureSequenceDialog.d.ts +3 -1
  42. package/esm/BaseFeatureWidget/SequenceFeatureDetails/dialogs/FeatureSequenceDialog.js +2 -2
  43. package/esm/BaseFeatureWidget/SequenceFeatureDetails/dialogs/HelpDialog.d.ts +3 -2
  44. package/esm/BaseFeatureWidget/SequenceFeatureDetails/dialogs/HelpDialog.js +4 -2
  45. package/esm/BaseFeatureWidget/SequenceFeatureDetails/dialogs/SequenceDialog.d.ts +1 -2
  46. package/esm/BaseFeatureWidget/SequenceFeatureDetails/dialogs/SequenceDialog.js +2 -2
  47. package/esm/BaseFeatureWidget/SequenceFeatureDetails/dialogs/SequenceTypeSelector.d.ts +1 -2
  48. package/esm/BaseFeatureWidget/SequenceFeatureDetails/dialogs/SequenceTypeSelector.js +15 -36
  49. package/esm/BaseFeatureWidget/SequenceFeatureDetails/dialogs/TranscriptSelector.d.ts +3 -2
  50. package/esm/BaseFeatureWidget/SequenceFeatureDetails/dialogs/TranscriptSelector.js +4 -2
  51. package/esm/BaseFeatureWidget/SequenceFeatureDetails/featureTypeUtil.d.ts +4 -2
  52. package/esm/BaseFeatureWidget/SequenceFeatureDetails/featureTypeUtil.js +29 -20
  53. package/esm/BaseFeatureWidget/SequenceFeatureDetails/model.d.ts +13 -1
  54. package/esm/BaseFeatureWidget/SequenceFeatureDetails/model.js +28 -1
  55. package/esm/BaseFeatureWidget/SequenceFeatureDetails/seqtypes/CDNASequence.js +3 -3
  56. package/esm/BaseFeatureWidget/SequenceFeatureDetails/seqtypes/SequenceDisplay.js +2 -2
  57. package/esm/BaseFeatureWidget/stateModelFactory.d.ts +9 -0
  58. package/esm/BaseFeatureWidget/stateModelFactory.js +11 -0
  59. package/esm/BaseFeatureWidget/types.d.ts +2 -0
  60. package/esm/PluginManager.d.ts +7 -3
  61. package/esm/PluginManager.js +12 -3
  62. package/esm/ReExports/coreModules.generated.js +538 -518
  63. package/esm/ReExports/coreWorkerModules.generated.js +456 -438
  64. package/esm/ReExports/lazify.js +3 -2
  65. package/esm/ReExports/list.js +22 -6
  66. package/esm/ReExports/names.d.ts +1 -0
  67. package/esm/ReExports/names.generated.d.ts +2 -0
  68. package/esm/ReExports/names.generated.js +566 -0
  69. package/esm/ReExports/names.js +3 -0
  70. package/esm/TextSearch/TextSearchManager.d.ts +3 -3
  71. package/esm/TextSearch/TextSearchManager.js +6 -13
  72. package/esm/assemblyManager/assembly.d.ts +9 -0
  73. package/esm/assemblyManager/assembly.js +13 -0
  74. package/esm/assemblyManager/assemblyConfigSchema.d.ts +6 -1
  75. package/esm/assemblyManager/assemblyConfigSchema.js +23 -22
  76. package/esm/assemblyManager/assemblyManager.d.ts +11 -0
  77. package/esm/assemblyManager/assemblyManager.js +2 -0
  78. package/esm/assemblyManager/expandAssemblyConfigShorthand.d.ts +9 -0
  79. package/esm/assemblyManager/expandAssemblyConfigShorthand.js +23 -0
  80. package/esm/checkPlugins.js +10 -4
  81. package/esm/configuration/configurationSchema.d.ts +51 -100
  82. package/esm/configuration/configurationSchema.js +59 -225
  83. package/esm/configuration/configurationSchemaUnion.d.ts +2 -1
  84. package/esm/configuration/configurationSchemaUnion.js +2 -1
  85. package/esm/configuration/configurationSlot.d.ts +18 -64
  86. package/esm/configuration/configurationSlot.js +32 -98
  87. package/esm/configuration/fillLocations.d.ts +4 -2
  88. package/esm/configuration/fillLocations.js +9 -3
  89. package/esm/configuration/formatAboutConfigSchema.d.ts +2 -2
  90. package/esm/configuration/formatAboutConfigSchema.js +2 -2
  91. package/esm/configuration/formatDetailsConfigSchema.d.ts +2 -2
  92. package/esm/configuration/formatDetailsConfigSchema.js +7 -5
  93. package/esm/configuration/getConf.d.ts +7 -36
  94. package/esm/configuration/getConf.js +20 -41
  95. package/esm/configuration/index.d.ts +4 -3
  96. package/esm/configuration/index.js +3 -2
  97. package/esm/configuration/partitionAdvanced.d.ts +12 -0
  98. package/esm/configuration/partitionAdvanced.js +42 -0
  99. package/esm/configuration/plot.d.ts +6 -0
  100. package/esm/configuration/plot.js +56 -9
  101. package/esm/configuration/readConfObject.d.ts +15 -17
  102. package/esm/configuration/readConfObject.js +19 -50
  103. package/esm/configuration/schemaRegistry.d.ts +0 -2
  104. package/esm/configuration/schemaTypes.js +5 -1
  105. package/esm/configuration/slotFacade.js +2 -2
  106. package/esm/configuration/snapshotPreprocess.d.ts +42 -18
  107. package/esm/configuration/snapshotPreprocess.js +95 -37
  108. package/esm/configuration/tabixShorthand.js +1 -3
  109. package/esm/configuration/types.d.ts +60 -159
  110. package/esm/data_adapters/BaseAdapter/BaseAdapter.d.ts +7 -0
  111. package/esm/data_adapters/BaseAdapter/BaseAdapter.js +7 -0
  112. package/esm/data_adapters/BaseAdapter/BaseFeatureDataAdapter.d.ts +0 -22
  113. package/esm/data_adapters/BaseAdapter/BaseFeatureDataAdapter.js +0 -55
  114. package/esm/data_adapters/BaseAdapter/index.d.ts +0 -1
  115. package/esm/data_adapters/BaseAdapter/index.js +0 -1
  116. package/esm/data_adapters/BaseAdapter/rowSources.d.ts +2 -2
  117. package/esm/data_adapters/BaseAdapter/types.d.ts +1 -0
  118. package/esm/data_adapters/CytobandAdapter/configSchema.d.ts +2 -0
  119. package/esm/data_adapters/CytobandAdapter/configSchema.js +5 -0
  120. package/esm/data_adapters/dataAdapterCache.d.ts +25 -13
  121. package/esm/data_adapters/dataAdapterCache.js +68 -24
  122. package/esm/data_adapters/getFeatureAdapter.d.ts +9 -0
  123. package/esm/data_adapters/getFeatureAdapter.js +17 -0
  124. package/esm/pluggableElementTypes/DisplayType.d.ts +7 -0
  125. package/esm/pluggableElementTypes/DisplayType.js +7 -0
  126. package/esm/pluggableElementTypes/RpcMethodType.d.ts +7 -0
  127. package/esm/pluggableElementTypes/RpcMethodType.js +9 -0
  128. package/esm/pluggableElementTypes/addMenuItems.d.ts +2 -1
  129. package/esm/pluggableElementTypes/addMenuItems.js +2 -1
  130. package/esm/pluggableElementTypes/models/BaseConnectionModelFactory.d.ts +2 -0
  131. package/esm/pluggableElementTypes/models/BaseConnectionModelFactory.js +2 -0
  132. package/esm/pluggableElementTypes/models/BaseDisplayModel.d.ts +40 -5
  133. package/esm/pluggableElementTypes/models/BaseDisplayModel.js +57 -9
  134. package/esm/pluggableElementTypes/models/BaseTrackModel.d.ts +5 -7
  135. package/esm/pluggableElementTypes/models/BaseTrackModel.js +9 -10
  136. package/esm/pluggableElementTypes/models/BaseViewModel.d.ts +2 -0
  137. package/esm/pluggableElementTypes/models/BaseViewModel.js +2 -0
  138. package/esm/pluggableElementTypes/models/InternetAccountModel.d.ts +3 -0
  139. package/esm/pluggableElementTypes/models/InternetAccountModel.js +3 -0
  140. package/esm/pluggableElementTypes/models/baseConnectionConfig.d.ts +3 -0
  141. package/esm/pluggableElementTypes/models/baseConnectionConfig.js +3 -0
  142. package/esm/pluggableElementTypes/models/baseInternetAccountConfig.d.ts +3 -1
  143. package/esm/pluggableElementTypes/models/baseInternetAccountConfig.js +3 -1
  144. package/esm/pluggableElementTypes/models/baseTrackConfig.js +12 -1
  145. package/esm/pluggableElementTypes/models/components/SaveTrackData.js +2 -2
  146. package/esm/pluggableElementTypes/models/expandTrackConfigShorthand.d.ts +1 -1
  147. package/esm/pluggableElementTypes/models/expandTrackConfigShorthand.js +1 -1
  148. package/esm/pluginDefinitions.d.ts +7 -0
  149. package/esm/pluginDefinitions.js +20 -0
  150. package/esm/rpc/RpcRegistry.d.ts +2 -11
  151. package/esm/rpc/byteBudget.d.ts +15 -0
  152. package/esm/rpc/byteBudget.js +23 -0
  153. package/esm/rpc/configSchema.d.ts +2 -0
  154. package/esm/rpc/configSchema.js +3 -1
  155. package/esm/rpc/coreRpcMethods.d.ts +1 -2
  156. package/esm/rpc/coreRpcMethods.js +1 -2
  157. package/esm/rpc/explainTransferError.js +3 -3
  158. package/esm/rpc/methods/CoreGetEncodedLayers.d.ts +2 -2
  159. package/esm/rpc/methods/CoreGetEncodedLayers.js +7 -5
  160. package/esm/rpc/methods/CoreLoadTrackCode.d.ts +17 -0
  161. package/esm/rpc/methods/CoreLoadTrackCode.js +24 -0
  162. package/esm/rpc/methods/layerFeatures.d.ts +9 -6
  163. package/esm/rpc/methods/layerFeatures.js +21 -5
  164. package/esm/ui/ActionLink.d.ts +3 -2
  165. package/esm/ui/ActionLink.js +4 -2
  166. package/esm/ui/AddCustomPluginDialog.d.ts +3 -2
  167. package/esm/ui/AddCustomPluginDialog.js +6 -4
  168. package/esm/ui/AppLogo.js +43 -3
  169. package/esm/ui/BaseTooltip.d.ts +3 -2
  170. package/esm/ui/BaseTooltip.js +4 -2
  171. package/esm/ui/CascadingMenu.js +14 -12
  172. package/esm/ui/CascadingMenuButton.d.ts +2 -2
  173. package/esm/ui/CascadingMenuButton.js +5 -4
  174. package/esm/ui/CascadingMenuHelpDialog.d.ts +3 -2
  175. package/esm/ui/CascadingMenuHelpDialog.js +4 -2
  176. package/esm/ui/CascadingMenuHelpIconButton.d.ts +4 -3
  177. package/esm/ui/CascadingMenuHelpIconButton.js +9 -5
  178. package/esm/ui/ColorPicker.d.ts +5 -4
  179. package/esm/ui/ColorPicker.js +6 -4
  180. package/esm/ui/ContextMenu.d.ts +1 -1
  181. package/esm/ui/ContextMenu.js +1 -1
  182. package/esm/ui/CopyToClipboardButton.d.ts +3 -2
  183. package/esm/ui/CopyToClipboardButton.js +4 -2
  184. package/esm/ui/Crosshairs.js +13 -10
  185. package/esm/ui/DOMPurifySanitizedHTML.d.ts +3 -2
  186. package/esm/ui/DOMPurifySanitizedHTML.js +4 -2
  187. package/esm/ui/DataGridFlexContainer.d.ts +3 -2
  188. package/esm/ui/DataGridFlexContainer.js +4 -2
  189. package/esm/ui/Dialog.d.ts +1 -1
  190. package/esm/ui/Dialog.js +5 -4
  191. package/esm/ui/DropDownMenu.js +2 -2
  192. package/esm/ui/EditableTypography.d.ts +1 -1
  193. package/esm/ui/EditableTypography.js +3 -2
  194. package/esm/ui/ErrorActions.d.ts +3 -2
  195. package/esm/ui/ErrorActions.js +4 -2
  196. package/esm/ui/ErrorBanner.d.ts +2 -2
  197. package/esm/ui/ErrorBanner.js +3 -2
  198. package/esm/ui/ErrorBar.d.ts +3 -2
  199. package/esm/ui/ErrorBar.js +4 -2
  200. package/esm/ui/ErrorMessage.d.ts +3 -2
  201. package/esm/ui/ErrorMessage.js +4 -2
  202. package/esm/ui/ErrorMessageStackTraceContents.d.ts +3 -2
  203. package/esm/ui/ErrorMessageStackTraceContents.js +4 -2
  204. package/esm/ui/ErrorMessageStackTraceDialog.d.ts +3 -2
  205. package/esm/ui/ErrorMessageStackTraceDialog.js +4 -2
  206. package/esm/ui/ErrorOverlay.d.ts +3 -2
  207. package/esm/ui/ErrorOverlay.js +4 -2
  208. package/esm/ui/ExportSvgDialog.d.ts +3 -2
  209. package/esm/ui/ExportSvgDialog.js +4 -2
  210. package/esm/ui/ExternalLink.d.ts +2 -1
  211. package/esm/ui/ExternalLink.js +4 -2
  212. package/esm/ui/FactoryResetDialog.d.ts +3 -2
  213. package/esm/ui/FactoryResetDialog.js +4 -2
  214. package/esm/ui/FatalErrorDialog.d.ts +3 -2
  215. package/esm/ui/FatalErrorDialog.js +6 -4
  216. package/esm/ui/FileDropZone.d.ts +3 -2
  217. package/esm/ui/FileDropZone.js +4 -2
  218. package/esm/ui/FileSelector/LocalFileChooser.js +4 -4
  219. package/esm/ui/FileSelector/LocationInput.d.ts +3 -2
  220. package/esm/ui/FileSelector/LocationInput.js +4 -2
  221. package/esm/ui/FileSelector/SourceTypeSelector.d.ts +3 -2
  222. package/esm/ui/FileSelector/SourceTypeSelector.js +8 -6
  223. package/esm/ui/GpuFallbackButton.d.ts +3 -2
  224. package/esm/ui/GpuFallbackButton.js +4 -2
  225. package/esm/ui/HoverMenu.d.ts +2 -2
  226. package/esm/ui/HoverMenu.js +7 -3
  227. package/esm/ui/HoverTooltip.d.ts +3 -2
  228. package/esm/ui/HoverTooltip.js +4 -2
  229. package/esm/ui/Icons.d.ts +5 -5
  230. package/esm/ui/Icons.js +11 -10
  231. package/esm/ui/InlineMenuControls.d.ts +2 -2
  232. package/esm/ui/InlineMenuControls.js +4 -3
  233. package/esm/ui/JexlFilterRowEditors.d.ts +4 -4
  234. package/esm/ui/JexlFilterRowEditors.js +9 -8
  235. package/esm/ui/LabeledCheckbox.d.ts +3 -2
  236. package/esm/ui/LabeledCheckbox.js +4 -2
  237. package/esm/ui/LazyBaseTooltip.d.ts +12 -3
  238. package/esm/ui/LazyBaseTooltip.js +4 -2
  239. package/esm/ui/LegendSwatchGlyph.js +1 -0
  240. package/esm/ui/LoadingDots.d.ts +2 -1
  241. package/esm/ui/LoadingDots.js +4 -2
  242. package/esm/ui/LoadingEllipses.d.ts +5 -2
  243. package/esm/ui/LoadingEllipses.js +5 -3
  244. package/esm/ui/LoadingOverlay.d.ts +3 -2
  245. package/esm/ui/LoadingOverlay.js +4 -2
  246. package/esm/ui/LoadingProgress.d.ts +3 -2
  247. package/esm/ui/LoadingProgress.js +4 -2
  248. package/esm/ui/Logo.d.ts +2 -2
  249. package/esm/ui/Logo.js +9 -8
  250. package/esm/ui/MenuItemChevron.d.ts +2 -2
  251. package/esm/ui/MenuItemChevron.js +3 -2
  252. package/esm/ui/MenuItemEndDecoration.d.ts +2 -2
  253. package/esm/ui/MenuItemEndDecoration.js +3 -2
  254. package/esm/ui/MenuItemTrailing.d.ts +2 -2
  255. package/esm/ui/MenuItemTrailing.js +7 -6
  256. package/esm/ui/MenuTypes.d.ts +21 -1
  257. package/esm/ui/MenuTypes.js +20 -0
  258. package/esm/ui/MonospaceTextField.d.ts +3 -2
  259. package/esm/ui/MonospaceTextField.js +4 -2
  260. package/esm/ui/NumberTextField.d.ts +2 -2
  261. package/esm/ui/NumberTextField.js +4 -2
  262. package/esm/ui/PaletteContext.d.ts +11 -9
  263. package/esm/ui/PaletteContext.js +33 -18
  264. package/esm/ui/PluginStoreCard.d.ts +3 -2
  265. package/esm/ui/PluginStoreCard.js +4 -2
  266. package/esm/ui/PopoverPicker.d.ts +3 -2
  267. package/esm/ui/PopoverPicker.js +4 -2
  268. package/esm/ui/PrerenderedCanvas.d.ts +2 -2
  269. package/esm/ui/PrerenderedCanvas.js +3 -2
  270. package/esm/ui/RedErrorMessageBox.d.ts +3 -2
  271. package/esm/ui/RedErrorMessageBox.js +4 -2
  272. package/esm/ui/RefNameAutocomplete/EndAdornment.d.ts +3 -2
  273. package/esm/ui/RefNameAutocomplete/EndAdornment.js +4 -2
  274. package/esm/ui/RefNameAutocomplete/HelpDialog.d.ts +3 -2
  275. package/esm/ui/RefNameAutocomplete/HelpDialog.js +4 -2
  276. package/esm/ui/ReplaceCurrentViewButton.d.ts +3 -2
  277. package/esm/ui/ReplaceCurrentViewButton.js +4 -2
  278. package/esm/ui/ResizeHandle.d.ts +2 -2
  279. package/esm/ui/ResizeHandle.js +3 -2
  280. package/esm/ui/SanitizedHTML.d.ts +3 -2
  281. package/esm/ui/SanitizedHTML.js +6 -4
  282. package/esm/ui/ScrollChrome.d.ts +3 -2
  283. package/esm/ui/ScrollChrome.js +4 -2
  284. package/esm/ui/ScrollEdgeShadow.d.ts +2 -2
  285. package/esm/ui/ScrollEdgeShadow.js +2 -2
  286. package/esm/ui/SessionJsonPanel.d.ts +3 -2
  287. package/esm/ui/SessionJsonPanel.js +4 -2
  288. package/esm/ui/ShareLinkField.d.ts +3 -2
  289. package/esm/ui/ShareLinkField.js +4 -2
  290. package/esm/ui/SingleSlider.d.ts +2 -2
  291. package/esm/ui/SingleSlider.js +4 -2
  292. package/esm/ui/SliderTooltip.d.ts +2 -1
  293. package/esm/ui/SliderTooltip.js +4 -2
  294. package/esm/ui/SnackbarContents.d.ts +3 -2
  295. package/esm/ui/SnackbarContents.js +4 -2
  296. package/esm/ui/SnackbarModel.d.ts +2 -0
  297. package/esm/ui/SnackbarModel.js +2 -0
  298. package/esm/ui/StackTraceButton.d.ts +3 -2
  299. package/esm/ui/StackTraceButton.js +4 -2
  300. package/esm/ui/StatusProgressBar.d.ts +3 -2
  301. package/esm/ui/StatusProgressBar.js +4 -2
  302. package/esm/ui/SubmitForm.d.ts +2 -1
  303. package/esm/ui/SubmitForm.js +4 -2
  304. package/esm/ui/SvgColorLegend.d.ts +3 -4
  305. package/esm/ui/SvgColorLegend.js +27 -18
  306. package/esm/ui/TagTextField.d.ts +2 -2
  307. package/esm/ui/TagTextField.js +4 -2
  308. package/esm/ui/ViewLoadingScreen.d.ts +3 -2
  309. package/esm/ui/ViewLoadingScreen.js +4 -2
  310. package/esm/ui/buildExtraTrackMenuItems.d.ts +2 -2
  311. package/esm/ui/colorScale.d.ts +5 -1
  312. package/esm/ui/colorScale.js +12 -10
  313. package/esm/ui/colors.d.ts +42 -31
  314. package/esm/ui/colors.js +85 -48
  315. package/esm/ui/filterMenuItems.d.ts +10 -31
  316. package/esm/ui/filterMenuItems.js +13 -14
  317. package/esm/ui/index.d.ts +1 -1
  318. package/esm/ui/index.js +1 -1
  319. package/esm/ui/launchTargetsMenuItem.js +9 -13
  320. package/esm/ui/legendMenuItem.d.ts +4 -4
  321. package/esm/ui/legendMenuItem.js +4 -4
  322. package/esm/ui/menuItemAdornment.d.ts +1 -1
  323. package/esm/ui/menuItemAdornment.js +1 -1
  324. package/esm/ui/menuItems.d.ts +1 -1
  325. package/esm/ui/menuItems.js +1 -1
  326. package/esm/ui/menuLabels.d.ts +2 -2
  327. package/esm/ui/menuLabels.js +2 -2
  328. package/esm/ui/multiTrackMenuItems.d.ts +2 -2
  329. package/esm/ui/palette.d.ts +2 -2
  330. package/esm/ui/palette.js +10 -10
  331. package/esm/ui/radioSubMenu.d.ts +5 -3
  332. package/esm/ui/radioSubMenu.js +2 -2
  333. package/esm/ui/rampKey.d.ts +15 -0
  334. package/esm/ui/rampKey.js +17 -0
  335. package/esm/ui/showSubMenu.d.ts +0 -5
  336. package/esm/ui/showSubMenu.js +6 -15
  337. package/esm/ui/theme.d.ts +2 -2
  338. package/esm/ui/theme.js +1 -1
  339. package/esm/ui/useAssemblySelection.d.ts +2 -0
  340. package/esm/ui/useMouseTracking.d.ts +8 -20
  341. package/esm/ui/useMouseTracking.js +23 -62
  342. package/esm/ui/usePlacedMenuFocus.d.ts +19 -0
  343. package/esm/ui/usePlacedMenuFocus.js +28 -0
  344. package/esm/util/Base1DViewModel.d.ts +5 -3
  345. package/esm/util/Base1DViewModel.js +5 -3
  346. package/esm/util/SvgCanvas.js +1 -1
  347. package/esm/util/aggregateFieldName.d.ts +1 -10
  348. package/esm/util/aggregateFieldName.js +1 -8
  349. package/esm/util/alignedBytes.d.ts +19 -0
  350. package/esm/util/alignedBytes.js +37 -0
  351. package/esm/util/analytics.d.ts +6 -9
  352. package/esm/util/analytics.js +148 -15
  353. package/esm/util/bezierConnector.d.ts +20 -0
  354. package/esm/util/bezierConnector.js +34 -96
  355. package/esm/util/cacheBudgets.d.ts +3 -0
  356. package/esm/util/cacheBudgets.js +3 -0
  357. package/esm/util/categoricalField.d.ts +24 -4
  358. package/esm/util/categoricalField.js +38 -5
  359. package/esm/util/cellMatches.js +14 -14
  360. package/esm/util/cellsStep.d.ts +3 -5
  361. package/esm/util/cellsStep.js +31 -29
  362. package/esm/util/color/index.d.ts +1 -1
  363. package/esm/util/color/index.js +2 -2
  364. package/esm/util/color-bits/bit.js +1 -1
  365. package/esm/util/color-bits/parse.js +28 -17
  366. package/esm/util/colorBits.d.ts +15 -4
  367. package/esm/util/colorBits.js +38 -15
  368. package/esm/util/colorRamp.d.ts +3 -3
  369. package/esm/util/colorRamp.js +20 -2
  370. package/esm/util/colorScale.d.ts +123 -22
  371. package/esm/util/colorScale.js +157 -28
  372. package/esm/util/colorSchemes.d.ts +7 -3
  373. package/esm/util/colorSchemes.js +8 -2
  374. package/esm/util/createSvgRasterCanvas.d.ts +14 -1
  375. package/esm/util/createSvgRasterCanvas.js +36 -12
  376. package/esm/util/diagonalizeRegions.js +18 -9
  377. package/esm/util/featureTransforms.d.ts +2 -2
  378. package/esm/util/featureTransforms.js +85 -135
  379. package/esm/util/fileHandleStore.js +5 -0
  380. package/esm/util/groupKeys.d.ts +5 -4
  381. package/esm/util/groupKeys.js +15 -9
  382. package/esm/util/index.js +1 -1
  383. package/esm/util/installFetch.d.ts +2 -2
  384. package/esm/util/installPrerequisiteFetch.d.ts +8 -3
  385. package/esm/util/installPrerequisiteFetch.js +9 -7
  386. package/esm/util/io/RemoteFileWithRangeCache.d.ts +1 -1
  387. package/esm/util/io/RemoteFileWithRangeCache.js +1 -1
  388. package/esm/util/isoformRank.d.ts +39 -0
  389. package/esm/util/isoformRank.js +118 -0
  390. package/esm/util/jexl.js +1 -1
  391. package/esm/util/layouts/GranularRectLayout.d.ts +19 -3
  392. package/esm/util/layouts/GranularRectLayout.js +57 -34
  393. package/esm/util/leadingEdgeAutorun.d.ts +9 -1
  394. package/esm/util/leadingEdgeAutorun.js +5 -2
  395. package/esm/util/markEncoding.d.ts +10 -8
  396. package/esm/util/markEncoding.js +50 -12
  397. package/esm/util/markEncodingTypes.d.ts +77 -21
  398. package/esm/util/originCut.d.ts +14 -0
  399. package/esm/util/originCut.js +19 -0
  400. package/esm/util/paintLayer.d.ts +1 -1
  401. package/esm/util/paintLayer.js +4 -3
  402. package/esm/util/pathSeries.d.ts +18 -0
  403. package/esm/util/pathSeries.js +143 -0
  404. package/esm/util/pressOwner.d.ts +20 -0
  405. package/esm/util/pressOwner.js +26 -0
  406. package/esm/util/quantileExtent.d.ts +23 -1
  407. package/esm/util/quantileExtent.js +25 -2
  408. package/esm/util/rowStackGeometry.d.ts +1 -1
  409. package/esm/util/rowStackGeometry.js +1 -1
  410. package/esm/util/sessionActivity.d.ts +36 -0
  411. package/esm/util/sessionActivity.js +88 -0
  412. package/esm/util/stepOutputs.d.ts +165 -0
  413. package/esm/util/stepOutputs.js +201 -0
  414. package/esm/util/stepTables.d.ts +7 -3
  415. package/esm/util/stepTables.js +86 -3
  416. package/esm/util/systemColorScheme.d.ts +4 -0
  417. package/esm/util/systemColorScheme.js +21 -0
  418. package/esm/util/tabix.d.ts +1 -1
  419. package/esm/util/tabix.js +1 -1
  420. package/esm/util/temporaryAssembly.d.ts +2 -2
  421. package/esm/util/temporaryAssembly.js +2 -3
  422. package/esm/util/thresholdScale.d.ts +1 -1
  423. package/esm/util/thresholdScale.js +1 -1
  424. package/esm/util/trackConfigDelta.d.ts +1 -1
  425. package/esm/util/tracks.d.ts +25 -15
  426. package/esm/util/tracks.js +68 -44
  427. package/esm/util/types/index.d.ts +15 -7
  428. package/esm/util/types/index.js +21 -2
  429. package/esm/util/usePanZoom.js +4 -10
  430. package/esm/util/useRowVirtualScroll.d.ts +1 -0
  431. package/esm/util/windowStep.d.ts +6 -0
  432. package/esm/util/windowStep.js +153 -0
  433. package/package.json +27 -16
  434. package/esm/data_adapters/BaseAdapter/featureDensity.d.ts +0 -40
  435. package/esm/data_adapters/BaseAdapter/featureDensity.js +0 -31
  436. package/esm/rpc/methods/CoreGetFeatureDensity.d.ts +0 -11
  437. package/esm/rpc/methods/CoreGetFeatureDensity.js +0 -22
  438. package/esm/rpc/methods/CoreLoadAdapterCode.d.ts +0 -13
  439. package/esm/rpc/methods/CoreLoadAdapterCode.js +0 -16
@@ -1,14 +1,59 @@
1
1
  import { effectiveRenderer, getGraphicsCapabilities, } from '@jbrowse/render-core/graphicsCapabilities';
2
2
  import { readConfObject } from '../configuration/index.js';
3
3
  import { isElectron, rIC } from '../util/index.js';
4
+ import { createSessionActivity, describeSession, tallyTypes, } from './sessionActivity.js';
5
+ import { getConfAssemblyNamesOrNone } from './tracks.js';
6
+ const analyticsUrl = 'https://analytics.jbrowse.org/api/v1';
7
+ // Ties a page load's end reports to its start report. It lives in memory only,
8
+ // so a reload gets a new one and nothing follows a user from load to load.
9
+ let pageLoadId;
10
+ function getPageLoadId() {
11
+ pageLoadId ??=
12
+ typeof crypto.randomUUID === 'function'
13
+ ? crypto.randomUUID()
14
+ : `${Date.now().toString(36)}-${Math.random().toString(36).slice(2)}`;
15
+ return pageLoadId;
16
+ }
17
+ // Names only, and only JBrowse's own: says whether a load was a link to a
18
+ // location or a set of tracks without saying which. Read when this module
19
+ // loads, because jbrowse-web folds `loc`, `tracks` and `assembly` into a
20
+ // `session` parameter before the report goes out.
21
+ const knownUrlParams = [
22
+ 'assembly',
23
+ 'config',
24
+ 'highlight',
25
+ 'loc',
26
+ 'nav',
27
+ 'session',
28
+ 'sessionName',
29
+ 'sessionTracks',
30
+ 'tracklist',
31
+ 'tracks',
32
+ ];
33
+ export function urlParamNames(search) {
34
+ const params = new URLSearchParams(search);
35
+ return knownUrlParams.filter(name => params.has(name)).join(',');
36
+ }
37
+ const initialUrlParams = typeof window === 'undefined' ? '' : urlParamNames(window.location.search);
38
+ function sessionTrackTypeCounts(session) {
39
+ const counts = {};
40
+ for (const track of session?.sessionTracks ?? []) {
41
+ const key = `sessionTrack-types-${track.type}`;
42
+ counts[key] = (counts[key] ?? 0) + 1;
43
+ }
44
+ return counts;
45
+ }
46
+ async function send(stats, init) {
47
+ const qs = new URLSearchParams(Object.entries(stats).map(([key, value]) => [key, String(value)])).toString();
48
+ await fetch(`${analyticsUrl}?${qs}`, init);
49
+ }
4
50
  // Both writers are fire-and-forget from several call sites, so they swallow
5
51
  // their own failures rather than rejecting: a floating rejected promise trips
6
52
  // the webpack-dev-server overlay (it listens for unhandledrejection), and an
7
53
  // analytics ping is never worth interrupting a session for.
8
54
  export async function writeAWSAnalytics(rootModel, initialTimestamp, sessionQuery) {
9
55
  try {
10
- const url = 'https://analytics.jbrowse.org/api/v1';
11
- const multiAssemblyTracks = rootModel.jbrowse.tracks.filter(track => readConfObject(track, 'assemblyNames').length > 1).length;
56
+ const multiAssemblyTracks = rootModel.jbrowse.tracks.filter(track => getConfAssemblyNamesOrNone(track).length > 1).length;
12
57
  // The rung createGpuHal built where a display has built one by idle time,
13
58
  // else the ladder's prediction with any page-wide pin applied — so a
14
59
  // session that fell back to Canvas2D is counted as Canvas2D rather than as
@@ -24,8 +69,11 @@ export async function writeAWSAnalytics(rootModel, initialTimestamp, sessionQuer
24
69
  const softwareRendering = capabilities.softwareWebgl ?? 'unknown';
25
70
  const { jbrowse: config, session, version: ver } = rootModel;
26
71
  const { tracks, assemblies, plugins } = config;
72
+ const shape = describeSession(session);
27
73
  // stats to be recorded in db
28
74
  const stats = {
75
+ event: 'start',
76
+ sid: getPageLoadId(),
29
77
  ver,
30
78
  'plugins-count': plugins?.length ?? 0,
31
79
  'plugin-names': plugins?.map(p => p.name).join(','),
@@ -33,6 +81,9 @@ export async function writeAWSAnalytics(rootModel, initialTimestamp, sessionQuer
33
81
  'tracks-count': tracks.length,
34
82
  'session-tracks-count': session?.sessionTracks.length ?? 0,
35
83
  'open-views': session?.views.length ?? 0,
84
+ 'view-types': tallyTypes(shape.viewTypes),
85
+ 'open-track-types': tallyTypes(shape.trackTypes),
86
+ 'url-params': initialUrlParams,
36
87
  'synteny-tracks-count': multiAssemblyTracks,
37
88
  // No `saved-sessions-count`: it counted localStorage keys matching
38
89
  // `localSaved-`, a format nothing has written since autosaved sessions
@@ -61,14 +112,8 @@ export async function writeAWSAnalytics(rootModel, initialTimestamp, sessionQuer
61
112
  const key = `track-types-${track.type}`;
62
113
  trackTypeCounts[key] = (trackTypeCounts[key] ?? 0) + 1;
63
114
  }
64
- const sessionTrackTypeCounts = {};
65
- for (const track of session?.sessionTracks ?? []) {
66
- const key = `sessionTrack-types-${track.type}`;
67
- sessionTrackTypeCounts[key] = (sessionTrackTypeCounts[key] ?? 0) + 1;
68
- }
69
- Object.assign(stats, trackTypeCounts, sessionTrackTypeCounts);
70
- const qs = new URLSearchParams(Object.entries(stats).map(([key, value]) => [key, String(value)])).toString();
71
- await fetch(`${url}?${qs}`);
115
+ Object.assign(stats, trackTypeCounts, sessionTrackTypeCounts(session));
116
+ await send(stats);
72
117
  }
73
118
  catch (e) {
74
119
  console.warn('Failed to write analytics to AWS.', e);
@@ -108,6 +153,83 @@ export async function writeGAAnalytics(rootModel, initialTimestamp) {
108
153
  console.warn('Failed to write analytics to GA.', e);
109
154
  }
110
155
  }
156
+ // What the page load's sessions held while in use, for the end report.
157
+ const activity = createSessionActivity();
158
+ let latestRootModel;
159
+ let endReportsInstalled = false;
160
+ let endReportsSent = 0;
161
+ let lastEndSignature;
162
+ let visibleMs = 0;
163
+ let visibleSince;
164
+ let visibleMsAtLastEnd = 0;
165
+ const maxEndReports = 10;
166
+ const resendAfterVisibleMs = 60_000;
167
+ // The end report says what a session came to hold: the view, track and widget
168
+ // types open when the tab was hidden and those opened at any point before.
169
+ // A tab is hidden many times before it closes and the close itself is not
170
+ // reliably observable, so each hide sends one, numbered by `seq`, when the
171
+ // session changed or another minute was spent on the page. The last one for a
172
+ // `sid` is the session's end.
173
+ export async function writeAWSSessionEnd() {
174
+ try {
175
+ if (!activity.watching || endReportsSent >= maxEndReports) {
176
+ return;
177
+ }
178
+ const seen = activity.stats();
179
+ const signature = JSON.stringify(seen);
180
+ if (signature === lastEndSignature &&
181
+ visibleMs - visibleMsAtLastEnd < resendAfterVisibleMs) {
182
+ return;
183
+ }
184
+ lastEndSignature = signature;
185
+ visibleMsAtLastEnd = visibleMs;
186
+ endReportsSent += 1;
187
+ const stats = {
188
+ event: 'end',
189
+ sid: getPageLoadId(),
190
+ seq: endReportsSent,
191
+ duration: Math.round(performance.now() / 1000),
192
+ 'visible-time': Math.round(visibleMs / 1000),
193
+ ...seen,
194
+ electron: isElectron,
195
+ jb2: true,
196
+ };
197
+ try {
198
+ const { session, version } = latestRootModel ?? {};
199
+ stats.ver = version;
200
+ stats['session-tracks-count'] = session?.sessionTracks.length ?? 0;
201
+ Object.assign(stats, sessionTrackTypeCounts(session));
202
+ }
203
+ catch {
204
+ // root model left its state tree; the accumulated types still go out
205
+ }
206
+ // keepalive lets the request outlive the page it was sent from
207
+ await send(stats, { keepalive: true });
208
+ }
209
+ catch (e) {
210
+ console.warn('Failed to write analytics to AWS.', e);
211
+ }
212
+ }
213
+ function installEndReports() {
214
+ if (!endReportsInstalled) {
215
+ endReportsInstalled = true;
216
+ if (document.visibilityState === 'visible') {
217
+ visibleSince = performance.now();
218
+ }
219
+ document.addEventListener('visibilitychange', () => {
220
+ if (document.visibilityState === 'hidden') {
221
+ if (visibleSince !== undefined) {
222
+ visibleMs += performance.now() - visibleSince;
223
+ visibleSince = undefined;
224
+ }
225
+ void writeAWSSessionEnd();
226
+ }
227
+ else {
228
+ visibleSince = performance.now();
229
+ }
230
+ });
231
+ }
232
+ }
111
233
  // One pageview per page load, not per pluginManager. jbrowse-web rebuilds the
112
234
  // whole pluginManager (and rootModel) whenever plugins change, and StrictMode
113
235
  // builds it twice on mount — without this guard each rebuild re-pings AWS and
@@ -115,9 +237,19 @@ export async function writeGAAnalytics(rootModel, initialTimestamp) {
115
237
  // growing the document on every plugin install.
116
238
  let analyticsSent = false;
117
239
  export function doAnalytics(rootModel, initialTimestamp, initialSessionQuery) {
118
- if (rootModel &&
119
- !analyticsSent &&
120
- !readConfObject(rootModel.jbrowse.configuration, 'disableAnalytics')) {
240
+ if (!rootModel) {
241
+ return;
242
+ }
243
+ // a config that opts out stops the end reports too, whichever config or
244
+ // session started them
245
+ if (readConfObject(rootModel.jbrowse.configuration, 'disableAnalytics')) {
246
+ activity.stop();
247
+ return;
248
+ }
249
+ latestRootModel = rootModel;
250
+ activity.watch(() => rootModel.session);
251
+ installEndReports();
252
+ if (!analyticsSent) {
121
253
  analyticsSent = true;
122
254
  // writeGAAnalytics injects Google's scripts and writeAWSAnalytics probes
123
255
  // graphics capabilities, hundreds of ms of main-thread work together. Idle
@@ -138,7 +270,8 @@ export function doAnalytics(rootModel, initialTimestamp, initialSessionQuery) {
138
270
  // `[data-app-phase="ready"]`, or a timeout for a page that never shows one
139
271
  // (Desktop's start screen)
140
272
  function afterAppReady(callback, maxWaitMs = 10_000) {
141
- const isReady = () => document.querySelector('[data-app-phase="ready"]') !== null;
273
+ const doc = document;
274
+ const isReady = () => doc.querySelector('[data-app-phase="ready"]') !== null;
142
275
  if (isReady()) {
143
276
  callback();
144
277
  return;
@@ -158,7 +291,7 @@ function afterAppReady(callback, maxWaitMs = 10_000) {
158
291
  }
159
292
  });
160
293
  const timer = setTimeout(finish, maxWaitMs);
161
- observer.observe(document.body, {
294
+ observer.observe(doc.body, {
162
295
  subtree: true,
163
296
  childList: true,
164
297
  attributeFilter: ['data-app-phase'],
@@ -1,5 +1,25 @@
1
+ /**
2
+ * A symmetric cubic's extreme sits 3/4 of the way from its baseline to its
3
+ * controls; the sashimi labels solve the same equation in the other direction.
4
+ */
1
5
  export declare const CUBIC_APEX_RATIO = 0.75;
6
+ /**
7
+ * How far a curve can stray outside the band between its two endpoints, which
8
+ * a culler pads its viewport test by.
9
+ */
2
10
  export declare const BEZIER_CONNECTOR_MAX_REACH_PX = 110;
11
+ /**
12
+ * One horizontal-tangent connector curve as an SVG path: the read and
13
+ * breakpoint connector BreakpointSplitView's AlignmentConnections draws, and
14
+ * the alignments display draws as render-core's `connector` mark. The
15
+ * geometry is that shader's own, through its JS twin, so the two views cannot
16
+ * drift in which way a connection leaves its read.
17
+ *
18
+ * A discordant connection dips below its ends instead of bowing up over them,
19
+ * so the two classes read apart at a glance. How deep is the caller's call:
20
+ * only it knows the band the ink has to survive in, and `discordantDipPx`
21
+ * (@jbrowse/sv-core) is the law the two views share.
22
+ */
3
23
  export declare function bezierConnectorPath({ x1, y1, x2, y2, s1, s2, leadingEnd2, reversed1, reversed2, maxHandlePx, dipPx, }: {
4
24
  x1: number;
5
25
  y1: number;
@@ -1,101 +1,39 @@
1
- // One horizontal-tangent "oval" connector curve, shared by the alignments
2
- // linked-read bezier overlay (PileupBezierOverlay) and BreakpointSplitView's
3
- // AlignmentConnections so the two renderers draw a connection identically. Both
4
- // describe the same thing — two read endpoints (from the shared
5
- // connectionEndpoints rule), each segment's strand, and whether the second end
6
- // is a split junction's 5' edge — and this owns the curve geometry, so the
7
- // direction logic can't drift between them.
8
- // A handle or bow larger than the endpoints' own separation folds the cubic
9
- // back over itself: the curve leaves along its tangent, overshoots the far
10
- // endpoint, and has to curl back to arrive — the "loop-de-loop"/squiggle seen
11
- // on tightly-spaced reads. So every shaping term stays under this fraction of
12
- // the span the curve actually has to cover. Endpoints that nearly touch
13
- // therefore get no shaping at all and draw as the straight line they should be.
14
- const SPAN_FACTOR = 0.3;
15
- // Ceiling on the control-handle length. The span budget is what actually scales
16
- // the handle — it resolves below this for any connection whose endpoints are
17
- // closer than ~667px apart, which is nearly all of them — so this only bites on
18
- // very wide arcs. There it bounds the fold-back hook that an inversion draws at
19
- // its leading end: unbounded, that hook grows with the arc, and a full-width
20
- // inversion flings a ~500px curl back across unrelated reads.
21
- const MAX_HANDLE_PX = 200;
22
- // A symmetric cubic's extreme sits 3/4 of the way from its baseline to its
23
- // control points, so an arc asked to reach a given apex puts its controls 4/3
24
- // past it. Exported because the sashimi overlay solves the same equation in the
25
- // other direction, and the two spellings drifting apart would put the insert-
26
- // size ruler's labels at heights nothing plots at.
27
- export const CUBIC_APEX_RATIO = 0.75;
28
- // Vertical bow applied to a connection whose two endpoints share (or nearly
29
- // share) a row — e.g. a chain whose split segments are all laid out on one
30
- // pileup row. Without it the horizontal-only handles collapse the cubic to a
31
- // flat, invisible line lying on the row; the bow lifts the control points so
32
- // the curve arcs into a visible hump. This is the control-point lift, not the
33
- // height the curve reaches.
34
- const MAX_BOW_PX = 30;
35
- // A discordant connection bows *down* instead of up, so the two classes read
36
- // apart at a glance. Both renderers follow this: BreakpointSplitView dips its
37
- // same-level discordant links, and the pileup overlay dips every discordant
38
- // curve it draws (a normal-orientation pair is a plain line, or bows up over its
39
- // row where a hidden-segment one would lie on a chain's connecting line). Keep
40
- // it that way — a renderer that opts out makes "below the reads" mean two
41
- // different things in two views of the same data.
42
- //
43
- // HOW DEEP is the renderer's call, not this file's. Depth is the mark's one free
44
- // channel, and only the renderer knows the band the ink has to survive in — the
45
- // pileup clips each section at its band bottom, and the split view bleeds a
46
- // too-deep dip into the panel below. So callers pass the depth they want and
47
- // `discordantDipPx` (@jbrowse/sv-core) is the law the two of them share.
48
- // How far a curve can stray outside the band between its two endpoints. The dip
49
- // is the deeper of the two shaping terms, so this is a ceiling on it, applied
50
- // here rather than trusted to a caller: a culler pads its viewport test by this,
51
- // and the shaping is applied to the *control points*, so a curve whose two
52
- // endpoints both sit just outside the viewport can still have a visible body.
53
- export const BEZIER_CONNECTOR_MAX_REACH_PX = 110;
54
- // Sign (+1/-1) of an endpoint's horizontal control handle. The handle leaves a
55
- // trailing (3') endpoint along the read's reading direction (`strand`); at a
56
- // split junction's leading (5') endpoint it flips, so the curve arrives flowing
57
- // *into* the next segment (a fwd→rev inversion folds back instead of cutting
58
- // straight across). `reversed` flips screen-x for a reverse-complemented region.
59
- function tangentSign(strand, leading, reversed) {
60
- return strand * (leading ? -1 : 1) * (reversed ? -1 : 1);
61
- }
62
- // How much shaping (handle length, bow height) this curve may spend: a fraction
63
- // of the distance it has to cover.
64
- function shapingBudget(p1, p2) {
65
- return Math.hypot(p2.x - p1.x, p2.y - p1.y) * SPAN_FACTOR;
66
- }
67
- // Fades to zero as the endpoints' rows separate, since a cross-row curve
68
- // already has vertical extent — and via the budget as they close in
69
- // horizontally, since a short connector is legible without a hump.
70
- function bowHeight(p1, p2, budget) {
71
- return Math.min(budget, Math.max(0, MAX_BOW_PX - Math.abs(p2.y - p1.y)));
72
- }
73
- function cubicPath(from, ctrl1, ctrl2, to) {
74
- return `M ${from.x} ${from.y} C ${ctrl1.x} ${ctrl1.y} ${ctrl2.x} ${ctrl2.y} ${to.x} ${to.y}`;
75
- }
1
+ import { connectorBudgetPx, connectorHandlePx, connectorLiftPx, connectorTangent, } from '@jbrowse/render-core/shaders/connectorMark';
2
+ import { CONNECTOR_APEX_RATIO, CONNECTOR_BOW, CONNECTOR_MAX_HANDLE_PX, CONNECTOR_MAX_REACH_PX, } from '@jbrowse/render-core/shaders/connectorMarkConsts';
3
+ /**
4
+ * A symmetric cubic's extreme sits 3/4 of the way from its baseline to its
5
+ * controls; the sashimi labels solve the same equation in the other direction.
6
+ */
7
+ export const CUBIC_APEX_RATIO = CONNECTOR_APEX_RATIO;
8
+ /**
9
+ * How far a curve can stray outside the band between its two endpoints, which
10
+ * a culler pads its viewport test by.
11
+ */
12
+ export const BEZIER_CONNECTOR_MAX_REACH_PX = CONNECTOR_MAX_REACH_PX;
13
+ /**
14
+ * One horizontal-tangent connector curve as an SVG path: the read and
15
+ * breakpoint connector BreakpointSplitView's AlignmentConnections draws, and
16
+ * the alignments display draws as render-core's `connector` mark. The
17
+ * geometry is that shader's own, through its JS twin, so the two views cannot
18
+ * drift in which way a connection leaves its read.
19
+ *
20
+ * A discordant connection dips below its ends instead of bowing up over them,
21
+ * so the two classes read apart at a glance. How deep is the caller's call:
22
+ * only it knows the band the ink has to survive in, and `discordantDipPx`
23
+ * (@jbrowse/sv-core) is the law the two views share.
24
+ */
76
25
  export function bezierConnectorPath({ x1, y1, x2, y2, s1, s2,
77
26
  // The second endpoint is a split junction's 5' leading edge (its handle flips
78
27
  // to fold the curve into the next segment); false for a paired mate's 3' edge.
79
- leadingEnd2 = false, reversed1 = false, reversed2 = false, maxHandlePx = MAX_HANDLE_PX,
80
- // Depth, in px, of the dip a discordant connection draws instead of the bow a
81
- // concordant one gets — aberrant pair orientation, or a split junction's
82
- // strand flip, so the two classes are tellable apart by shape alone. It is
83
- // the depth of the curve's APEX — what a caller can bound by the room it has —
84
- // and CUBIC_APEX_RATIO converts it to the control-point drop that puts the ink
85
- // there. Leave it out to bow up.
28
+ leadingEnd2 = false, reversed1 = false, reversed2 = false, maxHandlePx = CONNECTOR_MAX_HANDLE_PX,
29
+ // Depth, in px, of the APEX of the dip a discordant connection draws instead
30
+ // of the bow a concordant one gets. Leave it out to bow up.
86
31
  dipPx, }) {
87
- const from = { x: x1, y: y1 };
88
- const to = { x: x2, y: y2 };
89
- const budget = shapingBudget(from, to);
90
- const handle = Math.min(maxHandlePx, budget);
91
- // The dip is deliberately not clamped to the budget, unlike the bow. The
92
- // budget stops the cubic folding back over itself, and only the horizontal
93
- // handles can do that — a vertical offset leaves x(t) monotonic however deep
94
- // it goes, so a big event squeezed into a few px draws a narrow trough rather
95
- // than a squiggle. Pinned by 'a dipped connection never overshoots its
96
- // endpoints in x'.
97
- const bow = dipPx === undefined
98
- ? bowHeight(from, to, budget)
99
- : -Math.min(dipPx, BEZIER_CONNECTOR_MAX_REACH_PX) / CUBIC_APEX_RATIO;
100
- return cubicPath(from, { x: x1 + handle * tangentSign(s1, false, reversed1), y: y1 - bow }, { x: x2 + handle * tangentSign(s2, leadingEnd2, reversed2), y: y2 - bow }, to);
32
+ const dy = y2 - y1;
33
+ const budget = connectorBudgetPx(x2 - x1, dy);
34
+ const handle = connectorHandlePx(budget, maxHandlePx);
35
+ const lift = connectorLiftPx(budget, dy, dipPx ?? CONNECTOR_BOW);
36
+ const c1x = x1 + handle * connectorTangent(s1, 0, reversed1 ? 1 : 0);
37
+ const c2x = x2 + handle * connectorTangent(s2, leadingEnd2 ? 1 : 0, reversed2 ? 1 : 0);
38
+ return `M ${x1} ${y1} C ${c1x} ${y1 - lift} ${c2x} ${y2 - lift} ${x2} ${y2}`;
101
39
  }
@@ -51,5 +51,8 @@ import { SharedBudget } from '@gmod/shared-read-cache';
51
51
  * why this used to be two budgets named for their units: a million records
52
52
  * could not be added to bytes, and never bound long-read data either, where a
53
53
  * 6 MB slice counted as 37.
54
+ *
55
+ * `@jbrowse/tables` lowers the limit for a host such as R, which keeps no
56
+ * track open to pan (`packages/tables/src/cache.ts`).
54
57
  */
55
58
  export declare const decompressedBytesBudget: SharedBudget;
@@ -51,5 +51,8 @@ import { SharedBudget } from '@gmod/shared-read-cache';
51
51
  * why this used to be two budgets named for their units: a million records
52
52
  * could not be added to bytes, and never bound long-read data either, where a
53
53
  * 6 MB slice counted as 37.
54
+ *
55
+ * `@jbrowse/tables` lowers the limit for a host such as R, which keeps no
56
+ * track open to pan (`packages/tables/src/cache.ts`).
54
57
  */
55
58
  export const decompressedBytesBudget = new SharedBudget(1024 * 2 ** 20);
@@ -1,3 +1,4 @@
1
+ import type { HeldSlots } from '../ui/colors.ts';
1
2
  /** #api */
2
3
  export declare const STRAND_FIELD = "strand";
3
4
  /**
@@ -19,7 +20,9 @@ export declare const NO_VALUE_LABEL = "(no value)";
19
20
  * orders keys (the `domain` first, the rest by `compareGroupKeys`, `''`
20
21
  * after them), `label` names a key in a legend, `sectionLabel` on a chip, and
21
22
  * `color` paints it. A key's color depends only on the key and the
22
- * declaration, so every region agrees on it.
23
+ * declaration, so every region agrees on it, except that a field dealing its
24
+ * colors (`categoricalField`'s `held`) also steps a key off the colors of the
25
+ * keys met before it.
23
26
  */
24
27
  export interface CategoricalField {
25
28
  field: string;
@@ -38,7 +41,7 @@ export interface CategoricalField {
38
41
  }
39
42
  /**
40
43
  * #api
41
- * What a key names each of `keys`, from a colour object's `labels`: one each in
44
+ * What a key names each of `keys`, from a color object's `labels`: one each in
42
45
  * order, an empty or missing entry leaving that key its own name. Every key
43
46
  * that takes `labels` reads them through this, so a config means one thing by
44
47
  * them everywhere.
@@ -47,10 +50,27 @@ export declare function keyNames(keys: readonly unknown[], labels?: readonly str
47
50
  /**
48
51
  * #api
49
52
  * `labels` names the `domain`'s values in a key, one each in order, where a
50
- * config spells them for a reader rather than as the data does.
53
+ * config spells them for a reader rather than as the data does. `held` deals
54
+ * each key the domain does not list a color of its own on first sight
55
+ * (`categoricalScale`); the caller keeps it for as long as the colors should
56
+ * hold.
51
57
  */
52
- export declare function categoricalField(field: string, { domain, range, labels, }?: {
58
+ export declare function categoricalField(field: string, { domain, range, labels, held, }?: {
53
59
  domain?: readonly string[];
54
60
  range?: readonly string[];
55
61
  labels?: readonly string[];
62
+ held?: HeldSlots;
56
63
  }): CategoricalField;
64
+ /**
65
+ * #api
66
+ * Deals `keys` their colors in `field.compare` order, so the colors a set
67
+ * of keys first seen together takes do not depend on the order they arrive
68
+ * in. A no-op for a field that deals nothing.
69
+ */
70
+ export declare function dealKeyColors(field: CategoricalField, keys: Iterable<string>): void;
71
+ /**
72
+ * #api
73
+ * The `HeldSlots` `owner` keeps under `key`, made empty on first ask. Lives as
74
+ * long as `owner` and is never persisted, so a reload deals afresh.
75
+ */
76
+ export declare function heldSlotsOf(owner: object, key: string): HeldSlots;
@@ -18,7 +18,7 @@ export const SV_TYPE_FIELD = 'svType';
18
18
  export const NO_VALUE_LABEL = '(no value)';
19
19
  /**
20
20
  * #api
21
- * What a key names each of `keys`, from a colour object's `labels`: one each in
21
+ * What a key names each of `keys`, from a color object's `labels`: one each in
22
22
  * order, an empty or missing entry leaving that key its own name. Every key
23
23
  * that takes `labels` reads them through this, so a config means one thing by
24
24
  * them everywhere.
@@ -37,11 +37,14 @@ export function keyNames(keys, labels = []) {
37
37
  /**
38
38
  * #api
39
39
  * `labels` names the `domain`'s values in a key, one each in order, where a
40
- * config spells them for a reader rather than as the data does.
40
+ * config spells them for a reader rather than as the data does. `held` deals
41
+ * each key the domain does not list a color of its own on first sight
42
+ * (`categoricalScale`); the caller keeps it for as long as the colors should
43
+ * hold.
41
44
  */
42
- export function categoricalField(field, { domain = [], range = [], labels = [], } = {}) {
45
+ export function categoricalField(field, { domain = [], range = [], labels = [], held, } = {}) {
43
46
  // a field with a vocabulary of its own reads it on every channel, a facet's
44
- // sections as well as a colour's key
47
+ // sections as well as a color's key
45
48
  const vocabulary = universalPresetOf(field);
46
49
  const ownOrder = vocabulary?.domain ?? [];
47
50
  const order = domain.length > 0 ? domain : ownOrder;
@@ -66,8 +69,38 @@ export function categoricalField(field, { domain = [], range = [], labels = [],
66
69
  if (key === '') {
67
70
  return NO_CATEGORY_COLOR;
68
71
  }
69
- colorOf ??= categoricalColorScale(paired, colors);
72
+ colorOf ??= categoricalColorScale(paired, colors, held);
70
73
  return colorOf(key);
71
74
  },
72
75
  };
73
76
  }
77
+ /**
78
+ * #api
79
+ * Deals `keys` their colors in `field.compare` order, so the colors a set
80
+ * of keys first seen together takes do not depend on the order they arrive
81
+ * in. A no-op for a field that deals nothing.
82
+ */
83
+ export function dealKeyColors(field, keys) {
84
+ for (const key of [...new Set(keys)].sort(field.compare)) {
85
+ field.color(key);
86
+ }
87
+ }
88
+ const heldByOwner = new WeakMap();
89
+ /**
90
+ * #api
91
+ * The `HeldSlots` `owner` keeps under `key`, made empty on first ask. Lives as
92
+ * long as `owner` and is never persisted, so a reload deals afresh.
93
+ */
94
+ export function heldSlotsOf(owner, key) {
95
+ let byKey = heldByOwner.get(owner);
96
+ if (byKey === undefined) {
97
+ byKey = new Map();
98
+ heldByOwner.set(owner, byKey);
99
+ }
100
+ let held = byKey.get(key);
101
+ if (held === undefined) {
102
+ held = new Map();
103
+ byKey.set(key, held);
104
+ }
105
+ return held;
106
+ }
@@ -1,8 +1,9 @@
1
1
  // A `cells` step, the interval `bin` behind it and the `aggregate` of its
2
2
  // matches as one walk over the rows' bytes, which `runSteps` in
3
3
  // featureTransforms.ts reaches by relative path only.
4
+ import { DASH, SPACE, firstDrawn, isGapByte, lastDrawn, } from './alignedBytes.js';
4
5
  import { fusesBinAggregate } from './binnedAggregate.js';
5
- import { DASH, DEFAULT_CELLS_FIELD, MATCH, MISMATCH, NO_STATE, SPACE, cellState, firstDrawn, isGapByte, lastDrawn, walkedTexts, } from './cellsStep.js';
6
+ import { DEFAULT_CELLS_FIELD, MATCH, NO_STATE, cellState, comparesBase, opensRun, runKey, walkedTexts, } from './cellsStep.js';
6
7
  import { numberReaderOf, readerOf } from './featureTable.js';
7
8
  import { BIN_OVERLAP_FIELD, DEFAULT_BIN_AS, OpSums, groupKey, madeGroups, } from './stepTables.js';
8
9
  const isEdges = (pair) => pair?.length === 2 && pair[0] === 'start' && pair[1] === 'end';
@@ -97,10 +98,10 @@ class SectionBins {
97
98
  }
98
99
  /**
99
100
  * One row's runs as `cells` writes them, each met by its bins as the bin
100
- * step cuts it and in the order the lanes hold them: a run when the next
101
- * column's state differs, an insertion at the reference base after it,
102
- * ahead of the run still open. The bases a run of matches or mismatches
103
- * holds are counted in their bins as the walk passes them.
101
+ * step cuts it and in the order the lanes hold them: a run where the next
102
+ * column `opensRun`, an insertion at the reference base after it,
103
+ * ahead of the run still open. The compared bases a run holds are counted
104
+ * in their bins as the walk passes them.
104
105
  */
105
106
  walk(r, startPos, size, rowBytes, rowAt, rowLen, refBytes, refAt, refLen) {
106
107
  const { matched, compared, low } = this;
@@ -114,7 +115,7 @@ class SectionBins {
114
115
  let runOpen = false;
115
116
  let runBin = 0;
116
117
  let runState = NO_STATE;
117
- let runBase = -1;
118
+ let openKey = -1;
118
119
  let inserting = false;
119
120
  for (let col = 0; col < refLen; col++) {
120
121
  const refByte = refBytes[refAt + col];
@@ -130,22 +131,21 @@ class SectionBins {
130
131
  inserting = false;
131
132
  }
132
133
  const st = cellState(refByte, rowByte, col >= first && col <= last && col < rowLen);
133
- const base = st === MISMATCH ? rowByte : -1;
134
- if (st !== runState || base !== runBase) {
134
+ const key = runKey(st, refByte);
135
+ if (opensRun(st, key, runState, openKey)) {
135
136
  if (runOpen) {
136
137
  this.touch(runBin, pos > edge - size ? bin : bin - 1, r);
137
138
  }
138
139
  runOpen = st !== NO_STATE;
139
140
  runBin = bin;
140
141
  runState = st;
141
- runBase = base;
142
+ openKey = key;
142
143
  }
143
- if (st === MATCH) {
144
- m++;
145
- c++;
146
- }
147
- else if (st === MISMATCH) {
144
+ if (comparesBase(st, refByte)) {
148
145
  c++;
146
+ if (st === MATCH) {
147
+ m++;
148
+ }
149
149
  }
150
150
  pos++;
151
151
  if (pos === edge) {
@@ -2,15 +2,13 @@ import type { FeatureTable, TextColumn } from './featureTable.ts';
2
2
  import type { CellsStep } from './markEncodingTypes.ts';
3
3
  import type { Staged } from './stepTables.ts';
4
4
  export declare const DEFAULT_CELLS_FIELD = "seq";
5
- export declare const DASH = 45;
6
- export declare const SPACE = 32;
7
5
  export declare const MATCH = 0;
8
6
  export declare const MISMATCH = 1;
9
7
  export declare const NO_STATE = 255;
10
- export declare function isGapByte(b: number): b is 32 | 45;
11
- export declare function firstDrawn(bytes: Uint8Array, at: number, len: number): number;
12
- export declare function lastDrawn(bytes: Uint8Array, at: number, len: number, first: number): number;
13
8
  export declare function cellState(refByte: number, rowByte: number, drawn: boolean): 0 | 1 | 2 | 255;
9
+ export declare function comparesBase(state: number, refByte: number): boolean;
10
+ export declare function runKey(state: number, refByte: number): 0 | 1;
11
+ export declare function opensRun(state: number, key: number, runState: number, openKey: number): boolean;
14
12
  /**
15
13
  * The texts a `cells` walk reads, by the row of the table it walked: each
16
14
  * row's own, and the reference it is read against, which a row fanned out of