@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
@@ -1,46 +1,29 @@
1
+ import { makeScoreNormalizer, scaleTypeCode, } from '@jbrowse/render-core/scoreScale';
1
2
  import { GLYPH_DISC } from '@jbrowse/render-core/shaders/pointMarkConsts';
2
- import { categoricalPalette, categoricalValueColor } from '../ui/colors.js';
3
- import { cssColorToABGR, cssColorToRgba, packAbgr } from './colorBits.js';
4
- import { VIRIDIS_STOPS, buildColorRampLut } from './colorRamp.js';
3
+ import { categoricalScale } from '../ui/colors.js';
4
+ import { categoricalField } from './categoricalField.js';
5
+ import { MISCONFIGURED_COLOR } from './color/index.js';
6
+ import { cssColorToABGR, packAbgr } from './colorBits.js';
7
+ import { buildColorRampLut, colorRampStops, rampDomain } from './colorRamp.js';
8
+ import { fieldReader } from './fieldReader.js';
5
9
  import Flatbush from './flatbush/index.js';
6
10
  import { GLYPH_CODES, GLYPH_NAMES } from './glyphNames.js';
7
11
  import { isJexl, stringToJexlExpression } from './jexlStrings.js';
12
+ import { numericValue } from './numericValue.js';
8
13
  import { buildJexlContext } from './simpleFeature.js';
14
+ import { thresholdCuts, thresholdIndex, thresholdLabels, thresholdPalette, } from './thresholdScale.js';
15
+ export { COLOR_SCHEMES } from './colorSchemes.js';
16
+ export { NO_VALUE_LABEL } from './categoricalField.js';
9
17
  export const DEFAULT_MARK_COLOR = '#0068d1';
10
- // What a feature paints when its colour field is missing or a `jexl:` colour
11
- // yields a non-string: visible, so a misconfiguration surfaces rather than
12
- // vanishing.
13
- const FALLBACK_COLOR = cssColorToABGR('#808080');
14
- /**
15
- * #api
16
- * The key row a feature with nothing in a categorical field lands on, so the
17
- * legend says why a mark is grey, or a disc, rather than listing a blank
18
- * value.
19
- */
20
- export const NO_VALUE_LABEL = '(no value)';
18
+ const FALLBACK_COLOR = cssColorToABGR(MISCONFIGURED_COLOR);
21
19
  function jexlExpression(ref, jexl) {
22
20
  if (!jexl) {
23
21
  throw new Error(`a jexl: channel needs a jexl instance (${ref})`);
24
22
  }
25
23
  return stringToJexlExpression(ref, jexl);
26
24
  }
