@jbrowse/core 5.0.0-beta.8 → 5.0.0-beta.9

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 (379) hide show
  1. package/README.md +427 -130
  2. package/esm/BaseFeatureWidget/BaseFeatureDetail/ArrayValue.d.ts +3 -2
  3. package/esm/BaseFeatureWidget/BaseFeatureDetail/ArrayValue.js +5 -3
  4. package/esm/BaseFeatureWidget/BaseFeatureDetail/Attributes.d.ts +3 -5
  5. package/esm/BaseFeatureWidget/BaseFeatureDetail/Attributes.js +8 -9
  6. package/esm/BaseFeatureWidget/BaseFeatureDetail/CoreDetails.js +8 -13
  7. package/esm/BaseFeatureWidget/BaseFeatureDetail/FeatureDetails.d.ts +2 -1
  8. package/esm/BaseFeatureWidget/BaseFeatureDetail/FeatureDetails.js +3 -3
  9. package/esm/BaseFeatureWidget/BaseFeatureDetail/FieldActionsButton.d.ts +8 -0
  10. package/esm/BaseFeatureWidget/BaseFeatureDetail/FieldActionsButton.js +24 -0
  11. package/esm/BaseFeatureWidget/BaseFeatureDetail/SimpleField.d.ts +3 -2
  12. package/esm/BaseFeatureWidget/BaseFeatureDetail/SimpleField.js +5 -3
  13. package/esm/BaseFeatureWidget/BaseFeatureDetail/index.d.ts +1 -0
  14. package/esm/BaseFeatureWidget/BaseFeatureDetail/index.js +1 -4
  15. package/esm/BaseFeatureWidget/BaseFeatureDetail/jexlFilterActions.d.ts +16 -0
  16. package/esm/BaseFeatureWidget/BaseFeatureDetail/jexlFilterActions.js +53 -0
  17. package/esm/BaseFeatureWidget/BaseFeatureDetail/util.d.ts +0 -8
  18. package/esm/BaseFeatureWidget/BaseFeatureDetail/util.js +0 -16
  19. package/esm/BaseFeatureWidget/SequenceFeatureDetails/SequenceContents.js +7 -34
  20. package/esm/BaseFeatureWidget/configSchema.d.ts +1 -1
  21. package/esm/BaseFeatureWidget/formatDetails.d.ts +13 -29
  22. package/esm/BaseFeatureWidget/formatDetails.js +46 -79
  23. package/esm/BaseFeatureWidget/index.d.ts +1 -0
  24. package/esm/BaseFeatureWidget/stateModelFactory.d.ts +35 -28
  25. package/esm/BaseFeatureWidget/stateModelFactory.js +94 -102
  26. package/esm/BaseFeatureWidget/types.d.ts +3 -0
  27. package/esm/BaseFeatureWidget/util.d.ts +0 -3
  28. package/esm/BaseFeatureWidget/util.js +0 -17
  29. package/esm/PluginLoader.d.ts +14 -9
  30. package/esm/PluginLoader.js +34 -26
  31. package/esm/PluginManager.d.ts +4 -4
  32. package/esm/PluginManager.js +1 -1
  33. package/esm/ReExports/coreModules.generated.d.ts +2 -0
  34. package/esm/ReExports/coreModules.generated.js +492 -0
  35. package/esm/ReExports/coreWorkerModules.generated.d.ts +2 -0
  36. package/esm/ReExports/coreWorkerModules.generated.js +453 -0
  37. package/esm/ReExports/frameworkModules.d.ts +2 -0
  38. package/esm/ReExports/frameworkModules.js +67 -0
  39. package/esm/ReExports/frameworkShared.d.ts +12 -0
  40. package/esm/ReExports/frameworkShared.js +16 -0
  41. package/esm/ReExports/frameworkWorkerModules.generated.d.ts +2 -0
  42. package/esm/ReExports/frameworkWorkerModules.generated.js +130 -0
  43. package/esm/ReExports/list.js +493 -79
  44. package/esm/ReExports/modules.d.ts +1 -1
  45. package/esm/ReExports/modules.js +10 -87
  46. package/esm/ReExports/registry.d.ts +1 -0
  47. package/esm/ReExports/registry.js +23 -5
  48. package/esm/ReExports/uiStub.d.ts +2 -1
  49. package/esm/ReExports/uiStub.js +24 -2
  50. package/esm/ReExports/workerModules.js +8 -12
  51. package/esm/TextSearch/TextSearchManager.d.ts +3 -12
  52. package/esm/TextSearch/TextSearchManager.js +22 -10
  53. package/esm/assemblyManager/assembly.d.ts +10 -14
  54. package/esm/assemblyManager/assembly.js +10 -14
  55. package/esm/assemblyManager/assemblyConfigSchema.d.ts +23 -81
  56. package/esm/assemblyManager/assemblyManager.d.ts +10 -16
  57. package/esm/assemblyManager/assemblyManager.js +7 -10
  58. package/esm/assemblyManager/loadRefNameMap.js +3 -3
  59. package/esm/configuration/configurationSchema.d.ts +75 -31
  60. package/esm/configuration/configurationSchema.js +74 -40
  61. package/esm/configuration/configurationSchemaUnion.d.ts +39 -0
  62. package/esm/configuration/configurationSchemaUnion.js +59 -0
  63. package/esm/configuration/configurationSlot.d.ts +37 -12
  64. package/esm/configuration/configurationSlot.js +83 -22
  65. package/esm/configuration/formatAboutConfigSchema.d.ts +7 -21
  66. package/esm/configuration/formatDetailsConfigSchema.d.ts +11 -37
  67. package/esm/configuration/formatDetailsConfigSchema.js +10 -13
  68. package/esm/configuration/getConf.d.ts +17 -9
  69. package/esm/configuration/getConf.js +52 -7
  70. package/esm/configuration/index.d.ts +11 -4
  71. package/esm/configuration/index.js +7 -4
  72. package/esm/configuration/mergeFormatCallbacks.d.ts +6 -7
  73. package/esm/configuration/mergeFormatCallbacks.js +13 -10
  74. package/esm/configuration/readConfObject.d.ts +2 -22
  75. package/esm/configuration/readConfObject.js +15 -49
  76. package/esm/configuration/requirements.d.ts +37 -0
  77. package/esm/configuration/requirements.js +88 -0
  78. package/esm/configuration/schemaRegistry.d.ts +21 -1
  79. package/esm/configuration/schemaRegistry.js +11 -0
  80. package/esm/configuration/schemaTypes.d.ts +3 -0
  81. package/esm/configuration/schemaTypes.js +10 -0
  82. package/esm/configuration/slotFacade.d.ts +35 -4
  83. package/esm/configuration/slotFacade.js +96 -9
  84. package/esm/configuration/snapshotPreprocess.d.ts +27 -0
  85. package/esm/configuration/snapshotPreprocess.js +102 -0
  86. package/esm/configuration/types.d.ts +161 -22
  87. package/esm/data_adapters/BaseAdapter/BaseAdapter.d.ts +2 -2
  88. package/esm/data_adapters/BaseAdapter/BaseFeatureDataAdapter.d.ts +11 -2
  89. package/esm/data_adapters/BaseAdapter/BaseFeatureDataAdapter.js +12 -1
  90. package/esm/data_adapters/BaseAdapter/featureDensity.d.ts +2 -3
  91. package/esm/data_adapters/BaseAdapter/featureDensity.js +2 -3
  92. package/esm/data_adapters/BaseAdapter/index.d.ts +22 -3
  93. package/esm/data_adapters/BaseAdapter/types.d.ts +3 -4
  94. package/esm/data_adapters/BaseAdapter/zoomRange.d.ts +10 -0
  95. package/esm/data_adapters/BaseAdapter/zoomRange.js +1 -0
  96. package/esm/data_adapters/CytobandAdapter/configSchema.d.ts +9 -11
  97. package/esm/data_adapters/getSequenceSubAdapter.d.ts +1 -3
  98. package/esm/data_adapters/getSequenceSubAdapter.js +1 -3
  99. package/esm/pluggableElementTypes/AdapterType.d.ts +7 -7
  100. package/esm/pluggableElementTypes/RpcMethodType.d.ts +1 -1
  101. package/esm/pluggableElementTypes/RpcMethodType.js +3 -8
  102. package/esm/pluggableElementTypes/RpcMethodTypeWithFiltersAndRenameRegions.d.ts +1 -2
  103. package/esm/pluggableElementTypes/TextSearchAdapterType.d.ts +7 -7
  104. package/esm/pluggableElementTypes/index.d.ts +1 -1
  105. package/esm/pluggableElementTypes/index.js +1 -1
  106. package/esm/pluggableElementTypes/models/BaseConnectionModelFactory.d.ts +17 -7
  107. package/esm/pluggableElementTypes/models/BaseDisplayModel.d.ts +45 -48
  108. package/esm/pluggableElementTypes/models/BaseDisplayModel.js +40 -36
  109. package/esm/pluggableElementTypes/models/BaseTrackModel.d.ts +10 -13
  110. package/esm/pluggableElementTypes/models/BaseTrackModel.js +6 -6
  111. package/esm/pluggableElementTypes/models/BaseViewModel.d.ts +37 -17
  112. package/esm/pluggableElementTypes/models/BaseViewModel.js +25 -10
  113. package/esm/pluggableElementTypes/models/InternetAccountModel.d.ts +26 -16
  114. package/esm/pluggableElementTypes/models/assertDisplayContract.d.ts +1 -1
  115. package/esm/pluggableElementTypes/models/baseConnectionConfig.d.ts +22 -18
  116. package/esm/pluggableElementTypes/models/baseConnectionConfig.js +5 -5
  117. package/esm/pluggableElementTypes/models/baseInternetAccountConfig.d.ts +26 -31
  118. package/esm/pluggableElementTypes/models/baseTrackConfig.d.ts +57 -141
  119. package/esm/pluggableElementTypes/models/baseTrackConfig.js +22 -26
  120. package/esm/pluggableElementTypes/models/components/SaveTrackData.js +2 -2
  121. package/esm/pluggableElementTypes/models/components/fetchTrackData.d.ts +3 -4
  122. package/esm/pluggableElementTypes/models/components/fetchTrackData.js +3 -3
  123. package/esm/pluggableElementTypes/models/expandTrackConfigShorthand.d.ts +15 -7
  124. package/esm/pluggableElementTypes/models/expandTrackConfigShorthand.js +38 -29
  125. package/esm/pluggableElementTypes/models/index.d.ts +1 -2
  126. package/esm/pluggableElementTypes/models/index.js +1 -2
  127. package/esm/pluggableElementTypes/models/saveTrackFileTypes/genbank.d.ts +3 -3
  128. package/esm/pluggableElementTypes/models/saveTrackFileTypes/genbank.js +4 -4
  129. package/esm/pluggableElementTypes/models/saveTrackFileTypes/types.d.ts +3 -3
  130. package/esm/rpc/BaseRpcDriver.d.ts +1 -2
  131. package/esm/rpc/BaseRpcDriver.js +23 -30
  132. package/esm/rpc/MainThreadRpcDriver.d.ts +2 -2
  133. package/esm/rpc/MainThreadRpcDriver.js +13 -8
  134. package/esm/rpc/RpcClient.d.ts +17 -6
  135. package/esm/rpc/RpcClient.js +42 -12
  136. package/esm/rpc/RpcManager.d.ts +8 -10
  137. package/esm/rpc/RpcManager.js +1 -1
  138. package/esm/rpc/RpcRegistry.d.ts +8 -2
  139. package/esm/rpc/RpcServer.d.ts +3 -1
  140. package/esm/rpc/RpcServer.js +19 -12
  141. package/esm/rpc/WebWorkerRpcDriver.d.ts +3 -3
  142. package/esm/rpc/WebWorkerRpcDriver.js +9 -47
  143. package/esm/rpc/byteBudget.d.ts +3 -5
  144. package/esm/rpc/byteBudget.js +4 -4
  145. package/esm/rpc/configSchema.d.ts +7 -21
  146. package/esm/rpc/coreRpcMethods.d.ts +1 -0
  147. package/esm/rpc/coreRpcMethods.js +1 -0
  148. package/esm/rpc/methods/CoreEncodeFeatures.d.ts +6 -5
  149. package/esm/rpc/methods/CoreEncodeFeatures.js +26 -31
  150. package/esm/rpc/methods/CoreGetEncodedFeature.d.ts +13 -0
  151. package/esm/rpc/methods/CoreGetEncodedFeature.js +31 -0
  152. package/esm/rpc/methods/CoreGetExportData.js +2 -2
  153. package/esm/rpc/methods/CoreGetFeatureDensity.js +2 -2
  154. package/esm/rpc/methods/CoreGetFeatures.js +2 -2
  155. package/esm/rpc/methods/CoreGetSequence.js +2 -2
  156. package/esm/rpc/methods/layerFeatures.d.ts +26 -0
  157. package/esm/rpc/methods/layerFeatures.js +40 -0
  158. package/esm/svg/SvgExport.js +3 -4
  159. package/esm/svg/SvgThemeProviders.d.ts +12 -0
  160. package/esm/svg/SvgThemeProviders.js +15 -0
  161. package/esm/svg/exportViewSvg.d.ts +32 -0
  162. package/esm/svg/exportViewSvg.js +13 -0
  163. package/esm/svg/normalizeSvgMarkup.d.ts +7 -0
  164. package/esm/svg/normalizeSvgMarkup.js +99 -0
  165. package/esm/svg/serializeSvg.d.ts +7 -0
  166. package/esm/svg/serializeSvg.js +11 -0
  167. package/esm/svg/svgReady.d.ts +8 -7
  168. package/esm/svg/svgReady.js +8 -7
  169. package/esm/svg/trackNames.d.ts +5 -5
  170. package/esm/svg/trackNames.js +6 -6
  171. package/esm/svg/wrapSvgExport.js +6 -74
  172. package/esm/ui/CascadingMenu.js +83 -86
  173. package/esm/ui/ErrorMessageStackTraceDialog.js +0 -5
  174. package/esm/ui/FileSelector/useInternetAccounts.d.ts +156 -96
  175. package/esm/ui/HoverMenu.d.ts +1 -2
  176. package/esm/ui/HoverMenu.js +6 -3
  177. package/esm/ui/JexlFilterDialog.d.ts +13 -10
  178. package/esm/ui/JexlFilterDialog.js +122 -49
  179. package/esm/ui/JexlFilterRowEditors.d.ts +15 -0
  180. package/esm/ui/JexlFilterRowEditors.js +90 -0
  181. package/esm/ui/LazyBaseTooltip.d.ts +4 -0
  182. package/esm/ui/LazyBaseTooltip.js +9 -0
  183. package/esm/ui/LoadingOverlay.js +3 -1
  184. package/esm/ui/MonospaceTextField.d.ts +2 -1
  185. package/esm/ui/MonospaceTextField.js +21 -19
  186. package/esm/ui/PaletteContext.d.ts +7 -9
  187. package/esm/ui/PaletteContext.js +24 -10
  188. package/esm/ui/RefNameAutocomplete/index.d.ts +1 -2
  189. package/esm/ui/RefNameAutocomplete/index.js +1 -1
  190. package/esm/ui/ScrollChrome.d.ts +6 -9
  191. package/esm/ui/ScrollChrome.js +5 -6
  192. package/esm/ui/ScrollEdgeShadow.d.ts +6 -9
  193. package/esm/ui/ScrollEdgeShadow.js +9 -24
  194. package/esm/ui/SettingsChangesTable.js +3 -3
  195. package/esm/ui/VerticalScrollbar.d.ts +13 -34
  196. package/esm/ui/VerticalScrollbar.js +29 -83
  197. package/esm/ui/ViewLoadingScreen.d.ts +2 -2
  198. package/esm/ui/ViewLoadingScreen.js +3 -3
  199. package/esm/ui/colorScale.d.ts +26 -1
  200. package/esm/ui/colorScale.js +28 -5
  201. package/esm/ui/colors.d.ts +49 -1
  202. package/esm/ui/colors.js +139 -4
  203. package/esm/ui/hoverBoxStyle.d.ts +14 -2
  204. package/esm/ui/hoverBoxStyle.js +17 -2
  205. package/esm/ui/index.d.ts +5 -3
  206. package/esm/ui/index.js +9 -7
  207. package/esm/ui/launchViewMenu.js +3 -3
  208. package/esm/ui/legendSpec.d.ts +2 -0
  209. package/esm/ui/legendSpec.js +3 -0
  210. package/esm/ui/palette.d.ts +0 -1
  211. package/esm/ui/palette.js +3 -27
  212. package/esm/ui/replaceViewAction.d.ts +1 -1
  213. package/esm/ui/replaceViewAction.js +1 -1
  214. package/esm/ui/theme.d.ts +1 -1
  215. package/esm/ui/theme.js +6 -40
  216. package/esm/ui/viewHeaderHeight.d.ts +1 -0
  217. package/esm/ui/viewHeaderHeight.js +1 -0
  218. package/esm/util/Base1DUtils.d.ts +1 -1
  219. package/esm/util/Base1DUtils.js +2 -2
  220. package/esm/util/SvgCanvas.d.ts +15 -13
  221. package/esm/util/SvgCanvas.js +72 -53
  222. package/esm/util/aborting.d.ts +39 -0
  223. package/esm/util/aborting.js +84 -0
  224. package/esm/util/adapterMetadata.d.ts +1 -1
  225. package/esm/util/adapterMetadata.js +6 -6
  226. package/esm/util/addAndShowTrack.d.ts +1 -4
  227. package/esm/util/addRelativeUris.d.ts +10 -2
  228. package/esm/util/addRelativeUris.js +22 -7
  229. package/esm/util/addTrackFromWidget.d.ts +2 -5
  230. package/esm/util/animationAllowed.d.ts +9 -0
  231. package/esm/util/animationAllowed.js +13 -0
  232. package/esm/util/applyRowResizeWheel.d.ts +10 -5
  233. package/esm/util/applyRowResizeWheel.js +10 -21
  234. package/esm/util/bandLayout.d.ts +4 -4
  235. package/esm/util/bandLayout.js +4 -4
  236. package/esm/util/bezierConnector.js +5 -4
  237. package/esm/util/bgzfWorkerPool.d.ts +20 -74
  238. package/esm/util/bgzfWorkerPool.js +20 -74
  239. package/esm/util/cachedSetup.d.ts +1 -1
  240. package/esm/util/cachedSetup.js +2 -2
  241. package/esm/util/categoricalField.d.ts +37 -0
  242. package/esm/util/categoricalField.js +52 -0
  243. package/esm/util/color/cssColorsLevel4.d.ts +1 -0
  244. package/esm/util/color/cssColorsLevel4.js +1 -0
  245. package/esm/util/color/index.d.ts +5 -3
  246. package/esm/util/color/index.js +7 -4
  247. package/esm/util/colorBits.d.ts +1 -2
  248. package/esm/util/colorBits.js +17 -39
  249. package/esm/util/colorRamp.d.ts +27 -1
  250. package/esm/util/colorRamp.js +56 -2
  251. package/esm/util/colorSchemes.d.ts +9 -0
  252. package/esm/util/colorSchemes.js +7 -0
  253. package/esm/util/{createStopTokenRotation.d.ts → createAbortRotation.d.ts} +11 -14
  254. package/esm/util/{createStopTokenRotation.js → createAbortRotation.js} +14 -26
  255. package/esm/util/cssColorParse.d.ts +15 -0
  256. package/esm/util/cssColorParse.js +53 -0
  257. package/esm/util/diagonalizeRegions.d.ts +2 -3
  258. package/esm/util/diagonalizeRegions.js +7 -12
  259. package/esm/util/expandLooseSearchIndex.d.ts +7 -0
  260. package/esm/util/expandLooseSearchIndex.js +25 -0
  261. package/esm/util/featureTransforms.d.ts +30 -3
  262. package/esm/util/featureTransforms.js +233 -36
  263. package/esm/util/fetchAndMaybeUnzip.js +5 -6
  264. package/esm/util/fetchContext.d.ts +5 -6
  265. package/esm/util/fetchContext.js +1 -1
  266. package/esm/util/fetchHub.d.ts +3 -1
  267. package/esm/util/fetchHub.js +2 -2
  268. package/esm/util/fetchSeq.d.ts +2 -3
  269. package/esm/util/fetchSeq.js +2 -2
  270. package/esm/util/fieldReader.d.ts +17 -0
  271. package/esm/util/fieldReader.js +62 -0
  272. package/esm/util/groupKeys.d.ts +75 -0
  273. package/esm/util/groupKeys.js +152 -0
  274. package/esm/util/highlights.d.ts +6 -4
  275. package/esm/util/highlights.js +12 -25
  276. package/esm/util/hooks.d.ts +1 -2
  277. package/esm/util/hooks.js +1 -2
  278. package/esm/util/index.d.ts +3 -3
  279. package/esm/util/index.js +4 -3
  280. package/esm/util/indexCandidates.js +1 -1
  281. package/esm/util/installFetch.d.ts +13 -10
  282. package/esm/util/installFetch.js +11 -10
  283. package/esm/util/installPrerequisiteFetch.d.ts +5 -3
  284. package/esm/util/installPrerequisiteFetch.js +3 -4
  285. package/esm/util/io/index.js +12 -12
  286. package/esm/util/isDataCurrent.d.ts +7 -5
  287. package/esm/util/isDataCurrent.js +9 -6
  288. package/esm/util/jexl.js +24 -21
  289. package/esm/util/jexlFilterRows.d.ts +89 -0
  290. package/esm/util/jexlFilterRows.js +252 -0
  291. package/esm/util/jexlFilters.d.ts +7 -5
  292. package/esm/util/jexlStrings.d.ts +3 -4
  293. package/esm/util/jexlStrings.js +2 -3
  294. package/esm/util/legendCandidates.d.ts +31 -27
  295. package/esm/util/legendCandidates.js +79 -53
  296. package/esm/util/localStorage.js +4 -4
  297. package/esm/util/markEncoding.d.ts +32 -16
  298. package/esm/util/markEncoding.js +177 -150
  299. package/esm/util/markEncodingTypes.d.ts +137 -66
  300. package/esm/util/mstUtils.d.ts +19 -22
  301. package/esm/util/mstUtils.js +19 -22
  302. package/esm/util/numericUtils.d.ts +7 -0
  303. package/esm/util/numericUtils.js +16 -0
  304. package/esm/util/numericValue.d.ts +14 -0
  305. package/esm/util/numericValue.js +34 -0
  306. package/esm/util/openFeatureWidget.js +1 -2
  307. package/esm/util/openViews.d.ts +1 -0
  308. package/esm/util/openViews.js +3 -3
  309. package/esm/util/parseLineByLine.d.ts +3 -4
  310. package/esm/util/parseLineByLine.js +7 -13
  311. package/esm/util/progress.d.ts +21 -21
  312. package/esm/util/progress.js +27 -26
  313. package/esm/util/renameRegions.d.ts +1 -2
  314. package/esm/util/renderToStaticMarkup.js +16 -16
  315. package/esm/util/rxjs.d.ts +7 -8
  316. package/esm/util/rxjs.js +12 -15
  317. package/esm/util/simpleFeature.d.ts +0 -1
  318. package/esm/util/svgColorProps.d.ts +11 -0
  319. package/esm/util/svgColorProps.js +28 -1
  320. package/esm/util/tabix.d.ts +3 -4
  321. package/esm/util/tabix.js +6 -7
  322. package/esm/util/thresholdScale.d.ts +54 -0
  323. package/esm/util/thresholdScale.js +112 -0
  324. package/esm/util/timeGate.d.ts +4 -5
  325. package/esm/util/timeGate.js +4 -5
  326. package/esm/util/trackConfigDelta.d.ts +22 -18
  327. package/esm/util/trackConfigDelta.js +40 -38
  328. package/esm/util/tracks.d.ts +27 -4
  329. package/esm/util/tracks.js +116 -43
  330. package/esm/util/translateTranscript.d.ts +44 -0
  331. package/esm/util/translateTranscript.js +102 -0
  332. package/esm/util/types/index.d.ts +19 -7
  333. package/esm/util/types/services.d.ts +1 -1
  334. package/esm/util/unknownSnapshotKeys.d.ts +15 -0
  335. package/esm/util/unknownSnapshotKeys.js +13 -0
  336. package/esm/util/useFeatureSequence.js +4 -4
  337. package/esm/util/useFetch.d.ts +3 -4
  338. package/esm/util/useFetch.js +5 -6
  339. package/esm/util/usePanelVirtualScroll.d.ts +7 -39
  340. package/esm/util/usePanelVirtualScroll.js +9 -40
  341. package/esm/util/useRowVirtualScroll.d.ts +6 -29
  342. package/esm/util/useRowVirtualScroll.js +8 -49
  343. package/esm/util/useVirtualScrollWheel.d.ts +20 -4
  344. package/esm/util/useVirtualScrollWheel.js +40 -84
  345. package/esm/util/viewHighlights.d.ts +3 -0
  346. package/esm/util/viewHighlights.js +5 -0
  347. package/esm/util/viewStatus.d.ts +24 -15
  348. package/esm/util/viewStatus.js +17 -0
  349. package/esm/util/withLaunchInput.d.ts +1 -1
  350. package/esm/util/withLaunchInput.js +0 -4
  351. package/package.json +26 -12
  352. package/esm/BaseFeatureWidget/SequenceFeatureDetails/test_data/DLGAP3.d.ts +0 -80
  353. package/esm/BaseFeatureWidget/SequenceFeatureDetails/test_data/DLGAP3.js +0 -583
  354. package/esm/BaseFeatureWidget/SequenceFeatureDetails/test_data/NCDN.d.ts +0 -141
  355. package/esm/BaseFeatureWidget/SequenceFeatureDetails/test_data/NCDN.js +0 -1116
  356. package/esm/ReExports/BaseFeatureDetails.d.ts +0 -1
  357. package/esm/ReExports/BaseFeatureDetails.js +0 -10
  358. package/esm/ReExports/barrelOnlyNames.d.ts +0 -5
  359. package/esm/ReExports/barrelOnlyNames.js +0 -63
  360. package/esm/ReExports/index.d.ts +0 -1
  361. package/esm/ReExports/index.js +0 -1
  362. package/esm/ReExports/publicTracks.d.ts +0 -1
  363. package/esm/ReExports/publicTracks.js +0 -14
  364. package/esm/ReExports/publicUi.d.ts +0 -4
  365. package/esm/ReExports/publicUi.js +0 -33
  366. package/esm/ReExports/publicUtil.d.ts +0 -1
  367. package/esm/ReExports/publicUtil.js +0 -32
  368. package/esm/ReExports/sharedModules.d.ts +0 -96
  369. package/esm/ReExports/sharedModules.js +0 -66
  370. package/esm/ReExports/workerNamespaceNames.d.ts +0 -11
  371. package/esm/ReExports/workerNamespaceNames.js +0 -275
  372. package/esm/pluggableElementTypes/models/HighlightsMixin.d.ts +0 -51
  373. package/esm/pluggableElementTypes/models/HighlightsMixin.js +0 -78
  374. package/esm/ui/highlightChipReveal.d.ts +0 -32
  375. package/esm/ui/highlightChipReveal.js +0 -39
  376. package/esm/util/adapterConfigKey.d.ts +0 -12
  377. package/esm/util/adapterConfigKey.js +0 -14
  378. package/esm/util/stopToken.d.ts +0 -212
  379. package/esm/util/stopToken.js +0 -438
