@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,43 +1,47 @@
1
1
  import { getConfigurationSchemaMetadata } from '../../configuration/schemaRegistry.js';
2
- function schemaSlotNames(schema) {
3
- const meta = getConfigurationSchemaMetadata(schema);
4
- return new Set(meta ? Object.keys(meta.definition) : []);
2
+ import { slotValueRefusal } from '../../configuration/slotFacade.js';
3
+ function declares(schema, key) {
4
+ return !!getConfigurationSchemaMetadata(schema)?.definition[key];
5
5
  }
6
6
  function isPlainObject(v) {
7
7
  return typeof v === 'object' && v !== null && !Array.isArray(v);
8
8
  }
9
- /** display type name → its config slot names, for one track type. */
10
- function trackDisplaySlots(trackType) {
11
- const displaySlots = new Map();
12
- for (const d of trackType.displayTypes) {
13
- displaySlots.set(d.name, schemaSlotNames(d.configSchema));
14
- }
15
- return displaySlots;
16
- }
17
9
  /**
18
- * Pure: route each shorthand `displayDefaults: {...}` setting to the display
19
- * types that define it. A setting goes to every display type whose config schema
20
- * has that slot, so slot names disambiguate across displays on their own (e.g.
21
- * `color` → LinearVariantDisplay, `strokeColor` → ChordVariantDisplay). Keys no
22
- * display defines are returned as `unknownKeys` for the caller to surface.
10
+ * Route each shorthand `displayDefaults: {...}` setting to the display types
11
+ * whose slot of that name takes its value, so slot names disambiguate across
12
+ * displays (`color` → LinearVariantDisplay, `strokeColor` →
13
+ * ChordVariantDisplay) and so do the values: `displayMode: 'compact'` on a
14
+ * FeatureTrack reaches the feature display and not the arc display, whose
15
+ * `displayMode` is `arcs | semicircles`. A key no display declares is an `unknownKeys`
16
+ * entry, and one every declaring display refuses a `refused` entry carrying
17
+ * each display's reason.
23
18
  */
24
- export function collectDisplayOverrides(displaySettings, displaySlots) {
19
+ export function collectDisplayOverrides(displaySettings, displaySchemas) {
25
20
  const overrides = new Map();
26
21
  const unknownKeys = [];
22
+ const refused = [];
27
23
  for (const [key, value] of Object.entries(displaySettings)) {
28
- const targets = [...displaySlots]
29
- .filter(([, slots]) => slots.has(key))
30
- .map(([name]) => name);
31
- if (targets.length) {
32
- for (const name of targets) {
33
- overrides.set(name, { ...overrides.get(name), [key]: value });
34
- }
35
- }
36
- else {
24
+ const verdicts = [...displaySchemas]
25
+ .filter(([, schema]) => declares(schema, key))
26
+ .map(([name, schema]) => ({
27
+ name,
28
+ refusal: slotValueRefusal(schema, key, value),
29
+ }));
30
+ const targets = verdicts.filter(v => v.refusal === undefined);
31
+ if (verdicts.length === 0) {
37
32
  unknownKeys.push(key);
38
33
  }
34
+ else if (targets.length === 0) {
35
+ refused.push({
36
+ key,
37
+ reasons: verdicts.map(v => `${v.name}: ${v.refusal}`),
38
+ });
39
+ }
40
+ for (const { name } of targets) {
41
+ overrides.set(name, { ...overrides.get(name), [key]: value });
42
+ }
39
43
  }
40
- return { overrides, unknownKeys };
44
+ return { overrides, unknownKeys, refused };
41
45
  }
42
46
  /**
43
47
  * Pure: fold per-display override props into a `displays` array, creating an
@@ -61,7 +65,7 @@ export function mergeOverridesIntoDisplays(displays, overrides, trackId) {
61
65
  * Expands the shorthand `displayDefaults` **object** into the explicit `displays`
62
66
  * **array**, so users can set display settings without naming the display type
63
67
  * or nesting in `displays:[{type,...}]`. `displayDefaults:{color:'green'}` routes
64
- * each setting to the display type(s) that define that slot, folding them into
68
+ * each setting to the display type(s) whose slot takes it, folding them into
65
69
  * whatever `displays` array the track already has (explicit entries win).
66
70
  *
67
71
  * `displayDefaults` is kept separate from `displays` (rather than overloading
@@ -101,10 +105,15 @@ export function expandTrackConfigShorthand(input, pluginManager) {
101
105
  if (!trackType.displayTypes.length) {
102
106
  return snap;
103
107
  }
104
- const { overrides, unknownKeys } = collectDisplayOverrides(shorthand, trackDisplaySlots(trackType));
108
+ const { overrides, unknownKeys, refused } = collectDisplayOverrides(shorthand, new Map(trackType.displayTypes.map(d => [d.name, d.configSchema])));
105
109
  for (const key of unknownKeys) {
106
110
  console.warn(`Track "${trackId}": display setting "${key}" is not a slot on any display of a ${type}`);
107
111
  }
112
+ if (refused.length > 0) {
113
+ throw new Error(refused
114
+ .map(({ key, reasons }) => `Track "${trackId}": no display of a ${type} takes displayDefaults.${key} (${reasons.join('; ')})`)
115
+ .join('\n'));
116
+ }
108
117
  const displays = Array.isArray(rest.displays)
109
118
  ? rest.displays
110
119
  : [];
@@ -2,7 +2,6 @@ export { default as baseConnectionConfig } from './baseConnectionConfig.ts';
2
2
  export { default as BaseConnectionModelFactory } from './BaseConnectionModelFactory.ts';
3
3
  export { default as BaseViewModel } from './BaseViewModel.ts';
4
4
  export type { IBaseViewModel } from './BaseViewModel.ts';
5
- export { default as HighlightsMixin } from './HighlightsMixin.ts';
6
5
  export { BaseDisplay } from './BaseDisplayModel.tsx';
7
6
  export type { BaseDisplayModel, BaseDisplayStateModel, DisplayModel, } from './BaseDisplayModel.tsx';
8
7
  export { InternetAccount } from './InternetAccountModel.ts';
@@ -10,7 +9,7 @@ export type { BaseInternetAccountModel, BaseInternetAccountStateModel, } from '.
10
9
  export { BaseInternetAccountConfig } from './baseInternetAccountConfig.ts';
11
10
  export { createBaseTrackModel } from './BaseTrackModel.ts';
12
11
  export type { BaseTrackModel, BaseTrackStateModel } from './BaseTrackModel.ts';
13
- export { createBaseTrackConfig, preprocessTrackConfigSnapshot, trackConfigActions, } from './baseTrackConfig.ts';
12
+ export { createBaseTrackConfig, preprocessTrackConfigSnapshot, } from './baseTrackConfig.ts';
14
13
  export type { BaseTrackConfig } from './baseTrackConfig.ts';
15
14
  export { addDisplayConfigMigration } from './migrateTrackConfig.ts';
16
15
  export type { TrackConfigSnapshot } from './migrateTrackConfig.ts';
@@ -1,10 +1,9 @@
1
1
  export { default as baseConnectionConfig } from './baseConnectionConfig.js';
2
2
  export { default as BaseConnectionModelFactory } from './BaseConnectionModelFactory.js';
3
3
  export { default as BaseViewModel } from './BaseViewModel.js';
4
- export { default as HighlightsMixin } from './HighlightsMixin.js';
5
4
  export { BaseDisplay } from './BaseDisplayModel.js';
6
5
  export { InternetAccount } from './InternetAccountModel.js';
7
6
  export { BaseInternetAccountConfig } from './baseInternetAccountConfig.js';
8
7
  export { createBaseTrackModel } from './BaseTrackModel.js';
9
- export { createBaseTrackConfig, preprocessTrackConfigSnapshot, trackConfigActions, } from './baseTrackConfig.js';
8
+ export { createBaseTrackConfig, preprocessTrackConfigSnapshot, } from './baseTrackConfig.js';
10
9
  export { addDisplayConfigMigration } from './migrateTrackConfig.js';
@@ -1,13 +1,13 @@
1
- import type { AbstractSessionModel, Feature, StatusCallback, StopToken } from '../../../util/index.ts';
1
+ import type { AbstractSessionModel, Feature, StatusCallback } from '../../../util/index.ts';
2
2
  export declare function formatFeatWithSubfeatures({ feature, minPos, geneName, }: {
3
3
  feature: Feature;
4
4
  minPos: number;
5
5
  geneName?: string;
6
6
  }): string;
7
- export declare function stringifyGBK({ features, assemblyName, session, stopToken, statusCallback, }: {
7
+ export declare function stringifyGBK({ features, assemblyName, session, signal, statusCallback, }: {
8
8
  assemblyName: string;
9
9
  session: AbstractSessionModel;
10
10
  features: Feature[];
11
- stopToken?: StopToken;
11
+ signal?: AbortSignal;
12
12
  statusCallback?: StatusCallback;
13
13
  }): Promise<string>;
@@ -148,7 +148,7 @@ function formatHeader({ refName, region, assemblyName, length, }) {
148
148
  // One LOCUS..ORIGIN..// record, spanning the features on a single reference
149
149
  // sequence. GenBank has no way to express a span that crosses one, which is why
150
150
  // this takes a refName rather than deriving it.
151
- async function formatRecord({ refName, features, assemblyName, session, stopToken, statusCallback, }) {
151
+ async function formatRecord({ refName, features, assemblyName, session, signal, statusCallback, }) {
152
152
  const minPos = min(features.map(f => f.get('start')));
153
153
  const maxPos = max(features.map(f => f.get('end')));
154
154
  const length = maxPos - minPos;
@@ -159,14 +159,14 @@ async function formatRecord({ refName, features, assemblyName, session, stopToke
159
159
  start: minPos,
160
160
  end: maxPos,
161
161
  refName,
162
- stopToken,
162
+ signal,
163
163
  statusCallback,
164
164
  });
165
165
  const header = formatHeader({ refName, region, assemblyName, length });
166
166
  const body = features.map(feat => formatFeatWithSubfeatures({ feature: feat, minPos }));
167
167
  return [...header, ...body, ...formatOrigin(contig)].join('\n');
168
168
  }
169
- export async function stringifyGBK({ features, assemblyName, session, stopToken, statusCallback, }) {
169
+ export async function stringifyGBK({ features, assemblyName, session, signal, statusCallback, }) {
170
170
  // A record per reference sequence, which is what GenBank is: a multi-region
171
171
  // view used to take min(start)/max(end) across every feature and label the
172
172
  // result with the first one's refName, so two contigs on screen produced one
@@ -182,7 +182,7 @@ export async function stringifyGBK({ features, assemblyName, session, stopToken,
182
182
  features: feats,
183
183
  assemblyName,
184
184
  session,
185
- stopToken,
185
+ signal,
186
186
  statusCallback: slot(),
187
187
  })));
188
188
  return records.join('\n');
@@ -1,10 +1,10 @@
1
- import type { AbstractSessionModel, Feature, StatusCallback, StopToken } from '@jbrowse/core/util';
1
+ import type { AbstractSessionModel, Feature, StatusCallback } from '@jbrowse/core/util';
2
2
  export interface FileTypeExporter {
3
3
  name: string;
4
4
  extension: string;
5
5
  helpText?: string;
6
6
  /**
7
- * The stop token and status callback are the pair every RPC on the export
7
+ * The signal and status callback are the pair every RPC on the export
8
8
  * path already carries. Most writers are string assembly and ignore both;
9
9
  * GenBank fetches the ORIGIN sequence, and without them closing the dialog
10
10
  * left a whole-gene read running with nothing waiting on it.
@@ -13,7 +13,7 @@ export interface FileTypeExporter {
13
13
  features: Feature[];
14
14
  session: AbstractSessionModel;
15
15
  assemblyName: string;
16
- stopToken?: StopToken;
16
+ signal?: AbortSignal;
17
17
  statusCallback?: StatusCallback;
18
18
  }) => Promise<string> | string;
19
19
  }
@@ -1,7 +1,6 @@
1
1
  import type PluginManager from '../PluginManager.ts';
2
2
  import type { AnyConfigurationModel } from '../configuration/index.ts';
3
3
  import type RpcMethodType from '../pluggableElementTypes/RpcMethodType.ts';
4
- import type { StatusCallback } from '../util/progress.ts';
5
4
  import type { RpcHandles } from './RpcRegistry.ts';
6
5
  /**
7
6
  * The method that drops a session's cached adapters, named once because
@@ -28,5 +27,5 @@ export default abstract class BaseRpcDriver {
28
27
  freeSession(sessionId: string): Promise<void>;
29
28
  destroy(): void;
30
29
  call(sessionId: string, functionName: string, args: Record<string, unknown> & RpcHandles): Promise<unknown>;
31
- protected abstract transport(sessionId: string, rpcMethod: RpcMethodType, serializedArgs: Record<string, unknown>, statusCallback: StatusCallback | undefined): Promise<unknown>;
30
+ protected abstract transport(sessionId: string, rpcMethod: RpcMethodType, serializedArgs: Record<string, unknown>, handles: RpcHandles): Promise<unknown>;
32
31
  }
@@ -1,4 +1,4 @@
1
- import { isStopToken, withStopTokenCheck } from '../util/stopToken.js';
1
+ import { checkAbortSignal, withAbortCheck } from '../util/aborting.js';
2
2
  /**
3
3
  * The method that drops a session's cached adapters, named once because
4
4
  * {@link BaseRpcDriver.freeSession} is the only thing that dispatches it.
@@ -44,40 +44,33 @@ export default class BaseRpcDriver {
44
44
  // "which plugin is missing" answer. No `undefined` check belongs here; one
45
45
  // was added and lint called it dead, correctly.
46
46
  const rpcMethod = this.pluginManager.getRpcMethodType(functionName);
47
- // statusCallback is an out-of-band progress handle, not data: each transport
48
- // wires up its own channel for it, so it must not reach the serialized
49
- // payload. Everything that does must be structured-cloneable; the worker
50
- // postMessage clones it and throws on anything that isn't, surfacing bad data
47
+ // The two handles are out of band, not data: each transport wires its own
48
+ // channel for them, and neither survives structured clone. The worker
49
+ // postMessage throws on anything that isn't cloneable, surfacing bad data
51
50
  // at the boundary instead of silently dropping it.
52
51
  //
53
- // Stripped on the way OUT rather than on the way in, so `serializeArguments`
54
- // can see it. That is not cosmetic: serialization is where the refName map
55
- // is resolved, and resolving one downloads the adapter's index (and for an
56
- // in-memory adapter, the whole file). Destructuring the callback off first
57
- // left that download with nothing to report through — `loadRefNameMap`
58
- // forwards a `statusCallback` for exactly this and, for every RPC, was
59
- // handed undefined. The wire payload is identical either way.
52
+ // The callback is stripped on the way OUT rather than on the way in, so
53
+ // `serializeArguments` can see it. That is not cosmetic: serialization is
54
+ // where the refName map is resolved, and resolving one downloads the
55
+ // adapter's index (and for an in-memory adapter, the whole file).
56
+ // Destructuring the callback off first left that download with nothing to
57
+ // report through — `loadRefNameMap` forwards a `statusCallback` for exactly
58
+ // this and, for every RPC, was handed undefined.
60
59
  //
61
60
  // Serialization is the one long await here, and it is wrapped rather than
62
61
  // fenced by hand-placed checks so the check on the FAR side comes with the
63
- // near one — that is the whole point of `withStopTokenCheck`, and the far
64
- // one is what was missing. A call whose token was already stopped has
65
- // nothing to deliver to, so refuse it rather than serializing args, waking a
66
- // worker and racing a stop notification against the call it means to cancel;
67
- // and a stop landing DURING serialization had nowhere to be seen at all,
68
- // because the broadcast it fires reaches only *booted* workers and on a
69
- // driver's first call `LazyWorker.workerP` is undefined until `transport`
70
- // reaches `getWorker`. The worker never learned the token was stopped and
71
- // ground the fetch to completion. SharedArrayBuffer tokens see the stop
72
- // through shared memory regardless; this is the string-token path, which is
73
- // every deployment we ship — `stopToken.ts`, "Which path runs where".
74
- //
75
- // Callers already treat an abort as the ordinary outcome of a superseded
76
- // fetch.
77
- const stopToken = isStopToken(args.stopToken) ? args.stopToken : undefined;
78
- const { statusCallback } = args;
79
- const { statusCallback: _outOfBand, ...serializedArgs } = await withStopTokenCheck(stopToken, () => rpcMethod.serializeArguments(args));
80
- const result = await this.transport(sessionId, rpcMethod, serializedArgs, statusCallback);
62
+ // near one. A call already aborted has nothing to deliver to, so refuse it
63
+ // rather than serializing args and waking a worker; an abort landing DURING
64
+ // serialization used to go unseen and the worker ground the fetch to
65
+ // completion. Callers already treat an abort as the ordinary outcome of a
66
+ // superseded fetch.
67
+ const { signal, ...rest } = args;
68
+ checkAbortSignal(signal);
69
+ const { statusCallback: _outOfBand, ...serializedArgs } = await withAbortCheck(signal, () => rpcMethod.serializeArguments(rest));
70
+ const result = await this.transport(sessionId, rpcMethod, serializedArgs, {
71
+ statusCallback: rest.statusCallback,
72
+ signal,
73
+ });
81
74
  return rpcMethod.deserializeReturn(result, args);
82
75
  }
83
76
  }
@@ -1,6 +1,6 @@
1
1
  import BaseRpcDriver from './BaseRpcDriver.ts';
2
2
  import type RpcMethodType from '../pluggableElementTypes/RpcMethodType.ts';
3
- import type { StatusCallback } from '../util/progress.ts';
3
+ import type { RpcHandles } from './RpcRegistry.ts';
4
4
  /**
5
5
  * RPC driver that runs RPC functions in-band on the main thread. It owns no
6
6
  * worker pool, so `destroy` stays the BaseRpcDriver no-op and `freeSession`
@@ -9,5 +9,5 @@ import type { StatusCallback } from '../util/progress.ts';
9
9
  */
10
10
  export default class MainThreadRpcDriver extends BaseRpcDriver {
11
11
  name: string;
12
- protected transport(_sessionId: string, rpcMethod: RpcMethodType, serializedArgs: Record<string, unknown>, statusCallback: StatusCallback | undefined): Promise<unknown>;
12
+ protected transport(_sessionId: string, rpcMethod: RpcMethodType, serializedArgs: Record<string, unknown>, { statusCallback, signal }: RpcHandles): Promise<unknown>;
13
13
  }
@@ -7,16 +7,21 @@ import BaseRpcDriver from './BaseRpcDriver.js';
7
7
  */
8
8
  export default class MainThreadRpcDriver extends BaseRpcDriver {
9
9
  name = 'MainThreadRpcDriver';
10
- async transport(_sessionId, rpcMethod, serializedArgs, statusCallback) {
11
- // re-attach the out-of-band statusCallback that BaseRpcDriver.call split off,
12
- // mirroring how the worker re-wires it on the far side of postMessage —
13
- // including the case where there is none, which `wrapForRpc` answers by
14
- // adding no key at all. Spreading `statusCallback: undefined` in would leave
15
- // the two drivers handing `execute` bags that differ by a key, which is the
16
- // kind of difference nothing tests and something eventually reads.
10
+ async transport(_sessionId, rpcMethod, serializedArgs, { statusCallback, signal }) {
11
+ // re-attach the out-of-band handles that BaseRpcDriver.call split off,
12
+ // mirroring how the worker re-wires them on the far side of postMessage —
13
+ // including the case where there is none, which `wrapForRpc` and
14
+ // `RpcServer` answer by adding no key at all. Spreading `statusCallback:
15
+ // undefined` in would leave the two drivers handing `execute` bags that
16
+ // differ by a key, which is the kind of difference nothing tests and
17
+ // something eventually reads.
17
18
  //
18
19
  // `invoke`, not `execute` — it is the entry point that deserializes the
19
20
  // arguments first, and the worker binds the same one
20
- return rpcMethod.invoke(statusCallback ? { ...serializedArgs, statusCallback } : serializedArgs);
21
+ return rpcMethod.invoke({
22
+ ...serializedArgs,
23
+ ...(statusCallback ? { statusCallback } : {}),
24
+ ...(signal ? { signal } : {}),
25
+ });
21
26
  }
22
27
  }
@@ -27,12 +27,23 @@ export default class RpcClient {
27
27
  protected reject(uid: string, error: string | ErrorObject): void;
28
28
  protected resolve(uid: string, data: unknown): void;
29
29
  /**
30
- * Tell this worker that a stop token has been stopped, so the calls running
31
- * there see it at their next await boundary and drop their in-flight reads.
32
- * Fire-and-forget: it settles no pending call, and a worker holding nothing
33
- * under that id ignores it.
30
+ * Abort the call `uid`, so the signal it runs under in the worker aborts.
31
+ * Fire-and-forget: it settles no pending call, and a worker no longer running
32
+ * that call ignores it.
34
33
  */
35
- notifyStopToken(id: string): void;
36
- call(method: string, data: unknown): Promise<unknown>;
34
+ abort(uid: string): void;
35
+ /**
36
+ * No transfer list: transferables flow only worker → main, in a reply's
37
+ * rpcResult wrapper. Transferring an argument would neuter the main thread's
38
+ * own buffer — this took an option for one and nothing ever passed it.
39
+ *
40
+ * With a `signal`, the worker runs the method under a signal of its own and
41
+ * aborts it when this one aborts. The uid is the call's identity on both
42
+ * sides, so the abort frame needs nothing else; the listener is attached
43
+ * before the call frame is posted and removed when the call settles, so an
44
+ * abort in between reaches a worker still running the call, and one after
45
+ * reaches nothing.
46
+ */
47
+ call(method: string, data: unknown, signal?: AbortSignal): Promise<unknown>;
37
48
  }
38
49
  export {};
@@ -1,3 +1,4 @@
1
+ import { makeAbortError } from '../util/aborting.js';
1
2
  import { deserializeError } from './serializeError/index.js';
2
3
  export default class RpcClient {
3
4
  worker;
@@ -125,28 +126,57 @@ export default class RpcClient {
125
126
  }
126
127
  }
127
128
  /**
128
- * Tell this worker that a stop token has been stopped, so the calls running
129
- * there see it at their next await boundary and drop their in-flight reads.
130
- * Fire-and-forget: it settles no pending call, and a worker holding nothing
131
- * under that id ignores it.
129
+ * Abort the call `uid`, so the signal it runs under in the worker aborts.
130
+ * Fire-and-forget: it settles no pending call, and a worker no longer running
131
+ * that call ignores it.
132
132
  */
133
- notifyStopToken(id) {
134
- this.worker.postMessage({ stopToken: id, libRpc: true });
133
+ abort(uid) {
134
+ this.worker.postMessage({ abort: uid, libRpc: true });
135
135
  }
136
- // No transfer list: transferables flow only worker → main, in a reply's
137
- // rpcResult wrapper. Transferring an argument would neuter the main thread's
138
- // own buffer — this took an option for one and nothing ever passed it.
139
- call(method, data) {
136
+ /**
137
+ * No transfer list: transferables flow only worker → main, in a reply's
138
+ * rpcResult wrapper. Transferring an argument would neuter the main thread's
139
+ * own buffer — this took an option for one and nothing ever passed it.
140
+ *
141
+ * With a `signal`, the worker runs the method under a signal of its own and
142
+ * aborts it when this one aborts. The uid is the call's identity on both
143
+ * sides, so the abort frame needs nothing else; the listener is attached
144
+ * before the call frame is posted and removed when the call settles, so an
145
+ * abort in between reaches a worker still running the call, and one after
146
+ * reaches nothing.
147
+ */
148
+ call(method, data, signal) {
140
149
  const uid = String(++this.counter);
141
150
  return new Promise((resolve, reject) => {
142
- this.pending.set(uid, { resolve, reject });
151
+ if (signal?.aborted) {
152
+ reject(makeAbortError());
153
+ return;
154
+ }
155
+ const onAbort = () => {
156
+ this.abort(uid);
157
+ };
158
+ signal?.addEventListener('abort', onAbort, { once: true });
159
+ const detach = () => {
160
+ signal?.removeEventListener('abort', onAbort);
161
+ };
162
+ this.pending.set(uid, {
163
+ resolve: value => {
164
+ detach();
165
+ resolve(value);
166
+ },
167
+ reject: error => {
168
+ detach();
169
+ reject(error);
170
+ },
171
+ });
143
172
  try {
144
- this.worker.postMessage({ method, uid, data, libRpc: true }, []);
173
+ this.worker.postMessage({ method, uid, data, libRpc: true, abortable: signal !== undefined }, []);
145
174
  }
146
175
  catch (e) {
147
176
  // a non-cloneable payload throws here, which rejects this promise; drop
148
177
  // the entry that is now waiting on a reply the worker never received
149
178
  this.pending.delete(uid);
179
+ detach();
150
180
  throw e;
151
181
  }
152
182
  });
@@ -9,18 +9,16 @@ export interface RpcManagerOptions {
9
9
  export default class RpcManager {
10
10
  static configSchema: import("../configuration/configurationSchema.ts").ConfigurationSchemaType<{
11
11
  readonly defaultDriver: {
12
- readonly type: "string";
13
- readonly description: "the RPC driver to run data fetching on: MainThreadRpcDriver or WebWorkerRpcDriver. Leave empty to use the default for this application";
14
- readonly defaultValue: "";
15
- readonly advanced: true;
12
+ type: "string";
13
+ } & {
14
+ defaultValue: string;
16
15
  };
17
16
  readonly workerCount: {
18
- readonly type: "number";
19
- readonly description: "The number of workers to use. If 0 (the default) JBrowse will decide how many workers to use.";
20
- readonly defaultValue: 0;
21
- readonly advanced: true;
17
+ type: "number";
18
+ } & {
19
+ defaultValue: number;
22
20
  };
23
- }, import("../configuration/configurationSchema.ts").ConfigurationSchemaOptions<undefined, undefined>>;
21
+ }, import("../configuration/configurationSchema.ts").ConfigurationSchemaOptions<undefined, undefined, undefined, import("../configuration/requirements.ts").ConfigurationSchemaRequirement<Partial<Record<string, string[]>>, string>>>;
24
22
  private pluginManager;
25
23
  private mainConfiguration;
26
24
  private hostDriverName;
@@ -60,7 +58,7 @@ export default class RpcManager {
60
58
  private makeDriver;
61
59
  /**
62
60
  * `args` carries the method's data and the caller's handles on the operation —
63
- * the stop token and the status callback. Both handles are always accepted,
61
+ * the signal and the status callback. Both handles are always accepted,
64
62
  * for every method, because {@link RpcHandles} is part of `RpcCallArgs` rather
65
63
  * than of any registry entry.
66
64
  *
@@ -82,7 +82,7 @@ export default class RpcManager {
82
82
  }
83
83
  /**
84
84
  * `args` carries the method's data and the caller's handles on the operation —
85
- * the stop token and the status callback. Both handles are always accepted,
85
+ * the signal and the status callback. Both handles are always accepted,
86
86
  * for every method, because {@link RpcHandles} is part of `RpcCallArgs` rather
87
87
  * than of any registry entry.
88
88
  *
@@ -3,7 +3,6 @@ import type { CoreEncodeFeaturesArgs, EncodedFeaturesResult } from '../util/mark
3
3
  import type { StatusCallback } from '../util/progress.ts';
4
4
  import type { UnwrapRpcResult } from '../util/rpc.ts';
5
5
  import type { Feature, SimpleFeatureSerialized } from '../util/simpleFeature.ts';
6
- import type { StopToken } from '../util/stopToken.ts';
7
6
  import type { NoAssemblyRegion } from '../util/types/data.ts';
8
7
  import type { RpcResult } from './RpcServer.ts';
9
8
  import type { ByteEstimateScope, RegionTooLargeResult } from './byteBudget.ts';
@@ -50,6 +49,13 @@ export interface RpcRegistry {
50
49
  return: EncodedFeaturesResult | RegionTooLargeResult;
51
50
  transferables: EncodedFeaturesResult;
52
51
  };
52
+ CoreGetEncodedFeature: {
53
+ args: Omit<CoreEncodeFeaturesArgs, 'byteLimit'> & {
54
+ layer: number;
55
+ featureIndex: number;
56
+ };
57
+ return: SimpleFeatureSerialized | undefined;
58
+ };
53
59
  CoreGetRegionByteEstimate: {
54
60
  args: {
55
61
  adapterConfig: Record<string, unknown>;
@@ -120,7 +126,7 @@ export type RpcReturn<M extends RpcMethodName> = RpcRegistry[M]['return'];
120
126
  * the pattern the type exists to support.
121
127
  */
122
128
  export type RpcHandles = {
123
- stopToken?: StopToken;
129
+ signal?: AbortSignal;
124
130
  statusCallback?: StatusCallback;
125
131
  };
126
132
  export type RpcSession = {
@@ -12,11 +12,13 @@ interface RpcMessageData {
12
12
  uid: string;
13
13
  libRpc?: true;
14
14
  data: unknown;
15
- stopToken?: string;
15
+ abortable?: boolean;
16
+ abort?: string;
16
17
  }
17
18
  export default class RpcServer {
18
19
  protected methods: Record<string, Procedure>;
19
20
  private self;
21
+ private aborters;
20
22
  constructor(methods: Record<string, Procedure>);
21
23
  handler(e: MessageEvent<RpcMessageData>): void;
22
24
  private post;
@@ -1,5 +1,4 @@
1
1
  import { isRpcResult } from '../util/rpc.js';
2
- import { markStopTokenStopped } from '../util/stopToken.js';
3
2
  import { bufferPaths, containerEntries, explainTransferError, } from './explainTransferError.js';
4
3
  import { serializeError } from './serializeError/index.js';
5
4
  // `self` is a DedicatedWorkerGlobalScope in the worker, but the DOM lib types the
@@ -126,6 +125,7 @@ export function rpcResultWithArrayBuffers(value) {
126
125
  export default class RpcServer {
127
126
  methods;
128
127
  self;
128
+ aborters = new Map();
129
129
  constructor(methods) {
130
130
  if (!workerSelf) {
131
131
  throw new Error('RpcServer must be constructed in a worker global scope');
@@ -143,31 +143,38 @@ export default class RpcServer {
143
143
  });
144
144
  }
145
145
  handler(e) {
146
- const { libRpc, method, uid, data, stopToken } = e.data;
146
+ const { libRpc, method, uid, data, abort, abortable } = e.data;
147
147
  if (!libRpc) {
148
148
  return;
149
149
  }
150
- if (stopToken !== undefined) {
151
- // Every in-flight method holding this token now sees it as stopped at its
152
- // next await boundary, and any AbortSignal taken against it aborts, so a
153
- // canceled read drops off the socket. Handled ahead of the method lookup:
154
- // this frame has no method name and would otherwise land in the unknown
155
- // method branch with no uid to reply to.
156
- markStopTokenStopped(stopToken);
150
+ if (abort !== undefined) {
151
+ // Handled ahead of the method lookup: this frame has no method name and
152
+ // would otherwise land in the unknown method branch with no uid to reply
153
+ // to. A call that already settled left no controller, so a late abort is
154
+ // a no-op.
155
+ this.aborters.get(abort)?.abort();
157
156
  return;
158
157
  }
159
158
  const methodFn = Object.hasOwn(this.methods, method)
160
159
  ? this.methods[method]
161
160
  : undefined;
162
161
  if (methodFn) {
163
- // wrap so a synchronous throw inside methodFn still routes to .throw()
164
- ;
165
- (async () => methodFn(data))()
162
+ const controller = abortable ? new AbortController() : undefined;
163
+ if (controller) {
164
+ this.aborters.set(uid, controller);
165
+ }
166
+ const args = controller
167
+ ? { ...data, signal: controller.signal }
168
+ : data;
169
+ (async () => methodFn(args))()
166
170
  .then(response => {
167
171
  this.reply(uid, response, method);
168
172
  })
169
173
  .catch((error) => {
170
174
  this.throw(uid, serializeError(error));
175
+ })
176
+ .finally(() => {
177
+ this.aborters.delete(uid);
171
178
  });
172
179
  }
173
180
  else {