27
- function fieldReader(ref, jexl) {
28
- if (typeof ref === 'function') {
29
- return ref;
30
- }
31
- if (isJexl(ref)) {
32
- const expr = jexlExpression(ref, jexl);
33
- return feature => expr.eval(buildJexlContext({ feature }));
34
- }
35
- return feature => feature.get(ref);
36
- }
37
- /**
38
- * #api
39
- * The field a `y` declaration reads, whichever of its two forms it is
40
- * written in.
41
- */
42
- export function valueField(y) {
43
- return typeof y === 'string' ? y : y.field;
25
+ function channelReader(ref, jexl) {
26
+ return typeof ref === 'function' ? ref : fieldReader(ref, jexl);
44
27
  }
45
28
  function isGlyphName(glyph) {
46
29
  return glyph in GLYPH_CODES;
@@ -62,90 +45,55 @@ function glyphReader(glyph, jexl) {
62
45
  return typeof v === 'string' && isGlyphName(v) ? GLYPH_CODES[v] : GLYPH_DISC;
63
46
  };
64
47
  }
65
- function rampStops(ramp) {
66
- if (ramp === undefined || ramp === 'viridis') {
67
- return VIRIDIS_STOPS;
68
- }
69
- return ramp.map(c => cssColorToRgba(c));
70
- }
71
48
  function lutColorAt(lut, t) {
72
49
  const entries = lut.length / 4;
73
50
  const i = Math.min(entries - 1, Math.max(0, Math.round(t * (entries - 1))));
74
51
  const o = i * 4;
75
52
  return packAbgr(lut[o], lut[o + 1], lut[o + 2], lut[o + 3]);
76
53
  }
77
- // The `[0, 1]` fraction a value sits at in the domain: the scale half of the
78
- // y-channel split (ADR-097), spelled once here for colour. The log arm floors
79
- // at the domain's own minimum so a domain below 1 still spreads.
80
- function normalizer(scale, domain) {
81
- const [min, max] = domain;
82
- if (scale === 'log') {
83
- const floorV = min > 0 ? min : 1;
84
- const logMin = Math.log2(floorV);
85
- const logRange = Math.log2(Math.max(max, floorV)) - logMin;
86
- return (v) => logRange <= 0
87
- ? 0
88
- : Math.min(1, Math.max(0, (Math.log2(Math.max(v, floorV)) - logMin) / logRange));
89
- }
90
- const range = max - min;
91
- return (v) => range <= 0 ? 0 : Math.min(1, Math.max(0, (v - min) / range));
92
- }
93
- function categoryOrder(seen, domain) {
94
- const listed = (domain ?? []).map(String);
95
- const rest = [...seen.keys()].filter(k => !listed.includes(k));
96
- const numeric = rest.every(k => k !== '' && Number.isFinite(Number(k)));
97
- rest.sort(numeric ? (a, b) => Number(a) - Number(b) : (a, b) => a.localeCompare(b));
98
- return [...listed, ...rest];
99
- }
100
54
  // The categorical arm `color` and `glyph` share: the walk records which
101
- // distinct value each admitted instance carried, and `resolve` hands every
102
- // value its range entry once the region's table is known. A listed domain
103
- // is the author's order and walks the range; without one the entry derives
104
- // from the value itself, so two regions that met different value sets still
105
- // agree on every value they share.
106
- function categoricalChannel(read, n) {
107
- const categories = new Map();
108
- const indexOf = new Int32Array(n);
55
+ // key each admitted instance carried, `''` for none, and `resolve` hands
56
+ // every key met its entry in the field's order, so two regions that met
57
+ // different key sets still agree on every key they share.
58
+ function categoricalChannel(read, categories, n) {
59
+ const keys = new Map();
60
+ const indexOf = new Uint32Array(n);
109
61
  return {
110
62
  indexOf,
111
63
  collect(f, at) {
112
- const raw = read(f);
113
- if (raw === undefined || raw === null || raw === '') {
114
- indexOf[at] = -1;
115
- return;
116
- }
117
- const label = String(raw);
118
- let index = categories.get(label);
64
+ const key = categories.key(read(f));
65
+ let index = keys.get(key);
119
66
  if (index === undefined) {
120
- index = categories.size;
121
- categories.set(label, index);
67
+ index = keys.size;
68
+ keys.set(key, index);
122
69
  }
123
70
  indexOf[at] = index;
124
71
  },
125
- resolve(domain, range) {
126
- const ofIndex = Array.from({ length: categories.size });
72
+ resolve(entryOf) {
73
+ const ofIndex = Array.from({ length: keys.size });
127
74
  const entries = [];
128
- categoryOrder(categories, domain).forEach((label, slot) => {
129
- const value = domain
130
- ? range[slot % range.length]
131
- : categoricalValueColor(label, range);
132
- const index = categories.get(label);
133
- if (index !== undefined) {
134
- ofIndex[index] = value;
135
- }
136
- entries.push({ label, value });
137
- });
75
+ for (const value of [...keys.keys()].sort(categories.compare)) {
76
+ const entry = entryOf(value);
77
+ ofIndex[keys.get(value)] = entry;
78
+ entries.push({ value, entry });
79
+ }
138
80
  return { ofIndex, entries };
139
81
  },
140
82
  };
141
83
  }
142
- function hasMissing(indexOf, count) {
84
+ /**
85
+ * #api
86
+ * The hit index over `count` instances: each a box from `x` to `x2` at its
87
+ * `y`, or at 0 for a mark with no value.
88
+ */
89
+ export function hitIndexOf(x, x2, y, count = x.length) {
90
+ const fb = new Flatbush(count, undefined, Float64Array);
143
91
  for (let i = 0; i < count; i++) {
144
- if (indexOf[i] < 0) {
145
- return true;
146
- }
92
+ const v = y ? y[i] : 0;
93
+ fb.add(x[i], v, x2[i], v);
147
94
  }
148
- return false;
95
+ fb.finish();
96
+ return fb;
149
97
  }
150
98
  /**
151
99
  * #api
@@ -162,14 +110,16 @@ export function encodeFeatures(features, encoding, lanes, ctx = {}) {
162
110
  const { jexl, report } = ctx;
163
111
  const n = features.length;
164
112
  const has = (lane) => lanes.includes(lane);
165
- const readX = fieldReader(encoding.x ?? 'start', jexl);
166
- const readX2 = fieldReader(encoding.x2 ?? 'end', jexl);
113
+ const readX = channelReader(encoding.x ?? 'start', jexl);
114
+ const readX2 = channelReader(encoding.x2 ?? 'end', jexl);
167
115
  const { y: yEncoding } = encoding;
168
116
  const readY = has('y') && yEncoding !== undefined
169
- ? fieldReader(typeof yEncoding === 'object' ? valueField(yEncoding) : yEncoding, jexl)
117
+ ? channelReader(yEncoding, jexl)
170
118
  : undefined;
171
- const readRow = has('row') && encoding.row !== undefined
172
- ? fieldReader(encoding.row, jexl)
119
+ const { row: rowEncoding } = encoding;
120
+ const rowValues = has('row') && typeof rowEncoding === 'object' ? rowEncoding : undefined;
121
+ const readRow = has('row') && rowEncoding !== undefined && typeof rowEncoding !== 'object'
122
+ ? channelReader(rowEncoding, jexl)
173
123
  : undefined;
174
124
  const x = new Uint32Array(n);
175
125
  const x2 = new Uint32Array(n);
@@ -180,9 +130,11 @@ export function encodeFeatures(features, encoding, lanes, ctx = {}) {
180
130
  let yMin = Infinity;
181
131
  let yMax = -Infinity;
182
132
  let count = 0;
133
+ let skippedPosition = 0;
183
134
  const colorEncoding = encoding.color ?? DEFAULT_MARK_COLOR;
184
135
  const declaredScale = typeof colorEncoding === 'object' ? colorEncoding : undefined;
185
- const rampEncoding = declaredScale && declaredScale.scale !== 'categorical'
136
+ const rampEncoding = declaredScale &&
137
+ (declaredScale.scale === 'linear' || declaredScale.scale === 'log')
186
138
  ? declaredScale
187
139
  : undefined;
188
140
  // Which side of the wire a ramp resolves on is the caller's lane choice: a
@@ -199,19 +151,35 @@ export function encodeFeatures(features, encoding, lanes, ctx = {}) {
199
151
  ? colorEncoding
200
152
  : scaled === undefined
201
153
  ? colorEvaluator(colorEncoding, jexl)
202
- : fieldReader(scaled.field, jexl);
154
+ : channelReader(scaled.field, jexl);
203
155
  // A scaled channel resolves after the walk, once the table is known: the
204
156
  // category per admitted instance, or a ramp's raw value, kept here.
205
- const colorCategories = scaled?.scale === 'categorical' && readColor
206
- ? categoricalChannel(readColor, n)
157
+ const colorField = scaled?.scale === 'categorical'
158
+ ? categoricalField(scaled.field, {
159
+ domain: scaled.domain?.map(String),
160
+ range: scaled.range,
161
+ })
162
+ : undefined;
163
+ const colorCategories = colorField && readColor
164
+ ? categoricalChannel(readColor, colorField, n)
207
165
  : undefined;
208
- const rampValues = scaled && scaled.scale !== 'categorical'
209
- ? (colorValue ?? new Float32Array(n))
166
+ const rampValues = scaled && rampEncoding ? (colorValue ?? new Float32Array(n)) : undefined;
167
+ const thresholdEncoding = scaled?.scale === 'threshold' ? scaled : undefined;
168
+ const cuts = thresholdEncoding
169
+ ? thresholdCuts(thresholdEncoding.domain ?? [])
170
+ : undefined;
171
+ const binColors = thresholdEncoding && cuts
172
+ ? Uint32Array.from(thresholdPalette(cuts.length + 1, thresholdEncoding.range), c => cssColorToABGR(c))
210
173
  : undefined;
211
174
  const { glyph: glyphEncoding } = encoding;
212
175
  const glyphScaled = glyph && typeof glyphEncoding === 'object' ? glyphEncoding : undefined;
213
- const glyphCategories = glyphScaled
214
- ? categoricalChannel(fieldReader(glyphScaled.field, jexl), n)
176
+ const glyphField = glyphScaled
177
+ ? categoricalField(glyphScaled.field, {
178
+ domain: glyphScaled.domain?.map(String),
179
+ })
180
+ : undefined;
181
+ const glyphCategories = glyphScaled && glyphField
182
+ ? categoricalChannel(channelReader(glyphScaled.field, jexl), glyphField, n)
215
183
  : undefined;
216
184
  const readGlyph = glyph
217
185
  ? glyphReader(typeof glyphEncoding === 'object' ? undefined : glyphEncoding, jexl)
@@ -219,10 +187,13 @@ export function encodeFeatures(features, encoding, lanes, ctx = {}) {
219
187
  for (let i = 0; i < n; i++) {
220
188
  report?.(i);
221
189
  const f = features[i];
222
- const xv = Number(readX(f));
223
- const x2v = Number(readX2(f));
224
- const yv = readY ? Number(readY(f)) : 0;
190
+ const xv = numericValue(readX(f));
191
+ const x2v = numericValue(readX2(f));
192
+ const yv = readY ? numericValue(readY(f)) : 0;
225
193
  if (!Number.isFinite(xv) || !Number.isFinite(x2v) || !Number.isFinite(yv)) {
194
+ if (!Number.isFinite(xv) || !Number.isFinite(x2v)) {
195
+ skippedPosition++;
196
+ }
226
197
  continue;
227
198
  }
228
199
  x[count] = xv;
@@ -242,6 +213,10 @@ export function encodeFeatures(features, encoding, lanes, ctx = {}) {
242
213
  const rv = Number(readRow(f));
243
214
  row[count] = rv > 0 ? rv : 0;
244
215
  }
216
+ else if (row && rowValues) {
217
+ const rv = rowValues[i];
218
+ row[count] = rv > 0 ? rv : 0;
219
+ }
245
220
  if (glyphCategories) {
246
221
  glyphCategories.collect(f, count);
247
222
  }
@@ -253,7 +228,11 @@ export function encodeFeatures(features, encoding, lanes, ctx = {}) {
253
228
  colorCategories.collect(f, count);
254
229
  }
255
230
  else if (rampValues && readColor) {
256
- rampValues[count] = Number(readColor(f));
231
+ rampValues[count] = numericValue(readColor(f));
232
+ }
233
+ else if (binColors && cuts && color && readColor) {
234
+ const bin = thresholdIndex(readColor(f), cuts);
235
+ color[count] = bin < 0 ? FALLBACK_COLOR : binColors[bin];
257
236
  }
258
237
  else if (color && readColor) {
259
238
  color[count] = readColor(f);
@@ -261,31 +240,43 @@ export function encodeFeatures(features, encoding, lanes, ctx = {}) {
261
240
  count++;
262
241
  }
263
242
  let scale;
264
- if (scaled?.scale === 'categorical' && colorCategories && color) {
265
- const palette = (scaled.palette ?? categoricalPalette).map(cssColorToABGR);
266
- const { ofIndex, entries } = colorCategories.resolve(scaled.domain, palette);
243
+ if (scaled?.scale === 'categorical' &&
244
+ colorField &&
245
+ colorCategories &&
246
+ color) {
247
+ const { ofIndex, entries } = colorCategories.resolve(key => cssColorToABGR(colorField.color(key)));
267
248
  const { indexOf } = colorCategories;
268
249
  for (let i = 0; i < count; i++) {
269
- const index = indexOf[i];
270
- color[i] = index < 0 ? FALLBACK_COLOR : ofIndex[index];
250
+ color[i] = ofIndex[indexOf[i]];
271
251
  }
272
252
  scale = {
273
253
  kind: 'categorical',
274
254
  field: scaled.field,
275
- entries: [
276
- ...entries.map(e => ({ label: e.label, color: e.value })),
277
- ...(hasMissing(indexOf, count)
278
- ? [{ label: NO_VALUE_LABEL, color: FALLBACK_COLOR }]
279
- : []),
280
- ],
255
+ domain: [...colorField.domain],
256
+ ...(scaled.range ? { range: [...scaled.range] } : {}),
257
+ ...(keysAreNumeric(entries) ? { numericKeys: true } : {}),
258
+ entries: entries.map(e => ({ value: e.value, color: e.entry })),
281
259
  };
282
260
  }
283
- else if (scaled && scaled.scale !== 'categorical' && rampValues) {
261
+ else if (thresholdEncoding && cuts && binColors) {
262
+ scale = {
263
+ kind: 'threshold',
264
+ field: thresholdEncoding.field,
265
+ domain: cuts,
266
+ entries: thresholdLabels(cuts).map((value, i) => ({
267
+ value,
268
+ color: binColors[i],
269
+ })),
270
+ };
271
+ }
272
+ else if (rampEncoding && rampValues) {
284
273
  const extent = finiteExtremes(rampValues, count);
285
- const domain = scaled.domain ?? extent;
286
- const lut = buildColorRampLut(rampStops(scaled.ramp));
274
+ const { domainMin, domainMax, domainMid } = rampEncoding;
275
+ const domain = rampDomain(domainMin, domainMax, extent);
276
+ const norm = makeScoreNormalizer(domain[0], domain[1], scaleTypeCode(rampEncoding.scale), 1);
277
+ const stops = colorRampStops(rampEncoding);
278
+ const lut = rampLut(stops, rampEncoding.scale, domain, domainMid);
287
279
  if (color) {
288
- const norm = normalizer(scaled.scale, domain);
289
280
  for (let i = 0; i < count; i++) {
290
281
  const v = rampValues[i];
291
282
  color[i] = Number.isFinite(v)
@@ -295,47 +286,37 @@ export function encodeFeatures(features, encoding, lanes, ctx = {}) {
295
286
  }
296
287
  scale = {
297
288
  kind: 'ramp',
298
- field: scaled.field,
299
- scale: scaled.scale,
289
+ field: rampEncoding.field,
290
+ scale: rampEncoding.scale,
300
291
  domain,
301
- pinned: scaled.domain !== undefined,
292
+ pinned: [domainMin !== undefined, domainMax !== undefined],
293
+ ...(domainMid === undefined ? {} : { domainMid, stops }),
302
294
  extent,
303
295
  lut,
304
296
  };
305
297
  }
306
298
  let glyphScale;
307
- if (glyphScaled && glyphCategories && glyph) {
308
- const { ofIndex, entries } = glyphCategories.resolve(glyphScaled.domain, glyphScaled.range ?? GLYPH_NAMES);
299
+ if (glyphScaled && glyphField && glyphCategories && glyph) {
300
+ const glyphOf = categoricalScale(glyphField.domain, glyphScaled.range ?? GLYPH_NAMES);
301
+ const { ofIndex, entries } = glyphCategories.resolve((key) => key === '' ? 'disc' : glyphOf(key));
309
302
  const codeOfIndex = Uint8Array.from(ofIndex, name => GLYPH_CODES[name]);
310
303
  const { indexOf } = glyphCategories;
311
304
  for (let i = 0; i < count; i++) {
312
- const index = indexOf[i];
313
- glyph[i] = index < 0 ? GLYPH_DISC : codeOfIndex[index];
305
+ glyph[i] = codeOfIndex[indexOf[i]];
314
306
  }
315
307
  glyphScale = {
316
308
  kind: 'glyph',
317
309
  field: glyphScaled.field,
318
- entries: [
319
- ...entries.map(e => ({ label: e.label, glyph: e.value })),
320
- ...(hasMissing(indexOf, count)
321
- ? [{ label: NO_VALUE_LABEL, glyph: 'disc' }]
322
- : []),
323
- ],
310
+ domain: [...glyphField.domain],
311
+ ...(glyphScaled.range ? { range: [...glyphScaled.range] } : {}),
312
+ entries: entries.map(e => ({ value: e.value, glyph: e.entry })),
324
313
  };
325
314
  }
326
- let flatbushData;
327
- if (has('index') && count > 0) {
328
- const fb = new Flatbush(count, undefined, Float64Array);
329
- for (let i = 0; i < count; i++) {
330
- const v = y ? y[i] : 0;
331
- fb.add(x[i], v, x2[i], v);
332
- }
333
- fb.finish();
334
- flatbushData = fb.data;
335
- }
315
+ const flatbushData = has('index') && count > 0 ? hitIndexOf(x, x2, y, count).data : undefined;
336
316
  const encoded = {
337
317
  count,
338
318
  skipped: n - count,
319
+ skippedPosition,
339
320
  x: x.subarray(0, count),
340
321
  x2: x2.subarray(0, count),
341
322
  featureIndex: featureIndex.subarray(0, count),
@@ -368,6 +349,52 @@ export function encodeFeatures(features, encoding, lanes, ctx = {}) {
368
349
  }
369
350
  return encoded;
370
351
  }
352
+ function rampMid(scale, domain, domainMid) {
353
+ return domainMid === undefined
354
+ ? 0.5
355
+ : makeScoreNormalizer(domain[0], domain[1], scaleTypeCode(scale), 1)(domainMid);
356
+ }
357
+ function rampLut(stops, scale, domain, domainMid) {
358
+ return buildColorRampLut(stops, rampMid(scale, domain, domainMid));
359
+ }
360
+ const MAX_BAKED_RAMPS = 16;
361
+ const bakedRamps = new Map();
362
+ /**
363
+ * #api
364
+ * A ramp table over `extent`, the union a display took across the regions it
365
+ * loaded: each open end of the domain moved to the union's, the pinned ends
366
+ * kept, and the table baked again where a `domainMid` places its middle stop
367
+ * by that domain. Each region baked its own, so keeping the first region's
368
+ * put the middle colour at a value none of them declared.
369
+ *
370
+ * One table per stop list and middle position, so a display asking again over
371
+ * an extent that has not moved gets the bytes it already uploaded: a backend
372
+ * re-uploads a ramp on identity.
373
+ */
374
+ export function rampOverExtent(table, extent) {
375
+ const { stops, pinned } = table;
376
+ const domain = rampDomain(pinned[0] ? table.domain[0] : undefined, pinned[1] ? table.domain[1] : undefined, extent);
377
+ if (!stops) {
378
+ return { ...table, extent, domain };
379
+ }
380
+ const mid = rampMid(table.scale, domain, table.domainMid);
381
+ const key = `${mid}|${stops.join(';')}`;
382
+ let lut = bakedRamps.get(key);
383
+ if (!lut) {
384
+ if (bakedRamps.size >= MAX_BAKED_RAMPS) {
385
+ bakedRamps.delete(bakedRamps.keys().next().value);
386
+ }
387
+ lut = buildColorRampLut(stops, mid);
388
+ bakedRamps.set(key, lut);
389
+ }
390
+ return { ...table, extent, domain, lut };
391
+ }
392
+ function keysAreNumeric(entries) {
393
+ const named = entries.filter(e => e.value !== '');
394
+ return named.length > 0 && named.every(e => Number.isFinite(Number(e.value)));
395
+ }
396
+ // `[Infinity, -Infinity]` where no value is finite, which a union of regions'
397
+ // extents passes over.
371
398
  function finiteExtremes(values, count) {
372
399
  let min = Infinity;
373
400
  let max = -Infinity;
@@ -382,7 +409,7 @@ function finiteExtremes(values, count) {
382
409
  }
383
410
  }
384
411
  }
385
- return min === Infinity ? [0, 1] : [min, max];
412
+ return [min, max];
386
413
  }
387
414
  /**
388
415
  * #api