@@ -0,0 +1,37 @@
1
+ /** #api */
2
+ export declare const STRAND_FIELD = "strand";
3
+ /**
4
+ * #api
5
+ * The row a feature with nothing in a categorical field lands on, so a key
6
+ * says why a mark is grey rather than listing a blank value.
7
+ */
8
+ export declare const NO_VALUE_LABEL = "(no value)";
9
+ /**
10
+ * #api
11
+ * One categorical field as every channel reads it — a facet's sections, a
12
+ * color's range entries, a key's rows. `key` files a value, `compare`
13
+ * orders keys (the `domain` first, the rest by `compareGroupKeys`, `''`
14
+ * after them), `label` names a key in a legend, `sectionLabel` on a chip, and
15
+ * `color` paints it. A key's color depends only on the key and the
16
+ * declaration, so every region agrees on it.
17
+ */
18
+ export interface CategoricalField {
19
+ field: string;
20
+ /** The declared order, or the field's own where none is declared. */
21
+ domain: readonly string[];
22
+ /**
23
+ * Every key a value can file under is in `domain`, as a threshold scale's
24
+ * bins are, so a key lists all of them whether or not anything painted one.
25
+ */
26
+ closed?: boolean;
27
+ key: (value: unknown) => string;
28
+ compare: (a: string, b: string) => number;
29
+ label: (key: string) => string;
30
+ sectionLabel: (key: string) => string;
31
+ color: (key: string) => string;
32
+ }
33
+ /** #api */
34
+ export declare function categoricalField(field: string, { domain, range, }?: {
35
+ domain?: readonly string[];
36
+ range?: readonly string[];
37
+ }): CategoricalField;
@@ -0,0 +1,52 @@
1
+ import { categoricalColorScale } from '../ui/colors.js';
2
+ import { NO_CATEGORY_COLOR } from './color/index.js';
3
+ import { groupKeyComparator, valueText } from './groupKeys.js';
4
+ /** #api */
5
+ export const STRAND_FIELD = 'strand';
6
+ /**
7
+ * #api
8
+ * The row a feature with nothing in a categorical field lands on, so a key
9
+ * says why a mark is grey rather than listing a blank value.
10
+ */
11
+ export const NO_VALUE_LABEL = '(no value)';
12
+ // A field whose values have names, an order and colors of their own, so
13
+ // every channel reading it agrees without a config saying so. Red forward and
14
+ // blue reverse is the vocabulary the synteny ribbons paint too.
15
+ const VOCABULARIES = {
16
+ [STRAND_FIELD]: {
17
+ missing: '0',
18
+ domain: ['1', '-1', '0'],
19
+ range: ['tomato', 'cornflowerblue', 'goldenrod'],
20
+ labels: {
21
+ '1': 'Forward strand',
22
+ '-1': 'Reverse strand',
23
+ '0': 'No strand',
24
+ },
25
+ },
26
+ };
27
+ /** #api */
28
+ export function categoricalField(field, { domain = [], range = [], } = {}) {
29
+ const vocabulary = VOCABULARIES[field];
30
+ const order = domain.length > 0 ? domain : (vocabulary?.domain ?? []);
31
+ const colors = range.length > 0 ? range : (vocabulary?.range ?? []);
32
+ const named = (key) => vocabulary?.labels[key];
33
+ let colorOf;
34
+ return {
35
+ field,
36
+ domain: order,
37
+ key: value => {
38
+ const key = valueText(value);
39
+ return key === '' && vocabulary ? vocabulary.missing : key;
40
+ },
41
+ compare: groupKeyComparator(order),
42
+ label: key => named(key) ?? (key === '' ? NO_VALUE_LABEL : key),
43
+ sectionLabel: key => named(key) ?? `${field}: ${key === '' ? 'none' : key}`,
44
+ color: key => {
45
+ if (key === '') {
46
+ return NO_CATEGORY_COLOR;
47
+ }
48
+ colorOf ??= categoricalColorScale(order, colors);
49
+ return colorOf(key);
50
+ },
51
+ };
52
+ }
@@ -1,2 +1,3 @@
1
1
  export declare function namedColorToHex(name: string): string | undefined;
