@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,5 +1,4 @@
1
1
  import type { StatusCallback } from './progress.ts';
2
- import type { StopToken } from './stopToken.ts';
3
2
  import type { Region } from './types/data.ts';
4
3
  export interface AlignmentData {
5
4
  refRefName: string;
@@ -17,7 +16,7 @@ export interface DiagonalizationResult {
17
16
  regionsReversed: number;
18
17
  };
19
18
  }
20
- export declare function diagonalizeRegions(alignments: AlignmentData[], referenceRegions: Region[], currentRegions: Region[], { stopToken, statusCallback, }?: {
21
- stopToken?: StopToken;
19
+ export declare function diagonalizeRegions(alignments: AlignmentData[], referenceRegions: Region[], currentRegions: Region[], { signal, statusCallback, }?: {
20
+ signal?: AbortSignal;
22
21
  statusCallback?: StatusCallback;
23
22
  }): Promise<DiagonalizationResult>;
@@ -1,6 +1,6 @@
1
+ import { checkAbortSignal } from './aborting.js';
1
2
  import { cmpStr } from './cmpStr.js';
2
3
  import { createProgressReporter } from './progress.js';
3
- import { checkStopToken } from './stopToken.js';
4
4
  // A strand vote at least this lopsided (80% of aligned bases agreeing) decides
5
5
  // the reversal by itself. Below that the vote is unreliable: a chromosome
6
6
  // carrying many inversions splits it near 50/50, and MCScan `strand` is the
@@ -61,19 +61,14 @@ function anchorStats({ alignments, bases, strandWeightedSum }) {
61
61
  //
62
62
  // - refRefName: horizontal-axis (reference) chromosome
63
63
  // - queryRefName: vertical-axis (query) chromosome
64
- export async function diagonalizeRegions(alignments, referenceRegions, currentRegions, { stopToken, statusCallback, } = {}) {
65
- // Both passes below are long enough to notice on a whole-genome alignment —
66
- // the grouping walks every alignment, and the ordering pass sorts each query
67
- // chromosome's group. They used to share a single cancel check between them,
68
- // so the whole grouping pass ran after a cancel and the bar sat on the
69
- // fetch's last message throughout. Two reporters because the phases count
70
- // different things (alignments, then chromosomes), so one auto-incrementing
71
- // counter across both would report a meaningless fraction.
64
+ export async function diagonalizeRegions(alignments, referenceRegions, currentRegions, { signal, statusCallback, } = {}) {
65
+ // Two reporters because the phases count different things (alignments, then
66
+ // chromosomes). No breakpoint: each pass measured ~50ms over 500k alignments.
72
67
  const reportGrouping = createProgressReporter({
73
68
  label: 'Grouping alignments',
74
69
  total: alignments.length,
75
70
  statusCallback,
76
- stopToken,
71
+ signal,
77
72
  });
78
73
  // first appearance wins: a refName can appear in more than one reference
79
74
  // region, and the ordering key is where that chromosome starts on the axis
@@ -118,7 +113,7 @@ export async function diagonalizeRegions(alignments, referenceRegions, currentRe
118
113
  label: 'Ordering chromosomes',
119
114
  total: queryGroups.size,
120
115
  statusCallback,
121
- stopToken,
116
+ signal,
122
117
  });
123
118
  for (const [verticalChrom, group] of queryGroups) {
124
119
  reportOrdering();
@@ -142,7 +137,7 @@ export async function diagonalizeRegions(alignments, referenceRegions, currentRe
142
137
  });
143
138
  }
144
139
  }
145
- checkStopToken(stopToken);
140
+ checkAbortSignal(signal);
146
141
  queryOrdering.sort((a, b) => a.bestRefIndex - b.bestRefIndex ||
147
142
  a.bestRefPos - b.bestRefPos ||
148
143
  cmpStr(a.refName, b.refName));
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Fill in what a search index written short leaves out: `type` from a `uri`
3
+ * naming a `.ix`, which is what `jbrowse text-index` writes, and
4
+ * `assemblyNames` from the caller — the track's own for a per-track index, or a
5
+ * config's only assembly. A key already written is kept.
6
+ */
7
+ export declare function expandLooseSearchIndex<T>(snap: T, assemblyNames?: unknown): T;
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Fill in what a search index written short leaves out: `type` from a `uri`
3
+ * naming a `.ix`, which is what `jbrowse text-index` writes, and
4
+ * `assemblyNames` from the caller — the track's own for a per-track index, or a
5
+ * config's only assembly. A key already written is kept.
6
+ */
7
+ export function expandLooseSearchIndex(snap, assemblyNames) {
8
+ if (typeof snap !== 'object' || snap === null || Array.isArray(snap)) {
9
+ return snap;
10
+ }
11
+ const index = snap;
12
+ const guessType = index.type === undefined &&
13
+ typeof index.uri === 'string' &&
14
+ /\.ix$/i.test(index.uri.split(/[?#]/)[0]);
15
+ const fillNames = index.assemblyNames === undefined &&
16
+ Array.isArray(assemblyNames) &&
17
+ assemblyNames.length > 0;
18
+ return guessType || fillNames
19
+ ? {
20
+ ...index,
21
+ ...(guessType ? { type: 'TrixTextSearchAdapter' } : {}),
22
+ ...(fillNames ? { assemblyNames } : {}),
23
+ }
24
+ : snap;
25
+ }
@@ -1,11 +1,38 @@
1
1
  import type { JexlInstance } from './jexlStrings.ts';
2
- import type { AggregateOp, TransformStep } from './markEncodingTypes.ts';
2
+ import type { AggregateOp, FacetSection, FieldRef, TransformStep } from './markEncodingTypes.ts';
3
3
  import type { Feature } from './simpleFeature.ts';
4
+ export declare const DEFAULT_BIN_FIELD = "start";
4
5
  export declare const DEFAULT_BIN_AS: [string, string];
6
+ export declare const DEFAULT_FLATTEN_FIELD = "subfeatures";
5
7
  export declare const DEFAULT_COVERAGE_AS = "coverage";
6
- export declare const DEFAULT_STACK_AS = "row";
7
- export declare const DEFAULT_STACK_FIELDS: [string, string];
8
+ export declare const DEFAULT_PILEUP_AS = "row";
9
+ export declare const DEFAULT_PILEUP_FIELDS: [string, string];
8
10
  export declare function aggregateFieldName({ op, field, as }: AggregateOp): string;
11
+ /**
12
+ * #api
13
+ * One layer of a faceted request: its features in section order, and the
14
+ * stacked row of each, index for index.
15
+ */
16
+ export interface FacetedLayer {
17
+ features: readonly Feature[];
18
+ rows: readonly number[];
19
+ }
20
+ /**
21
+ * #api
22
+ * A faceted request's layers: the features split on `field`'s key, each
23
+ * layer's own steps run over each section alone, and the sections stacked —
24
+ * a section's rows start where the one above it ends, and it is as tall as
25
+ * the tallest layer packed it. Every layer's features come back in section
26
+ * order beside their stacked rows, so a faceted display is the unfaceted one
27
+ * drawn once per section, and a feature is handed on as its steps left it.
28
+ */
29
+ export declare function facetLayers(features: readonly Feature[], field: FieldRef, layers: readonly {
30
+ transform?: readonly TransformStep[];
31
+ row?: FieldRef;
32
+ }[], jexl?: JexlInstance): {
33
+ layers: FacetedLayer[];
34
+ sections: FacetSection[];
35
+ };
9
36
  /**
10
37
  * #api
11
38
  * Run the transform steps over a feature list, in order, in the worker. The
@@ -1,9 +1,14 @@
1
- import { stringToJexlExpression } from './jexlStrings.js';
1
+ import { categoricalField } from './categoricalField.js';
2
+ import { fieldReader, isPlainFieldRef } from './fieldReader.js';
3
+ import { isJexl, stringToJexlExpression } from './jexlStrings.js';
4
+ import { numericValue } from './numericValue.js';
2
5
  import SimpleFeature, { buildJexlContext } from './simpleFeature.js';
6
+ export const DEFAULT_BIN_FIELD = 'start';
3
7
  export const DEFAULT_BIN_AS = ['start', 'end'];
8
+ export const DEFAULT_FLATTEN_FIELD = 'subfeatures';
4
9
  export const DEFAULT_COVERAGE_AS = 'coverage';
5
- export const DEFAULT_STACK_AS = 'row';
6
- export const DEFAULT_STACK_FIELDS = ['start', 'end'];
10
+ export const DEFAULT_PILEUP_AS = 'row';
11
+ export const DEFAULT_PILEUP_FIELDS = ['start', 'end'];
7
12
  /**
8
13
  * A feature with fields written over another's: what `formula` and `bin`
9
14
  * produce, without copying the base feature's data per step.
@@ -58,6 +63,26 @@ function expression(expr, jexl) {
58
63
  }
59
64
  return stringToJexlExpression(expr, jexl);
60
65
  }
66
+ // A step reads a name or a dotted path. A plain name keeps the direct
67
+ // `f.get` its loop has always made; this is the reader a path takes instead,
68
+ // chosen once per step. A computed field is a `formula` step's to make.
69
+ function pathReader(ref, step) {
70
+ if (isJexl(ref)) {
71
+ throw new Error(`${step} field is a name or a dotted path, and a formula step in front computes one (${ref})`);
72
+ }
73
+ return fieldReader(ref, undefined);
74
+ }
75
+ // A list holding one value is that value, as a VCF's ALT and INFO fields
76
+ // arrive, and a longer one is its text: a Map keys a list by identity, which
77
+ // made every feature a group of its own. A missing value is one group, whether
78
+ // the field is absent or holds a VCF's `.`.
79
+ function groupKey(value) {
80
+ return Array.isArray(value)
81
+ ? value.length === 1
82
+ ? (value[0] ?? undefined)
83
+ : value.join(',')
84
+ : (value ?? undefined);
85
+ }
61
86
  function filter(features, expr, jexl) {
62
87
  const compiled = expression(expr, jexl);
63
88
  return features.filter(f => compiled.eval(buildJexlContext({ feature: f })));
@@ -97,10 +122,13 @@ class FlattenedFeature {
97
122
  }
98
123
  }
99
124
  function flatten(features, step) {
100
- const { field = 'subfeatures', index, keepEmpty } = step;
125
+ const { field = DEFAULT_FLATTEN_FIELD, index, keepEmpty } = step;
101
126
  const out = [];
127
+ const read = isPlainFieldRef(field)
128
+ ? undefined
129
+ : pathReader(field, 'a flatten');
102
130
  for (const f of features) {
103
- const items = f.get(field);
131
+ const items = read ? read(f) : f.get(field);
104
132
  if (!Array.isArray(items) || items.length === 0) {
105
133
  if (keepEmpty) {
106
134
  out.push(f);
@@ -121,13 +149,21 @@ function flatten(features, step) {
121
149
  return out;
122
150
  }
123
151
  function bin(features, step) {
124
- const { field = 'start', step: size } = step;
152
+ const { field = DEFAULT_BIN_FIELD, step: size } = step;
125
153
  if (!(size > 0)) {
126
154
  throw new Error(`a bin step needs a positive size (${size})`);
127
155
  }
128
156
  const [asStart, asEnd] = step.as ?? DEFAULT_BIN_AS;
157
+ if (isPlainFieldRef(field)) {
158
+ return features.map(f => {
159
+ const v = numericValue(f.get(field));
160
+ const start = Math.floor(v / size) * size;
161
+ return new DerivedFeature(f, { [asStart]: start, [asEnd]: start + size });
162
+ });
163
+ }
164
+ const read = pathReader(field, 'a bin');
129
165
  return features.map(f => {
130
- const v = Number(f.get(field));
166
+ const v = numericValue(read(f));
131
167
  const start = Math.floor(v / size) * size;
132
168
  return new DerivedFeature(f, { [asStart]: start, [asEnd]: start + size });
133
169
  });
@@ -145,7 +181,8 @@ function groupMembers(features, groupby) {
145
181
  for (const f of features) {
146
182
  let node = root;
147
183
  for (let i = 0; i < last; i++) {
148
- const v = f.get(groupby[i]);
184
+ const raw = f.get(groupby[i]);
185
+ const v = typeof raw === 'object' ? groupKey(raw) : raw;
149
186
  let next = node.get(v);
150
187
  if (!next) {
151
188
  next = new Map();
@@ -153,7 +190,8 @@ function groupMembers(features, groupby) {
153
190
  }
154
191
  node = next;
155
192
  }
156
- const v = f.get(groupby[last]);
193
+ const raw = f.get(groupby[last]);
194
+ const v = typeof raw === 'object' ? groupKey(raw) : raw;
157
195
  let members = node.get(v);
158
196
  if (!members) {
159
197
  members = [];
@@ -164,11 +202,49 @@ function groupMembers(features, groupby) {
164
202
  }
165
203
  return groups;
166
204
  }
205
+ // `groupMembers` over readers, for a groupby naming a dotted path.
206
+ function groupMembersBy(features, reads) {
207
+ const last = reads.length - 1;
208
+ const root = new Map();
209
+ const groups = [];
210
+ for (const f of features) {
211
+ let node = root;
212
+ for (let i = 0; i < last; i++) {
213
+ const v = groupKey(reads[i](f));
214
+ let next = node.get(v);
215
+ if (!next) {
216
+ next = new Map();
217
+ node.set(v, next);
218
+ }
219
+ node = next;
220
+ }
221
+ const v = groupKey(reads[last](f));
222
+ let members = node.get(v);
223
+ if (!members) {
224
+ members = [];
225
+ node.set(v, members);
226
+ groups.push(members);
227
+ }
228
+ members.push(f);
229
+ }
230
+ return groups;
231
+ }
232
+ function keyedGroupby(groupby) {
233
+ return groupby.some(field => !isPlainFieldRef(field));
234
+ }
167
235
  function aggregate(features, step) {
168
236
  const { groupby = [], ops } = step;
169
237
  const out = [];
170
238
  let serial = 0;
171
- for (const members of groupMembers(features, groupby)) {
239
+ const reads = keyedGroupby(groupby)
240
+ ? groupby.map(field => pathReader(field, 'an aggregate'))
241
+ : undefined;
242
+ const opReads = ops.map(({ op, field }) => op === 'count' || field === undefined || isPlainFieldRef(field)
243
+ ? undefined
244
+ : pathReader(field, 'an aggregate'));
245
+ for (const members of reads
246
+ ? groupMembersBy(features, reads)
247
+ : groupMembers(features, groupby)) {
172
248
  const first = members[0];
173
249
  const refName = first.get('refName');
174
250
  let start = Infinity;
@@ -178,11 +254,14 @@ function aggregate(features, step) {
178
254
  end = Math.max(end, m.get('end'));
179
255
  }
180
256
  const data = {};
181
- for (const field of groupby) {
182
- data[field] = first.get(field);
257
+ for (const [i, field] of groupby.entries()) {
258
+ data[field] = groupKey(reads ? reads[i](first) : first.get(field));
183
259
  }
184
- for (const agg of ops) {
185
- data[aggregateFieldName(agg)] = aggregateValue(members, agg);
260
+ for (const [k, agg] of ops.entries()) {
261
+ const read = opReads[k];
262
+ data[aggregateFieldName(agg)] = read
263
+ ? aggregateValueBy(members, agg.op, read)
264
+ : aggregateValue(members, agg);
186
265
  }
187
266
  out.push(new MadeFeature({ ...data, refName, start, end }, `#${serial++}`));
188
267
  }
@@ -200,7 +279,7 @@ function aggregateValue(members, { op, field }) {
200
279
  let min = Infinity;
201
280
  let max = -Infinity;
202
281
  for (const m of members) {
203
- const v = Number(m.get(field));
282
+ const v = numericValue(m.get(field));
204
283
  if (!Number.isFinite(v)) {
205
284
  continue;
206
285
  }
@@ -224,31 +303,92 @@ function aggregateValue(members, { op, field }) {
224
303
  }
225
304
  }
226
305
  }
306
+ // `aggregateValue` over a reader, for an op naming a dotted path. A function
307
+ // of its own, and the fold written out again, so the loop above stays the size
308
+ // it was: both variants in one body measured 1.04-1.20x on a plain field.
309
+ function aggregateValueBy(members, op, read) {
310
+ let sum = 0;
311
+ let n = 0;
312
+ let min = Infinity;
313
+ let max = -Infinity;
314
+ for (const m of members) {
315
+ const v = numericValue(read(m));
316
+ if (!Number.isFinite(v)) {
317
+ continue;
318
+ }
319
+ sum += v;
320
+ n++;
321
+ min = Math.min(min, v);
322
+ max = Math.max(max, v);
323
+ }
324
+ return op === 'sum'
325
+ ? sum
326
+ : n === 0
327
+ ? undefined
328
+ : op === 'mean'
329
+ ? sum / n
330
+ : op === 'min'
331
+ ? min
332
+ : max;
333
+ }
227
334
  /**
228
- * The lowest row each feature fits on, greedy first fit in start order: the
229
- * layout a pileup is, as a step in front of the encoder rather than a packer
230
- * behind it. `rowEnds[r]` is where row `r` is free again, so the scan is over
231
- * rows rather than over features.
335
+ * The lowest row each feature fits on, greedy first fit in start order, as a
336
+ * step in front of the encoder rather than a packer behind it. `rowEnds[r]` is
337
+ * where row `r` is free again, so the scan is over rows rather than over
338
+ * features.
232
339
  */
233
- function stack(features, step) {
234
- const as = step.as ?? DEFAULT_STACK_AS;
235
- const [startField, endField] = step.fields ?? DEFAULT_STACK_FIELDS;
340
+ function pileup(features, step) {
341
+ const as = step.as ?? DEFAULT_PILEUP_AS;
342
+ const [startField, endField] = step.fields ?? DEFAULT_PILEUP_FIELDS;
236
343
  const padding = step.padding ?? 0;
237
- const out = [];
238
- for (const members of groupMembers(features, step.groupby ?? [])) {
239
- members.sort((a, b) => Number(a.get(startField)) - Number(b.get(startField)));
240
- const rowEnds = [];
241
- for (const f of members) {
242
- const start = Number(f.get(startField));
243
- const end = Number(f.get(endField));
244
- let row = 0;
245
- while (row < rowEnds.length && rowEnds[row] > start) {
246
- row++;
344
+ const n = features.length;
345
+ const starts = new Float64Array(n);
346
+ const ends = new Float64Array(n);
347
+ let inOrder = true;
348
+ if (isPlainFieldRef(startField) && isPlainFieldRef(endField)) {
349
+ for (let i = 0; i < n; i++) {
350
+ const f = features[i];
351
+ starts[i] = numericValue(f.get(startField));
352
+ ends[i] = numericValue(f.get(endField));
353
+ inOrder &&= i === 0 || starts[i] >= starts[i - 1];
354
+ }
355
+ }
356
+ else {
357
+ const readStart = pathReader(startField, 'a pileup');
358
+ const readEnd = pathReader(endField, 'a pileup');
359
+ for (let i = 0; i < n; i++) {
360
+ const f = features[i];
361
+ starts[i] = numericValue(readStart(f));
362
+ ends[i] = numericValue(readEnd(f));
363
+ inOrder &&= i === 0 || starts[i] >= starts[i - 1];
364
+ }
365
+ }
366
+ // Any unreadable start leaves the list out of order. Read as Infinity, it
367
+ // sorts last and packs where it claims no row a readable one could want,
368
+ // where NaN left the sort without an order and a row's end unreadable.
369
+ if (!inOrder) {
370
+ for (let i = 0; i < n; i++) {
371
+ if (Number.isNaN(starts[i])) {
372
+ starts[i] = Infinity;
247
373
  }
248
- rowEnds[row] = (end > start ? end : start) + padding;
249
- out.push(new DerivedFeature(f, { [as]: row }));
250
374
  }
251
375
  }
376
+ const order = inOrder
377
+ ? undefined
378
+ : Uint32Array.from(starts, (_, i) => i).sort((a, b) => starts[a] - starts[b] || a - b);
379
+ const rowEnds = [];
380
+ const out = [];
381
+ for (let k = 0; k < n; k++) {
382
+ const i = order ? order[k] : k;
383
+ const start = starts[i];
384
+ const end = ends[i];
385
+ let row = 0;
386
+ while (row < rowEnds.length && rowEnds[row] > start) {
387
+ row++;
388
+ }
389
+ rowEnds[row] = (end > start ? end : start) + padding;
390
+ out.push(new DerivedFeature(features[i], { [as]: row }));
391
+ }
252
392
  return out;
253
393
  }
254
394
  /**
@@ -298,6 +438,63 @@ function coverage(features, step) {
298
438
  }
299
439
  return out;
300
440
  }
441
+ function rowOf(value) {
442
+ const row = Number(value);
443
+ return row > 0 ? Math.floor(row) : 0;
444
+ }
445
+ /**
446
+ * #api
447
+ * A faceted request's layers: the features split on `field`'s key, each
448
+ * layer's own steps run over each section alone, and the sections stacked —
449
+ * a section's rows start where the one above it ends, and it is as tall as
450
+ * the tallest layer packed it. Every layer's features come back in section
451
+ * order beside their stacked rows, so a faceted display is the unfaceted one
452
+ * drawn once per section, and a feature is handed on as its steps left it.
453
+ */
454
+ export function facetLayers(features, field, layers, jexl) {
455
+ const categories = categoricalField(field);
456
+ const read = fieldReader(field, jexl);
457
+ const byKey = new Map();
458
+ for (const f of features) {
459
+ const key = categories.key(read(f));
460
+ const members = byKey.get(key);
461
+ if (members) {
462
+ members.push(f);
463
+ }
464
+ else {
465
+ byKey.set(key, [f]);
466
+ }
467
+ }
468
+ const readRows = layers.map(l => fieldReader(l.row ?? DEFAULT_PILEUP_AS, jexl));
469
+ const out = layers.map(() => ({
470
+ features: [],
471
+ rows: [],
472
+ }));
473
+ const sections = [];
474
+ let next = 0;
475
+ for (const key of [...byKey.keys()].sort(categories.compare)) {
476
+ const members = byKey.get(key);
477
+ let rowCount = 1;
478
+ for (const [l, { transform }] of layers.entries()) {
479
+ const placed = transform?.length
480
+ ? runTransforms(members, transform, jexl)
481
+ : members;
482
+ const readRow = readRows[l];
483
+ const layer = out[l];
484
+ for (const f of placed) {
485
+ const row = rowOf(readRow(f));
486
+ if (row + 1 > rowCount) {
487
+ rowCount = row + 1;
488
+ }
489
+ layer.features.push(f);
490
+ layer.rows.push(next + row);
491
+ }
492
+ }
493
+ sections.push({ key, firstRow: next, rowCount });
494
+ next += rowCount;
495
+ }
496
+ return { layers: out, sections };
497
+ }
301
498
  /**
302
499
  * #api
303
500
  * Run the transform steps over a feature list, in order, in the worker. The
@@ -332,8 +529,8 @@ export function runTransforms(features, steps, jexl) {
332
529
  current = coverage(current, step);
333
530
  break;
334
531
  }
335
- case 'stack': {
336
- current = stack(current, step);
532
+ case 'pileup': {
533
+ current = pileup(current, step);
337
534
  break;
338
535
  }
339
536
  }
@@ -1,6 +1,5 @@
1
1
  import { redactSource } from './getLocationUri.js';
2
2
  import { downloadStatus, phaseOf, updateStatus } from './progress.js';
3
- import { withStopTokenSignal } from './stopToken.js';
4
3
  export function isGzip(buf) {
5
4
  return buf[0] === 31 && buf[1] === 139 && buf[2] === 8;
6
5
  }
@@ -36,10 +35,10 @@ label = 'Downloading file') {
36
35
  const phase = loc.source === undefined
37
36
  ? label
38
37
  : { message: phaseOf(label), source: redactSource(loc.source) };
39
- const { statusCallback, stopToken } = opts;
40
- // the stop token becomes the read's signal, so a cancelled whole-file load
41
- // drops at the socket rather than downloading a multi-GB body to completion
42
- const buf = await withStopTokenSignal(stopToken, signal => downloadStatus(phase, statusCallback, onProgress => loc.readFile({ ...opts, onProgress, signal })));
38
+ const { statusCallback, signal } = opts;
39
+ // the signal reaches the read, so a cancelled whole-file load drops at the
40
+ // socket rather than downloading a multi-GB body to completion
41
+ const buf = await downloadStatus(phase, statusCallback, onProgress => loc.readFile({ ...opts, onProgress, signal }));
43
42
  // the inflater is imported dynamically because this module is reachable from
44
43
  // the core/util barrel, so a static import put bgzf-filehandle + pako
45
44
  // (~180KB) on the startup path of every page load; only an actually-gzipped
@@ -51,7 +50,7 @@ label = 'Downloading file') {
51
50
  },
52
51
  // a cancel landing here is otherwise discovered only by whatever parses
53
52
  // the result, after a whole-file inflate has run to completion
54
- stopToken)
53
+ signal)
55
54
  : buf;
56
55
  }
57
56
  export async function fetchAndMaybeUnzipText(loc, opts, label) {
@@ -1,9 +1,8 @@
1
1
  import type { RpcCallArgs, RpcCallReturn } from '../rpc/RpcRegistry.ts';
2
2
  import type { StatusCallback } from './progress.ts';
3
- import type { StopToken } from './stopToken.ts';
4
3
  import type { IStateTreeNode } from '@jbrowse/mobx-state-tree';
5
4
  export interface FetchContext {
6
- stopToken: StopToken;
5
+ signal: AbortSignal;
7
6
  isStale: () => boolean;
8
7
  /**
9
8
  * The RPC `statusCallback` for the work this context describes: guarded to
@@ -24,18 +23,18 @@ export interface FetchContext {
24
23
  /**
25
24
  * The one way a fetch calls an RPC: the registry-typed
26
25
  * `rpcManager.call(rpcSessionId, method, args)` with this context's
27
- * `stopToken` and `statusCallback` injected. Both used to be hand-threaded
26
+ * `signal` and `statusCallback` injected. Both used to be hand-threaded
28
27
  * at every fetch site, and forgetting either was silent — no cancellation
29
28
  * for that display, or no progress — which is exactly the failure class the
30
29
  * envelope makes inexpressible: a fetch cannot issue an RPC the cancel and
31
30
  * the status bar don't know about.
32
31
  *
33
32
  * Declared with a `this` parameter so it reads the *holding* context's
34
- * token and callback — the fan-out copies rebind it to their own status
33
+ * signal and callback — the fan-out copies rebind it to their own status
35
34
  * slot by construction — and so destructuring it off the context is a type
36
35
  * error rather than a stale binding.
37
36
  */
38
- callRpc: <M extends string>(this: FetchContext, method: M, args: Omit<RpcCallArgs<M>, 'stopToken' | 'statusCallback'>) => Promise<RpcCallReturn<M>>;
37
+ callRpc: <M extends string>(this: FetchContext, method: M, args: Omit<RpcCallArgs<M>, 'signal' | 'statusCallback'>) => Promise<RpcCallReturn<M>>;
39
38
  }
40
39
  /**
41
40
  * Build a {@link FetchContext} over a live fetch's primitives. One
@@ -52,7 +51,7 @@ export interface FetchContext {
52
51
  * track, which is what the breakpoint split view's overlay fetch does.
53
52
  */
54
53
  export declare function makeFetchContext(self: IStateTreeNode, base: {
55
- stopToken: StopToken;
54
+ signal: AbortSignal;
56
55
  isStale: () => boolean;
57
56
  statusCallback: StatusCallback;
58
57
  }): FetchContext;
@@ -21,7 +21,7 @@ export function makeFetchContext(self, base) {
21
21
  callRpc(method, args) {
22
22
  return getRpcHost(self).rpcManager.call(getRpcSessionId(self), method, {
23
23
  ...args,
24
- stopToken: this.stopToken,
24
+ signal: this.signal,
25
25
  statusCallback: this.statusCallback,
26
26
  });
27
27
  },
@@ -12,4 +12,6 @@ export declare function hubUrl(hub: string): string;
12
12
  * the name straight to `createLinearGenomeView({ assembly: 'hg38' })` for the
13
13
  * common case; call this directly only to cherry-pick tracks from the catalog.
14
14
  */
15
- export declare function fetchHub(hub: string): Promise<HubConfig>;
15
+ export declare function fetchHub(hub: string, { signal }?: {
16
+ signal?: AbortSignal;
17
+ }): Promise<HubConfig>;
@@ -15,9 +15,9 @@ export function hubUrl(hub) {
15
15
  * the name straight to `createLinearGenomeView({ assembly: 'hg38' })` for the
16
16
  * common case; call this directly only to cherry-pick tracks from the catalog.
17
17
  */
18
- export async function fetchHub(hub) {
18
+ export async function fetchHub(hub, { signal } = {}) {
19
19
  const url = hubUrl(hub);
20
- const response = await fetch(url);
20
+ const response = await fetch(url, { signal });
21
21
  if (response.ok) {
22
22
  const config = (await response.json());
23
23
  // hosted configs reference their data relative to the config's own location
@@ -1,12 +1,11 @@
1
1
  import type { StatusCallback } from './progress.ts';
2
- import type { StopToken } from './stopToken.ts';
3
2
  import type { AbstractSessionModel } from './types/index.ts';
4
- export declare function fetchSeq({ start, end, refName, assemblyName, session, stopToken, statusCallback, }: {
3
+ export declare function fetchSeq({ start, end, refName, assemblyName, session, signal, statusCallback, }: {
5
4
  start: number;
6
5
  end: number;
7
6
  refName: string;
8
7
  assemblyName: string;
9
8
  session: AbstractSessionModel;
10
- stopToken?: StopToken;
9
+ signal?: AbortSignal;
11
10
  statusCallback?: StatusCallback;
12
11
  }): Promise<string>;
@@ -1,5 +1,5 @@
1
1
  import { getSequenceAdapterConfig } from '../assemblyManager/getSequenceAdapterConfig.js';
2
- export async function fetchSeq({ start, end, refName, assemblyName, session, stopToken, statusCallback, }) {
2
+ export async function fetchSeq({ start, end, refName, assemblyName, session, signal, statusCallback, }) {
3
3
  const { rpcManager, assemblyManager } = session;
4
4
  const assembly = await assemblyManager.waitForAssembly(assemblyName);
5
5
  if (!assembly) {
@@ -28,7 +28,7 @@ export async function fetchSeq({ start, end, refName, assemblyName, session, sto
28
28
  refName: seqAdapterRefName,
29
29
  assemblyName,
30
30
  },
31
- stopToken,
31
+ signal,
32
32
  statusCallback,
33
33
  });
34
34
  return seq ?? '';
@@ -0,0 +1,17 @@
1
+ import type { JexlInstance } from './jexlStrings.ts';
2
+ import type { Feature } from './simpleFeature.ts';
3
+ /**
4
+ * #api
5
+ * What a channel reads off a feature: a field by name, a dotted path into a
6
+ * structured field where no field carries the whole name (`INFO.SVTYPE` on a
7
+ * VCF record), or a `jexl:` expression over `feature`. A jexl expression that
8
+ * does not compile throws here, once, rather than on every feature.
9
+ */
10
+ export declare function fieldReader(ref: string, jexl: JexlInstance | undefined): (feature: Feature) => unknown;
11
+ /**
12
+ * #api
13
+ * Whether a field ref is a bare name: what `feature.get` answers on its own,
14
+ * with no path to walk and no expression to evaluate. A loop over a plain name
15
+ * keeps the direct call, and only a config that writes a path pays for one.
16
+ */
17
+ export declare function isPlainFieldRef(ref: string): ref is never;