2
2
  export declare function isNamedColor(name: string): boolean;
3
+ export declare const CSS_COLOR_NAMES: readonly string[];
@@ -158,3 +158,4 @@ export function namedColorToHex(name) {
158
158
  export function isNamedColor(name) {
159
159
  return Object.hasOwn(colors, name);
160
160
  }
161
+ export const CSS_COLOR_NAMES = Object.keys(colors);
@@ -20,7 +20,9 @@ export declare function emphasize(color: string, coefficient?: number): string;
20
20
  * default refName colors.
21
21
  */
22
22
  export declare function makeContrasting(foreground: string, background?: string, minContrastRatio?: number): string;
23
- export { isNamedColor, namedColorToHex } from './cssColorsLevel4.ts';
23
+ export { CSS_COLOR_NAMES, isNamedColor, namedColorToHex, } from './cssColorsLevel4.ts';
24
+ export declare const NO_CATEGORY_COLOR = "#afafaf";
25
+ export declare const MISCONFIGURED_COLOR = "#808080";
24
26
  /**
25
27
  * #api
26
28
  * Move a color's OKLCH lightness by `lightnessShift` and scale its chroma,
@@ -69,8 +71,8 @@ export declare function relight(color: string, lightnessShift: number, chromaSca
69
71
  *
70
72
  * A value that is absent gets NO_CATEGORY_COLOR rather than a hue, and that is
71
73
  * the difference between this being usable on real data and not. The everyday
72
- * caller is the Color-by-attribute dialog, which writes
73
- * `jexl:randomColor(get(feature,'<attr>'))` over a whole track — and most files
74
+ * caller is a `jexl:randomColor(get(feature,'<attr>'))` color slot over a
75
+ * whole track — and most files
74
76
  * have the attribute on some features and not others, so most of the time this
75
77
  * is handed `undefined`. It used to throw on that (`str.length` of undefined),
76
78
  * once per feature, and what a reader saw was every unlabelled feature in one
@@ -72,7 +72,7 @@ export function makeContrasting(foreground, background = 'white', minContrastRat
72
72
  }
73
73
  return best;
74
74
  }
75
- export { isNamedColor, namedColorToHex } from './cssColorsLevel4.js';
75
+ export { CSS_COLOR_NAMES, isNamedColor, namedColorToHex, } from './cssColorsLevel4.js';
76
76
  // The (lightness, chroma) tiers randomColor picks between, in OKLCH. Values are
77
77
  // in the band a hand-built categorical palette occupies — bright enough to tell
78
78
  // apart, dark enough that black text over one still reads, and never near
@@ -81,7 +81,10 @@ export { isNamedColor, namedColorToHex } from './cssColorsLevel4.js';
81
81
  // What a value-less feature is painted. Neutral and unsaturated on purpose: it
82
82
  // has to read as "not in a category" beside a palette whose every member is
83
83
  // equally light and equally colorful, so it cannot be one more hue.
84
- const NO_CATEGORY_COLOR = '#afafaf';
84
+ export const NO_CATEGORY_COLOR = '#afafaf';
85
+ // What a colour declaration paints where it reads nothing it can colour, so a
86
+ // misconfiguration surfaces rather than passing for the no-category grey.
87
+ export const MISCONFIGURED_COLOR = '#808080';
85
88
  const RANDOM_COLOR_TIERS = [
86
89
  { lightness: 0.66, chroma: 0.15 },
87
90
  { lightness: 0.56, chroma: 0.14 },
@@ -175,8 +178,8 @@ export function relight(color, lightnessShift, chromaScale = 1) {
175
178
  *
176
179
  * A value that is absent gets NO_CATEGORY_COLOR rather than a hue, and that is
177
180
  * the difference between this being usable on real data and not. The everyday
178
- * caller is the Color-by-attribute dialog, which writes
179
- * `jexl:randomColor(get(feature,'<attr>'))` over a whole track — and most files
181
+ * caller is a `jexl:randomColor(get(feature,'<attr>'))` color slot over a
182
+ * whole track — and most files
180
183
  * have the attribute on some features and not others, so most of the time this
181
184
  * is handed `undefined`. It used to throw on that (`str.length` of undefined),
182
185
  * once per feature, and what a reader saw was every unlabelled feature in one
@@ -1,7 +1,7 @@
1
1
  import { abgrToCssRgba } from '@jbrowse/render-core/marks/colorFill';
2
- import type { Color } from './color-bits/index.ts';
3
2
  import type { Feature } from './simpleFeature.ts';
4
3
  export { abgrToCssRgba };
4
+ export { isCssColor, parseCssColorOr } from './cssColorParse.ts';
5
5
  export { alpha, blend, darken, formatHEX, formatHEXA, formatRGBA, getAlpha, getBlue, getGreen, getLuminance, getRed, lighten, newColor, parse, toHSLA, toRGBA, } from './color-bits/index.ts';
6
6
  export type { Color } from './color-bits/index.ts';
7
7
  /**
@@ -19,7 +19,6 @@ export declare function featureItemRgb(raw: unknown): string | undefined;
19
19
  * undefined if it declares none.
20
20
  */
21
21
  export declare function featureBedColor(feature: Feature): string | undefined;
22
- export declare function parseCssColorOr(color: string, fallback: Color): Color;
23
22
  export declare function parseCssColor(color: string | undefined | null): number;
24
23
  export declare function cssColorToNormalizedRgb(color: string): [number, number, number];
25
24
  export declare function cssColorToRgb(color: string): [number, number, number];
@@ -1,7 +1,8 @@
1
1
  import { abgrToCssRgba } from '@jbrowse/render-core/marks/colorFill';
2
- import { getAlpha, getBlue, getGreen, getRed, newColor, parse, } from './color-bits/index.js';
3
- import { namedColorToHex } from './color/cssColorsLevel4.js';
2
+ import { getAlpha, getBlue, getGreen, getRed, newColor, } from './color-bits/index.js';
3
+ import { bedTriple, parseCssColorOr } from './cssColorParse.js';
4
4
  export { abgrToCssRgba };
5
+ export { isCssColor, parseCssColorOr } from './cssColorParse.js';
5
6
  export { alpha, blend, darken, formatHEX, formatHEXA, formatRGBA, getAlpha, getBlue, getGreen, getLuminance, getRed, lighten, newColor, parse, toHSLA, toRGBA, } from './color-bits/index.js';
6
7
  // Magenta sentinel for invalid input. User-written jexl color callbacks can
7
8
  // legitimately return undefined (e.g. when a feature lacks the field they
@@ -9,10 +10,6 @@ export { alpha, blend, darken, formatHEX, formatHEXA, formatRGBA, getAlpha, getB
9
10
  // Returning magenta makes the bad slot visually obvious without breaking the
10
11
  // rest of the render.
11
12
  const INVALID_COLOR = newColor(255, 0, 255, 255);
12
- // A bare BED color triple ("255,0,0"), which is not a CSS color but is what
13
- // BED-family adapters put on the feature verbatim. The spec has no spaces, but
14
- // tolerate them rather than silently ignoring an otherwise-usable color.
15
- const BED_TRIPLE = /^(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})$/;
16
13
  // UCSC's convention is that a color of "0" means "no color specified", and plain
17
14
  // BED12 files fill the column with that placeholder (often spelled as the
18
15
  // all-zero triple) rather than omitting it — every itemRgb in our own
@@ -20,17 +17,6 @@ const BED_TRIPLE = /^(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})$/;
20
17
  // ordinary BED12 track solid black, so read them as absent. A file that really
21
18
  // wants black can say so with an explicit `color` slot.
22
19
  const BED_TRIPLE_UNSET = /^0(,0,0)?$/;
23
- /**
24
- * Normalize a bare BED color triple to canonical "r,g,b", or undefined if the
25
- * string isn't one. Each component must be in range: the underlying parser
26
- * masks to 8 bits, so a bogus "999,0,0" would otherwise *wrap* to 231 and paint
27
- * a plausible-looking but wrong color rather than being caught.
28
- */
29
- function bedTriple(str) {
30
- const m = BED_TRIPLE.exec(str.trim());
31
- const rgb = m?.slice(1, 4).map(Number);
32
- return rgb?.every(n => n <= 255) ? rgb.join(',') : undefined;
33
- }
34
20
  /**
35
21
  * One raw attribute value as a usable BED color, or undefined when it isn't
36
22
  * one. Deliberately strict: this feeds an *automatic* coloring path, so a value
@@ -75,27 +61,6 @@ export function featureBedColor(feature) {
75
61
  }
76
62
  return found;
77
63
  }
78
- // Resolve a CSS color string to a Color: honors named colors, `transparent`,
79
- // and bare BED color triples, and returns `fallback` on malformed-but-nonempty
80
- // input. `parse` throws on e.g. an empty "rgb()"; callers pass a fallback so one
81
- // bad per-feature color can't crash a whole render/RPC. An out-of-range triple
82
- // is left to throw into `fallback` (magenta) rather than wrapping to a wrong
83
- // color — the same rule featureItemRgb applies, so a jexl callback reading an
84
- // itemRgb column and the automatic path agree on what counts as a color.
85
- export function parseCssColorOr(color, fallback) {
86
- const str = color.trim().toLowerCase();
87
- if (str === 'transparent') {
88
- return newColor(0, 0, 0, 0);
89
- }
90
- try {
91
- const hex = namedColorToHex(str);
92
- const triple = bedTriple(str);
93
- return parse(hex ? hex : triple ? `rgb(${triple})` : str);
94
- }
95
- catch {
96
- return fallback;
97
- }
98
- }
99
64
  export function parseCssColor(color) {
100
65
  if (typeof color !== 'string' || color.length === 0) {
101
66
  return INVALID_COLOR;
@@ -120,9 +85,22 @@ export function cssColorToRgba(color) {
120
85
  export function packAbgr(r, g, b, a) {
121
86
  return ((a << 24) | (b << 16) | (g << 8) | r) >>> 0;
122
87
  }
88
+ // A packer resolves the same few strings once per primitive, so the parse is
89
+ // cached by string. Capped, because BED itemRgb triples are unbounded.
90
+ const ABGR_CACHE_LIMIT = 4096;
91
+ const abgrByCss = new Map();
123
92
  export function cssColorToABGR(color) {
93
+ const cached = abgrByCss.get(color);
94
+ if (cached !== undefined) {
95
+ return cached;
96
+ }
124
97
  const c = parseCssColor(color);
125
- return packAbgr(getRed(c), getGreen(c), getBlue(c), getAlpha(c));
98
+ const packed = packAbgr(getRed(c), getGreen(c), getBlue(c), getAlpha(c));
99
+ if (abgrByCss.size >= ABGR_CACHE_LIMIT) {
100
+ abgrByCss.clear();
101
+ }
102
+ abgrByCss.set(color, packed);
103
+ return packed;
126
104
  }
127
105
  // Replace the alpha byte of an ABGR-packed u32, keeping its RGB. RGB already
128
106
  // occupies the low 24 bits (b<<16 | g<<8 | r), so this is a mask + or — no
@@ -1,4 +1,5 @@
1
1
  import type { RampStop } from '../ui/colorScale.ts';
2
+ import type { ColorSchemeName } from './colorSchemes.ts';
2
3
  /** One evenly-spaced ramp stop: 8-bit red, green, blue, alpha. */
3
4
  export type ColorRampStop = readonly [number, number, number, number];
4
5
  /**
@@ -8,6 +9,25 @@ export type ColorRampStop = readonly [number, number, number, number];
8
9
  * stops.
9
10
  */
10
11
  export declare const VIRIDIS_STOPS: readonly ColorRampStop[];
12
+ /**
13
+ * #api
14
+ * The domain a continuous colour scale spans: each end `min` or `max` pins,
15
+ * else the extent's, ascending, since a span has no direction and `reverse`
16
+ * is the ramp's. An open end stops at a pinned one rather than crossing it,
17
+ * and an extent holding no value (`[Infinity, -Infinity]`) spans [0, 1].
18
+ */
19
+ export declare function rampDomain(min: number | undefined, max: number | undefined, extent: readonly [number, number]): [number, number];
20
+ /**
21
+ * #api
22
+ * The stops a continuous colour scale samples: `range`'s CSS colours where it
23
+ * lists any, else the named `scheme`, viridis while that is unset, turned
24
+ * round under `reverse`.
25
+ */
26
+ export declare function colorRampStops({ range, scheme, reverse, }: {
27
+ range?: readonly string[];
28
+ scheme?: ColorSchemeName;
29
+ reverse?: boolean;
30
+ }): readonly ColorRampStop[];
11
31
  /**
12
32
  * #api
13
33
  * The color at `t` in `[0, 1]` across a list of EVENLY SPACED stops, linearly
@@ -22,8 +42,14 @@ export declare function sampleColorRamp(stops: readonly ColorRampStop[], t: numb
22
42
  * texture both GPU backends upload and the Canvas2D twins index — entry `i` is
23
43
  * the color at `t = i / (N - 1)`. N comes off the shader that samples it, so
24
44
  * the table and `rampColor`'s texel mapping cannot disagree.
45
+ *
46
+ * `mid` is where the stop list's own midpoint lands in the table, so a
47
+ * diverging ramp whose middle colour belongs at a value off the centre of the
48
+ * domain is baked into the bytes. Every reader — the shader, the Canvas2D
49
+ * fillStyle table, the legend bar — then samples one evenly spaced table and
50
+ * cannot disagree about the warp.
25
51
  */
26
- export declare function buildColorRampLut(stops: readonly ColorRampStop[]): Uint8Array<ArrayBuffer>;
52
+ export declare function buildColorRampLut(stops: readonly ColorRampStop[], mid?: number): Uint8Array<ArrayBuffer>;
27
53
  /**
28
54
  * #api
29
55
  * `n` evenly spaced legend stops read straight out of a
@@ -1,4 +1,5 @@
1
1
  import { COLOR_RAMP_LUT_ENTRIES } from '@jbrowse/render-core/colorRampLut';
2
+ import { cssColorToRgba } from './colorBits.js';
2
3
  // Viridis full 256-color hex spec, kept whole so a LUT built from these stops
3
4
  // carries the smooth perceptually-uniform gradient rather than an
4
5
  // interpolation over a subset. Lived in the hic plugin until wiggle density
@@ -25,6 +26,42 @@ function viridisStopsFromHex() {
25
26
  * stops.
26
27
  */
27
28
  export const VIRIDIS_STOPS = viridisStopsFromHex();
29
+ const SCHEME_STOPS = {
30
+ viridis: VIRIDIS_STOPS,
31
+ };
32
+ const EMPTY_EXTENT_DOMAIN = [0, 1];
33
+ /**
34
+ * #api
35
+ * The domain a continuous colour scale spans: each end `min` or `max` pins,
36
+ * else the extent's, ascending, since a span has no direction and `reverse`
37
+ * is the ramp's. An open end stops at a pinned one rather than crossing it,
38
+ * and an extent holding no value (`[Infinity, -Infinity]`) spans [0, 1].
39
+ */
40
+ export function rampDomain(min, max, extent) {
41
+ const [lo, hi] = extent[0] <= extent[1] ? extent : EMPTY_EXTENT_DOMAIN;
42
+ if (min !== undefined && max !== undefined) {
43
+ return min <= max ? [min, max] : [max, min];
44
+ }
45
+ if (min !== undefined) {
46
+ return [min, Math.max(min, hi)];
47
+ }
48
+ if (max !== undefined) {
49
+ return [Math.min(lo, max), max];
50
+ }
51
+ return [lo, hi];
52
+ }
53
+ /**
54
+ * #api
55
+ * The stops a continuous colour scale samples: `range`'s CSS colours where it
56
+ * lists any, else the named `scheme`, viridis while that is unset, turned
57
+ * round under `reverse`.
58
+ */
59
+ export function colorRampStops({ range, scheme, reverse, }) {
60
+ const stops = range?.length
61
+ ? range.map(c => cssColorToRgba(c))
62
+ : SCHEME_STOPS[scheme ?? 'viridis'];
63
+ return reverse ? stops.toReversed() : stops;
64
+ }
28
65
  function lerp8(a, b, t) {
29
66
  return Math.round(a * (1 - t) + b * t);
30
67
  }
@@ -54,12 +91,20 @@ export function sampleColorRamp(stops, t) {
54
91
  * texture both GPU backends upload and the Canvas2D twins index — entry `i` is
55
92
  * the color at `t = i / (N - 1)`. N comes off the shader that samples it, so
56
93
  * the table and `rampColor`'s texel mapping cannot disagree.
94
+ *
95
+ * `mid` is where the stop list's own midpoint lands in the table, so a
96
+ * diverging ramp whose middle colour belongs at a value off the centre of the
97
+ * domain is baked into the bytes. Every reader — the shader, the Canvas2D
98
+ * fillStyle table, the legend bar — then samples one evenly spaced table and
99
+ * cannot disagree about the warp.
57
100
  */
58
- export function buildColorRampLut(stops) {
101
+ export function buildColorRampLut(stops, mid = 0.5) {
59
102
  const last = COLOR_RAMP_LUT_ENTRIES - 1;
60
103
  const data = new Uint8Array(COLOR_RAMP_LUT_ENTRIES * 4);
104
+ const m = Math.min(1, Math.max(0, mid));
61
105
  for (let i = 0; i < COLOR_RAMP_LUT_ENTRIES; i++) {
62
- const [r, g, b, a] = sampleColorRamp(stops, i / last);
106
+ const t = i / last;
107
+ const [r, g, b, a] = sampleColorRamp(stops, unwarp(t, m));
63
108
  data[i * 4] = r;
64
109
  data[i * 4 + 1] = g;
65
110
  data[i * 4 + 2] = b;
@@ -67,6 +112,15 @@ export function buildColorRampLut(stops) {
67
112
  }
68
113
  return data;
69
114
  }
115
+ function unwarp(t, mid) {
116
+ if (mid <= 0) {
117
+ return t >= 1 ? 1 : 0.5 + 0.5 * t;
118
+ }
119
+ if (mid >= 1) {
120
+ return t <= 0 ? 0 : 0.5 * t;
121
+ }
122
+ return t <= mid ? (0.5 * t) / mid : 0.5 + (0.5 * (t - mid)) / (1 - mid);
123
+ }
70
124
  /**
71
125
  * #api
72
126
  * `n` evenly spaced legend stops read straight out of a
@@ -0,0 +1,9 @@
1
+ /**
2
+ * #api
3
+ * The named ramps a continuous colour scale's `scheme` takes, each one a stop
4
+ * table in `colorRamp.ts` that every ramp baker reads, so no display can name
5
+ * a scheme nothing bakes.
6
+ */
7
+ export declare const COLOR_SCHEMES: readonly ['viridis'];
8
+ /** #api */
9
+ export type ColorSchemeName = (typeof COLOR_SCHEMES)[number];
@@ -0,0 +1,7 @@
1
+ /**
2
+ * #api
3
+ * The named ramps a continuous colour scale's `scheme` takes, each one a stop
4
+ * table in `colorRamp.ts` that every ramp baker reads, so no display can name
5
+ * a scheme nothing bakes.
6
+ */
7
+ export const COLOR_SCHEMES = ['viridis'];
@@ -1,5 +1,4 @@
1
1
  import type { RpcStatus, StatusWindow } from './progress.ts';
2
- import type { StopToken } from './stopToken.ts';
3
2
  import type { IStateTreeNode } from '@jbrowse/mobx-state-tree';
4
3
  /**
5
4
  * Where a rotation reports, in the one of two modes the host is actually in.
@@ -51,8 +50,7 @@ export interface StatusChannel {
51
50
  }
52
51
  export declare function createStatusChannel(): StatusChannel;
53
52
  export interface ActiveFetch {
54
- /** stop token to forward to the RPC call */
55
- stopToken: StopToken;
53
+ signal: AbortSignal;
56
54
  /**
57
55
  * True only while this is still the most recent fetch AND `self` is alive.
58
56
  * Gate every post-await write — result commit, error set — on it so a
@@ -73,8 +71,8 @@ export interface ActiveFetch {
73
71
  * other operation on the host is still reporting.
74
72
  *
75
73
  * Both together, because a caller doing it by hand gets a subset.
76
- * `isCurrent` is `token === current && isAlive`, and a run that *completes*
77
- * never rotates its own token — so without this the guard stays open past the
74
+ * `isCurrent` is `signal === current && isAlive`, and a run that *completes*
75
+ * never rotates its own signal — so without this the guard stays open past the
78
76
  * work and a trailing write lands on top of a hand-written
79
77
  * `setStatusMessage(undefined)` up to a window later.
80
78
  *
@@ -85,19 +83,18 @@ export interface ActiveFetch {
85
83
  end: () => void;
86
84
  }
87
85
  /**
88
- * Latest-wins stop-token rotation for a fetch that runs in a bare `autorun`
86
+ * Latest-wins abort rotation for a fetch that runs in a bare `autorun`
89
87
  * rather than through `FetchMixin.runFetch` (which welds the same mechanics to
90
88
  * `fetchGeneration`, so it's only for viewport-driven LGV fetches). Each
91
- * `begin()` aborts the prior fetch's token and returns a fresh one plus an
92
- * `isCurrent()` guard that captures this run's token — gate every post-await
93
- * write on it and a superseded or torn-down fetch can never clobber fresher
94
- * data. The guard is the return value, so a caller can't forget to compare a
95
- * token by hand.
89
+ * `begin()` aborts the prior fetch and returns a fresh signal plus an
90
+ * `isCurrent()` guard that captures this run — gate every post-await write on
91
+ * it and a superseded or torn-down fetch can never clobber fresher data. The
92
+ * guard is the return value, so a caller can't forget to compare by hand.
96
93
  *
97
94
  * `end()` in the run's `finally` is the other half, and for the same reason —
98
95
  * see {@link ActiveFetch.end} for the two things it does together.
99
96
  *
100
- * Owns the token mechanics and the status channel; the caller keeps its own
97
+ * Owns the controller and the status channel; the caller keeps its own
101
98
  * loading/error/commit side-effects. Three holders: `FetchMixin` as a member
102
99
  * (so `cancelFetch` can reach it), `installFetch` one per installation (every
103
100
  * other fetch in the tree runs on that skeleton), and the synteny diagonalize
@@ -111,8 +108,8 @@ export interface ActiveFetch {
111
108
  * passes a {@link createStatusChannel}, which is one volatile instead of two
112
109
  * fields and an action.
113
110
  */
114
- export type StopTokenRotation = ReturnType<typeof createStopTokenRotation>;
115
- export declare function createStopTokenRotation(self: IStateTreeNode, report: StatusReporter): {
111
+ export type AbortRotation = ReturnType<typeof createAbortRotation>;
112
+ export declare function createAbortRotation(self: IStateTreeNode, report: StatusReporter): {
116
113
  begin(): ActiveFetch;
117
114
  cancel: () => void;
118
115
  dispose(): void;
@@ -1,7 +1,6 @@
1
1
  import { isAlive } from '@jbrowse/mobx-state-tree';
2
2
  import { observable, runInAction } from 'mobx';
3
3
  import { createStatusWindow, statusFraction, statusMessageText, } from './progress.js';
4
- import { createStopToken, stopStopToken } from './stopToken.js';
5
4
  export function createStatusChannel() {
6
5
  // MobX rather than MST, so this is a value a model can hold rather than a
7
6
  // node it has to parent. A volatile is `observable.ref`, so the fields have
@@ -28,8 +27,8 @@ export function createStatusChannel() {
28
27
  },
29
28
  };
30
29
  }
31
- export function createStopTokenRotation(self, report) {
32
- let currentStopToken;
30
+ export function createAbortRotation(self, report) {
31
+ let current;
33
32
  // The host's window when it has one, so a display composing `FetchMixin` has
34
33
  // one window rather than two writing one field; our own otherwise. Lent means
35
34
  // this fetch is one slot beside the host's others rather than a second writer
@@ -49,8 +48,8 @@ export function createStopTokenRotation(self, report) {
49
48
  /**
50
49
  * Stop the in-flight fetch without starting one, and retire its slot.
51
50
  *
52
- * Dropping `currentStopToken` rather than only stopping it is what closes
53
- * every outstanding guard: `isCurrent` compares against this field, so one
51
+ * Dropping `current` rather than only aborting it is what closes every
52
+ * outstanding guard: `isCurrent` compares against this field, so one
54
53
  * assignment makes a fetch already past its await stale, whether it is the one
55
54
  * being cancelled or a superseded predecessor still unwinding.
56
55
  *
@@ -61,10 +60,8 @@ export function createStopTokenRotation(self, report) {
61
60
  * works: `addDisposer(self, rotation.dispose)` is a shape callers reach for.
62
61
  */
63
62
  const cancel = () => {
64
- if (currentStopToken) {
65
- stopStopToken(currentStopToken);
66
- currentStopToken = undefined;
67
- }
63
+ current?.abort();
64
+ current = undefined;
68
65
  // a fetch in flight when this is called never reaches its `finally`, and a
69
66
  // slot nobody retires goes on voting
70
67
  openStream?.clear();
@@ -72,17 +69,15 @@ export function createStopTokenRotation(self, report) {
72
69
  };
73
70
  return {
74
71
  begin() {
75
- if (currentStopToken) {
76
- stopStopToken(currentStopToken);
77
- }
78
- const stopToken = createStopToken();
79
- currentStopToken = stopToken;
72
+ current?.abort();
73
+ const controller = new AbortController();
74
+ current = controller;
80
75
  // `ended` is the term a completed fetch has no other way to express: the
81
- // token comparison catches a SUPERSEDED one, but a fetch that simply
82
- // finished still holds the current token. The stream reads it as well as
76
+ // controller comparison catches a SUPERSEDED one, but a fetch that simply
77
+ // finished still holds the current one. The stream reads it as well as
83
78
  // the caller's commit guard, which is why both go through this closure.
84
79
  let ended = false;
85
- const isCurrent = () => !ended && stopToken === currentStopToken && isAlive(self);
80
+ const isCurrent = () => !ended && controller === current && isAlive(self);
86
81
  // Opened BEFORE the superseded run reaches its `finally`, which is what
87
82
  // keeps the label the user is looking at from blanking between the two:
88
83
  // the run being replaced is suspended at an await and resumes a microtask
@@ -92,18 +87,11 @@ export function createStopTokenRotation(self, report) {
92
87
  const stream = statusWindow.open({ isCurrent });
93
88
  openStream = stream;
94
89
  return {
95
- stopToken,
90
+ signal: controller.signal,
96
91
  isCurrent,
97
92
  statusCallback: stream.statusCallback,
98
93
  end() {
99
94
  ended = true;
100
- // A completed fetch's token is released here, not only on supersede
101
- // or cancel — otherwise it pins its AbortSignal controllers (and blob
102
- // URL) until the next `begin()`, forever for a one-shot fetch that
103
- // succeeds and never reruns. `stopStopToken` is guarded, so the
104
- // superseded and cancelled runs that arrive here already-stopped cost
105
- // nothing.
106
- stopStopToken(stopToken);
107
95
  if (openStream === stream) {
108
96
  openStream = undefined;
109
97
  }
@@ -114,7 +102,7 @@ export function createStopTokenRotation(self, report) {
114
102
  cancel,
115
103
  dispose() {
116
104
  cancel();
117
- // the window outlives the token: a trailing write is queued on a timer,
105
+ // the window outlives the fetch: a trailing write is queued on a timer,
118
106
  // and while the sink's `isCurrent` makes it a no-op rather than a write to
119
107
  // a dead node, the timer itself still stands for up to a window past
120
108
  // teardown. Only ours — resetting a lent one drops a write the host's
@@ -0,0 +1,15 @@
1
+ import type { Color } from './color-bits/core.ts';
2
+ /**
3
+ * Normalize a bare BED color triple to canonical "r,g,b", or undefined if the
4
+ * string isn't one. Each component must be in range: the underlying parser
5
+ * masks to 8 bits, so a bogus "999,0,0" would otherwise *wrap* to 231 and paint
6
+ * a plausible-looking but wrong color rather than being caught.
7
+ */
8
+ export declare function bedTriple(str: string): string | undefined;
9
+ export declare function parseCssColorOr(color: string, fallback: Color): Color;
10
+ /**
11
+ * Whether the painters read `color` as a color — a CSS name, hex, functional
12
+ * form, `transparent` or a BED triple — rather than as the invalid sentinel.
13
+ * What a `color` config slot admits.
14
+ */
15
+ export declare function isCssColor(color: string): boolean;
@@ -0,0 +1,53 @@
1
+ import { newColor } from './color-bits/core.js';
2
+ import { parse } from './color-bits/parse.js';
3
+ import { namedColorToHex } from './color/cssColorsLevel4.js';
4
+ // Split out of colorBits.ts so a config slot can ask "is this a color?" without
5
+ // taking that module's re-export of render-core's packers: the closure ceiling
6
+ // in scripts/moduleClosure.test.ts is what says so.
7
+ // A bare BED color triple ("255,0,0"), which is not a CSS color but is what
8
+ // BED-family adapters put on the feature verbatim. The spec has no spaces, but
9
+ // tolerate them rather than silently ignoring an otherwise-usable color.
10
+ const BED_TRIPLE = /^(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})$/;
11
+ /**
12
+ * Normalize a bare BED color triple to canonical "r,g,b", or undefined if the
13
+ * string isn't one. Each component must be in range: the underlying parser
14
+ * masks to 8 bits, so a bogus "999,0,0" would otherwise *wrap* to 231 and paint
15
+ * a plausible-looking but wrong color rather than being caught.
16
+ */
17
+ export function bedTriple(str) {
18
+ const m = BED_TRIPLE.exec(str.trim());
19
+ const rgb = m?.slice(1, 4).map(Number);
20
+ return rgb?.every(n => n <= 255) ? rgb.join(',') : undefined;
21
+ }
22
+ function tryParseCssColor(color) {
23
+ const str = color.trim().toLowerCase();
24
+ if (str === 'transparent') {
25
+ return newColor(0, 0, 0, 0);
26
+ }
27
+ try {
28
+ const hex = namedColorToHex(str);
29
+ const triple = bedTriple(str);
30
+ return parse(hex ? hex : triple ? `rgb(${triple})` : str);
31
+ }
32
+ catch {
33
+ return undefined;
34
+ }
35
+ }
36
+ // Resolve a CSS color string to a Color: honors named colors, `transparent`,
37
+ // and bare BED color triples, and returns `fallback` on malformed-but-nonempty
38
+ // input. `parse` throws on e.g. an empty "rgb()"; callers pass a fallback so one
39
+ // bad per-feature color can't crash a whole render/RPC. An out-of-range triple
40
+ // is left to throw into `fallback` (magenta) rather than wrapping to a wrong
41
+ // color — the same rule featureItemRgb applies, so a jexl callback reading an
42
+ // itemRgb column and the automatic path agree on what counts as a color.
43
+ export function parseCssColorOr(color, fallback) {
44
+ return tryParseCssColor(color) ?? fallback;
45
+ }
46
+ /**
47
+ * Whether the painters read `color` as a color — a CSS name, hex, functional
48
+ * form, `transparent` or a BED triple — rather than as the invalid sentinel.
49
+ * What a `color` config slot admits.
50
+ */
51
+ export function isCssColor(color) {
52
+ return tryParseCssColor(color) !== undefined;
53
+ }