@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,61 +1,27 @@
1
- /**
2
- * @module
3
- * Resolving the `formatDetails` config hook across its two tiers, on behalf of
4
- * the feature-details widget's autorun. Plain functions rather than model
5
- * members: an MST action runs untracked, so folding these into one would leave
6
- * the autorun with no observable reads and fire it exactly once.
7
- */
8
- import { DEFAULT_FORMAT_DETAILS_DEPTH, getConf, mergeFormatCallbacks, } from '../configuration/index.js';
9
- import { isObject } from '../util/index.js';
10
- import { isEmpty } from './BaseFeatureDetail/util.js';
11
- import { formatSubfeatures } from './util.js';
12
- /** Both tiers of one slot, session first, so a spread puts the track on top. */
1
+ import { DEFAULT_FORMAT_DETAILS_DEPTH, mergeFormatCallbacks, readConfObject, } from '../configuration/index.js';
2
+ import { isPlainObject } from '../util/objectUtils.js';
13
3
  function readTiers({ session, track }, slot, args) {
14
4
  return [
15
- getConf(session, ['formatDetails', slot], args),
16
- track ? getConf(track, ['formatDetails', slot], args) : undefined,
5
+ readConfObject(session, ['formatDetails', slot], args),
6
+ track ? readConfObject(track, ['formatDetails', slot], args) : undefined,
17
7
  ];
18
8
  }
19
9
  /**
20
- * Whether either tier **declares** a callback for `slot`, read RAW off the
21
- * config node.
22
- *
23
- * Deliberately not `readTiers`: "is anything configured here" and "what does
24
- * this produce for this feature" are different questions, and an arg-less read
25
- * of a `jexl:` slot answers the second one badly — it evaluates the user's
26
- * expression against a context where `feature` is undefined (see
27
- * `configuration/CLAUDE.md`), which is a throw or a junk value, per tier, just
28
- * to find out the slot exists.
29
- *
30
- * Both callback slots default to `{}`, so a config that never mentions
31
- * `formatDetails` answers false for both and `applyFormatDetails` can hand the
32
- * feature straight back. That is the whole point of asking: the walk it skips
33
- * is proportional to the subfeature tree, and the tree can be very large (a
34
- * RefSeq BRCA1 is 368 transcripts, ~16k nodes) while the config that formats
35
- * none of it is the overwhelmingly common one.
10
+ * Whether either tier sets `slot`, read raw off the node: an arg-less read of
11
+ * a `jexl:` slot evaluates it against an empty context just to find out it
12
+ * exists. Both callback slots default to `{}`, so a config that never mentions
13
+ * `formatDetails` answers false and the walk below is skipped entirely, which
14
+ * matters on a RefSeq gene with 16k nested nodes.
36
15
  */
37
16
  function declaresCallback({ session, track }, slot) {
38
- return [session, track].some(holder => {
39
- // raw property access, not a reader: see above
40
- const sub = holder?.configuration.formatDetails;
41
- const value = sub?.[slot];
42
- // a `jexl:` slot is a string; a plain-object slot counts only when it has
43
- // keys, since `{}` is the schema default and merges to nothing
17
+ return [session, track].some(conf => {
18
+ const value = conf?.formatDetails?.[slot];
44
19
  return typeof value === 'string'
45
20
  ? value !== ''
46
- : isObject(value) && !isEmpty(value);
21
+ : isPlainObject(value) && Object.keys(value).length > 0;
47
22
  });
48
23
  }
49
- /**
50
- * `depth` or `maxDepth`: the track's value when the track sets one, else the
51
- * session's, else unset.
52
- *
53
- * These override rather than merge, unlike the callback objects. That is only
54
- * expressible because both are `maybeNumber` slots with no `defaultValue` --
55
- * given a schema default the track reported a value whether or not anyone set
56
- * one, so the session-wide tier could never apply to a track, and every real
57
- * config has a track.
58
- */
24
+ /** `depth` or `maxDepth`: the track's value when set, else the session's. */
59
25
  export function formatDetailsNumber(tiers, slot) {
60
26
  const [fromSession, fromTrack] = readTiers(tiers, slot);
61
27
  return typeof fromTrack === 'number'
@@ -65,39 +31,40 @@ export function formatDetailsNumber(tiers, slot) {
65
31
  : undefined;
66
32
  }
67
33
  /**
68
- * A copy of the feature with each tier's callback output merged onto it (and
69
- * onto its subfeatures, down to `depth`) as `__jbrowsefmt`, which the detail
70
- * components spread over the raw fields at render.
71
- *
72
- * `__jbrowsefmt` is attached only where a callback produced something, so a
73
- * config with no `formatDetails` at all leaves the feature exactly as it came
74
- * in rather than stamping empty objects through the persisted snapshot.
34
+ * The feature as the details panel shows it: each tier's `feature` callback
35
+ * output spread over the clicked feature, and `subfeatures` output over each
36
+ * subfeature down to `depth`. A key set to null or undefined hides that row,
37
+ * since every detail component filters with `!= null`. A config declaring no
38
+ * callback gets the input back untouched.
75
39
  */
76
- export function applyFormatDetails(tiers, featureData) {
77
- const hasFeature = declaresCallback(tiers, 'feature');
78
- const hasSubfeatures = declaresCallback(tiers, 'subfeatures');
79
- // Nothing declared by either tier: the result is the input, so return the
80
- // input. The clone and the per-node walk below are both proportional to the
81
- // subfeature tree and both produce nothing here, and this is the default
82
- // config -- most tracks never set `formatDetails` at all.
83
- if (!hasFeature && !hasSubfeatures) {
84
- return featureData;
85
- }
86
- const feature = structuredClone(featureData);
87
- if (hasFeature) {
88
- const fmt = mergeFormatCallbacks(...readTiers(tiers, 'feature', { feature }));
89
- if (!isEmpty(fmt)) {
90
- feature.__jbrowsefmt = fmt;
91
- }
40
+ export function applyFormatDetails(tiers, feature) {
41
+ const formatsFeature = declaresCallback(tiers, 'feature');
42
+ const formatsSubfeatures = declaresCallback(tiers, 'subfeatures');
43
+ if (!formatsFeature && !formatsSubfeatures) {
44
+ return feature;
92
45
  }
93
- if (hasSubfeatures) {
94
- const depth = formatDetailsNumber(tiers, 'depth') ?? DEFAULT_FORMAT_DETAILS_DEPTH;
95
- formatSubfeatures(feature, depth, sub => {
96
- const subFmt = mergeFormatCallbacks(...readTiers(tiers, 'subfeatures', { feature: sub }));
97
- if (!isEmpty(subFmt)) {
98
- sub.__jbrowsefmt = subFmt;
99
- }
100
- });
46
+ const depth = formatsSubfeatures
47
+ ? (formatDetailsNumber(tiers, 'depth') ?? DEFAULT_FORMAT_DETAILS_DEPTH)
48
+ : 0;
49
+ const track = tiers.track ? readConfObject(tiers.track) : undefined;
50
+ function format(node, level, fmt) {
51
+ const { subfeatures } = node;
52
+ return {
53
+ ...node,
54
+ ...(subfeatures && level < depth
55
+ ? {
56
+ subfeatures: subfeatures.map(sub => format(sub, level + 1, mergeFormatCallbacks(...readTiers(tiers, 'subfeatures', {
57
+ feature: sub,
58
+ parent: node,
59
+ depth: level + 1,
60
+ track,
61
+ })))),
62
+ }
63
+ : {}),
64
+ ...fmt,
65
+ };
101
66
  }
102
- return feature;
67
+ return format(feature, 0, formatsFeature
68
+ ? mergeFormatCallbacks(...readTiers(tiers, 'feature', { feature, track }))
69
+ : {});
103
70
  }
@@ -1,5 +1,6 @@
1
1
  export { configSchema } from './configSchema.ts';
2
2
  export type { Descriptors, FeatureDetailsModel, MaybeSerializedFeat, } from './types.tsx';
3
3
  export type { SequenceHoverPosition, ShowCoordinatesMode, } from './SequenceFeatureDetails/model.ts';
4
+ export type { FormatDetailsTiers } from './formatDetails.ts';
4
5
  export { stateModelFactory } from './stateModelFactory.ts';
5
6
  export type { BaseFeatureWidgetModel, BaseFeatureWidgetStateModel, } from './stateModelFactory.ts';
@@ -1,14 +1,16 @@
1
1
  import type PluginManager from '../PluginManager.ts';
2
+ import type { AnyConfigurationModel } from '../configuration/index.ts';
2
3
  import type { ParentFeatureSummary, SimpleFeatureSerialized } from '../util/index.ts';
3
4
  import type { SequenceHoverPosition } from './SequenceFeatureDetails/model.ts';
5
+ import type { FormatDetailsTiers } from './formatDetails.ts';
4
6
  import type { Descriptors, MaybeSerializedFeat } from './types.tsx';
5
7
  import type { Instance } from '@jbrowse/mobx-state-tree';
6
8
  /**
7
9
  * #stateModel BaseFeatureWidget
8
- * displays data about features, allowing configuration callbacks to modify the
9
- * contents of what is displayed
10
- *
11
- * see: formatDetails-\>feature,formatDetails-\>subfeatures
10
+ * The feature-details panel. `featureData` is the clicked feature with the
11
+ * track's and the session's `formatDetails` callbacks applied, derived on read
12
+ * from the raw feature the widget was opened with, so the same widget follows a
13
+ * config edit and survives its track being closed.
12
14
  */
13
15
  export declare function stateModelFactory(pluginManager: PluginManager): import("@jbrowse/mobx-state-tree").IModelType<{
14
16
  /**
@@ -21,10 +23,8 @@ export declare function stateModelFactory(pluginManager: PluginManager): import(
21
23
  type: import("@jbrowse/mobx-state-tree").ILiteralType<"BaseFeatureWidget">;
22
24
  /**
23
25
  * #property
24
- */
25
- featureData: import("@jbrowse/mobx-state-tree").IOptionalIType<import("@jbrowse/mobx-state-tree").IType<MaybeSerializedFeat, MaybeSerializedFeat, MaybeSerializedFeat>, [undefined]>;
26
- /**
27
- * #property
26
+ * the feature as the click handed it over, before any callback ran.
27
+ * Persisted as `featureData`
28
28
  */
29
29
  unformattedFeatureData: import("@jbrowse/mobx-state-tree").IOptionalIType<import("@jbrowse/mobx-state-tree").IType<MaybeSerializedFeat, MaybeSerializedFeat, MaybeSerializedFeat>, [undefined]>;
30
30
  /**
@@ -43,10 +43,6 @@ export declare function stateModelFactory(pluginManager: PluginManager): import(
43
43
  * #property
44
44
  */
45
45
  trackType: import("@jbrowse/mobx-state-tree").IMaybe<import("@jbrowse/mobx-state-tree").ISimpleType<string>>;
46
- /**
47
- * #property
48
- */
49
- maxDepth: import("@jbrowse/mobx-state-tree").IMaybe<import("@jbrowse/mobx-state-tree").ISimpleType<number>>;
50
46
  /**
51
47
  * #property
52
48
  */
@@ -76,39 +72,51 @@ export declare function stateModelFactory(pluginManager: PluginManager): import(
76
72
  */
77
73
  parentFeature: import("@jbrowse/mobx-state-tree").IOptionalIType<import("@jbrowse/mobx-state-tree").IType<ParentFeatureSummary | undefined, ParentFeatureSummary | undefined, ParentFeatureSummary | undefined>, [undefined]>;
78
74
  }, {
79
- error: unknown;
80
75
  sequenceHoverPosition: SequenceHoverPosition | undefined;
81
76
  } & {
82
77
  /**
83
- * #action
78
+ * #getter
79
+ * the config the track tier of `formatDetails` reads. The open track's
80
+ * own while it is open; after it is closed, the session's copy of the
81
+ * same config, which is why the widget records `trackId`
84
82
  */
85
- setSequenceHoverPosition(pos: SequenceHoverPosition | undefined): void;
83
+ readonly trackConfiguration: AnyConfigurationModel | undefined;
84
+ } & {
85
+ readonly formatDetailsTiers: FormatDetailsTiers;
86
+ } & {
87
+ readonly formatted: {
88
+ feature?: SimpleFeatureSerialized;
89
+ error?: Error;
90
+ };
86
91
  /**
87
- * #action
92
+ * #getter
93
+ * levels of subfeature card the panel renders; unset means no limit
88
94
  */
89
- setFeatureData(featureData: SimpleFeatureSerialized): void;
95
+ readonly maxDepth: number | undefined;
96
+ } & {
90
97
  /**
91
- * #action
98
+ * #getter
99
+ * the feature with every `formatDetails` callback applied
92
100
  */
93
- clearFeatureData(): void;
101
+ readonly featureData: SimpleFeatureSerialized | undefined;
94
102
  /**
95
- * #action
103
+ * #getter
96
104
  */
97
- setFormattedData(feat: SimpleFeatureSerialized): void;
105
+ readonly error: Error | undefined;
106
+ } & {
107
+ afterAttach(): void;
98
108
  /**
99
109
  * #action
100
110
  */
101
- setTrackInfo(type?: string, trackId?: string): void;
111
+ setSequenceHoverPosition(pos: SequenceHoverPosition | undefined): void;
102
112
  /**
103
113
  * #action
104
114
  */
105
- setMaxDepth(maxDepth?: number): void;
115
+ setFeatureData(featureData: SimpleFeatureSerialized): void;
106
116
  /**
107
117
  * #action
108
118
  */
109
- setError(e: unknown): void;
110
- } & {
111
- afterCreate(): void;
119
+ clearFeatureData(): void;
112
120
  }, import("@jbrowse/mobx-state-tree")._NotCustomized, {
113
121
  id: string;
114
122
  type: "BaseFeatureWidget";
@@ -116,11 +124,10 @@ export declare function stateModelFactory(pluginManager: PluginManager): import(
116
124
  track: import("@jbrowse/mobx-state-tree").ReferenceIdentifier | undefined;
117
125
  trackId: string | undefined;
118
126
  trackType: string | undefined;
119
- maxDepth: number | undefined;
120
127
  sequenceFeatureDetails: import("@jbrowse/mobx-state-tree").ModelSnapshotType<{}>;
121
128
  descriptions: Descriptors | undefined;
122
129
  parentFeature: ParentFeatureSummary | undefined;
123
- finalizedFeatureData: any;
130
+ featureData: MaybeSerializedFeat;
124
131
  }>;
125
132
  export type BaseFeatureWidgetStateModel = ReturnType<typeof stateModelFactory>;
126
133
  export type BaseFeatureWidgetModel = Instance<BaseFeatureWidgetStateModel>;
@@ -1,16 +1,15 @@
1
- import { addDisposer, types } from '@jbrowse/mobx-state-tree';
2
- import { autorun } from 'mobx';
1
+ import { getEnv, isStateTreeNode, types } from '@jbrowse/mobx-state-tree';
2
+ import { hydrateTrackConfig } from '../configuration/index.js';
3
3
  import { getSession } from '../util/index.js';
4
4
  import { ElementId } from '../util/types/mst.js';
5
5
  import { SequenceFeatureDetailsF } from './SequenceFeatureDetails/model.js';
6
6
  import { applyFormatDetails, formatDetailsNumber } from './formatDetails.js';
7
- import { nullReplacer } from './util.js';
8
7
  /**
9
8
  * #stateModel BaseFeatureWidget
10
- * displays data about features, allowing configuration callbacks to modify the
11
- * contents of what is displayed
12
- *
13
- * see: formatDetails-\>feature,formatDetails-\>subfeatures
9
+ * The feature-details panel. `featureData` is the clicked feature with the
10
+ * track's and the session's `formatDetails` callbacks applied, derived on read
11
+ * from the raw feature the widget was opened with, so the same widget follows a
12
+ * config edit and survives its track being closed.
14
13
  */
15
14
  export function stateModelFactory(pluginManager) {
16
15
  return types
@@ -25,10 +24,8 @@ export function stateModelFactory(pluginManager) {
25
24
  type: types.literal('BaseFeatureWidget'),
26
25
  /**
27
26
  * #property
28
- */
29
- featureData: types.optional(types.frozen(), undefined),
30
- /**
31
- * #property
27
+ * the feature as the click handed it over, before any callback ran.
28
+ * Persisted as `featureData`
32
29
  */
33
30
  unformattedFeatureData: types.optional(types.frozen(), undefined),
34
31
  /**
@@ -47,10 +44,6 @@ export function stateModelFactory(pluginManager) {
47
44
  * #property
48
45
  */
49
46
  trackType: types.maybe(types.string),
50
- /**
51
- * #property
52
- */
53
- maxDepth: types.maybe(types.number),
54
47
  /**
55
48
  * #property
56
49
  */
@@ -67,18 +60,93 @@ export function stateModelFactory(pluginManager) {
67
60
  parentFeature: types.optional(types.frozen(), undefined),
68
61
  })
69
62
  .volatile(() => ({
70
- /**
71
- * #volatile
72
- */
73
- error: undefined,
74
63
  /**
75
64
  * #volatile
76
65
  * genomic base currently hovered in this widget's sequence panel, read by
77
66
  * the LGV crosshair overlay
78
67
  */
79
68
  sequenceHoverPosition: undefined,
69
+ }))
70
+ .views(self => ({
71
+ /**
72
+ * #getter
73
+ * the config the track tier of `formatDetails` reads. The open track's
74
+ * own while it is open; after it is closed, the session's copy of the
75
+ * same config, which is why the widget records `trackId`
76
+ */
77
+ get trackConfiguration() {
78
+ const { track, trackId } = self;
79
+ if (track) {
80
+ return track.configuration;
81
+ }
82
+ if (!trackId) {
83
+ return undefined;
84
+ }
85
+ const conf = getSession(self).getTrackById(trackId);
86
+ return conf === undefined || isStateTreeNode(conf)
87
+ ? conf
88
+ : hydrateTrackConfig(getEnv(self).pluginManager, conf);
89
+ },
90
+ }))
91
+ .views(self => ({
92
+ get formatDetailsTiers() {
93
+ return {
94
+ session: getSession(self).configuration,
95
+ track: self.trackConfiguration,
96
+ };
97
+ },
98
+ }))
99
+ .views(self => ({
100
+ get formatted() {
101
+ const { unformattedFeatureData } = self;
102
+ if (!unformattedFeatureData) {
103
+ return {};
104
+ }
105
+ try {
106
+ return {
107
+ feature: applyFormatDetails(self.formatDetailsTiers, unformattedFeatureData),
108
+ };
109
+ }
110
+ catch (e) {
111
+ const where = self.trackId
112
+ ? `track "${self.trackId}"`
113
+ : 'the session configuration';
114
+ const error = new Error(`Error running the formatDetails callbacks for ${where}: ${e}`, { cause: e });
115
+ console.error(error);
116
+ return { error };
117
+ }
118
+ },
119
+ /**
120
+ * #getter
121
+ * levels of subfeature card the panel renders; unset means no limit
122
+ */
123
+ get maxDepth() {
124
+ return formatDetailsNumber(self.formatDetailsTiers, 'maxDepth');
125
+ },
126
+ }))
127
+ .views(self => ({
128
+ /**
129
+ * #getter
130
+ * the feature with every `formatDetails` callback applied
131
+ */
132
+ get featureData() {
133
+ return self.formatted.feature;
134
+ },
135
+ /**
136
+ * #getter
137
+ */
138
+ get error() {
139
+ return self.formatted.error;
140
+ },
80
141
  }))
81
142
  .actions(self => ({
143
+ afterAttach() {
144
+ const { track } = self;
145
+ if (track) {
146
+ self.trackId = track.configuration.trackId;
147
+ self.trackType = track.type;
148
+ }
149
+ },
82
150
  /**
83
151
  * #action
84
152
  */
@@ -105,96 +173,20 @@ export function stateModelFactory(pluginManager) {
105
173
  * #action
106
174
  */
107
175
  clearFeatureData() {
108
- self.featureData = undefined;
109
- },
110
- /**
111
- * #action
112
- */
113
- setFormattedData(feat) {
114
- self.featureData = feat;
115
- },
116
- /**
117
- * #action
118
- */
119
- setTrackInfo(type, trackId) {
120
- self.trackId = trackId;
121
- self.trackType = type;
122
- },
123
- /**
124
- * #action
125
- */
126
- setMaxDepth(maxDepth) {
127
- self.maxDepth = maxDepth;
128
- },
129
- /**
130
- * #action
131
- */
132
- setError(e) {
133
- self.error = e;
134
- },
135
- }))
136
- .actions(self => ({
137
- afterCreate() {
138
- addDisposer(self, autorun(function featureWidgetAutorun() {
139
- const { track } = self;
140
- // read before any config read so the catch below can attribute
141
- // the failure without repeating one that may be what threw
142
- let trackId;
143
- try {
144
- const { unformattedFeatureData } = self;
145
- const session = getSession(self);
146
- if (track) {
147
- trackId = track.configuration.trackId;
148
- self.setTrackInfo(track.type, trackId);
149
- }
150
- // both tiers apply: a widget can outlive its track
151
- // (safeReference) or never have had one, and the session-wide
152
- // `configuration.formatDetails` still means something. The
153
- // reads stay here in the autorun body rather than moving into
154
- // an action, which would run untracked
155
- const tiers = { session, track };
156
- // an unset maxDepth is the meaningful value, not a missing one:
157
- // the panel reads it as no nesting limit
158
- self.setMaxDepth(formatDetailsNumber(tiers, 'maxDepth'));
159
- if (unformattedFeatureData) {
160
- self.setFormattedData(applyFormatDetails(tiers, unformattedFeatureData));
161
- }
162
- }
163
- catch (e) {
164
- // jexl throws a bare parse/eval message with nothing naming the
165
- // slot or the config it came from, and this banner replaces the
166
- // whole panel -- say where to look
167
- const where = trackId
168
- ? `track "${trackId}"`
169
- : 'the session configuration';
170
- const err = new Error(`Error running the formatDetails callbacks for ${where}: ${e}`, { cause: e });
171
- console.error(err);
172
- self.setError(err);
173
- }
174
- }, { name: 'FeatureWidget' }));
176
+ self.unformattedFeatureData = undefined;
175
177
  },
176
178
  }))
177
179
  .preProcessSnapshot((snap) => {
178
- // old snapshots used `featureData`, new ones use `finalizedFeatureData`;
179
- // accept both for backwards compat
180
- const { featureData, finalizedFeatureData, ...rest } = (snap ?? {});
181
- return {
182
- unformattedFeatureData: featureData,
183
- featureData: finalizedFeatureData,
184
- ...rest,
185
- };
180
+ const { featureData, ...rest } = snap ?? {};
181
+ return { unformattedFeatureData: featureData, ...rest };
186
182
  })
187
183
  .postProcessSnapshot(snap => {
188
- const { unformattedFeatureData, featureData, ...rest } = snap;
184
+ const { unformattedFeatureData, ...rest } = snap;
189
185
  // JSON.stringify can return empty if too large
190
- const s2 = JSON.stringify(featureData, nullReplacer);
191
- const featureTooLargeToBeSerialized = !s2 || s2.length > 2_000_000;
192
- // `finalizedFeatureData` is persisted (rather than `featureData`) so
193
- // loading from snapshot doesn't re-run the formatter callbacks
186
+ const json = JSON.stringify(unformattedFeatureData);
187
+ const tooLargeToPersist = !json || json.length > 2_000_000;
194
188
  return {
195
- finalizedFeatureData: featureTooLargeToBeSerialized
196
- ? undefined
197
- : JSON.parse(s2),
189
+ featureData: tooLargeToPersist ? undefined : unformattedFeatureData,
198
190
  ...rest,
199
191
  };
200
192
  });
@@ -1,3 +1,4 @@
1
+ import type { MenuItem } from '../ui/MenuTypes.ts';
1
2
  import type { SimpleFeatureSerialized } from '../util/simpleFeature.ts';
2
3
  import type { SequenceFeatureDetailsModel, SequenceHoverTarget } from './SequenceFeatureDetails/model.ts';
3
4
  import type { IStateTreeNode } from '@jbrowse/mobx-state-tree';
@@ -13,6 +14,8 @@ export interface Descriptors {
13
14
  [key: string]: React.ReactNode | Descriptors;
14
15
  }
15
16
  export type FeatureFormatter = (value: unknown, key: string, index?: number) => React.ReactNode;
17
+ /** Menu items for one attribute's value, offered from a button on its row. */
18
+ export type FieldActions = (path: string[], value: unknown) => MenuItem[];
16
19
  export interface BaseProps extends BaseCardProps {
17
20
  feature: SimpleFeatureSerialized;
18
21
  formatter?: FeatureFormatter;
@@ -1,4 +1,3 @@
1
- import type { SerializedFeat } from './types.tsx';
2
1
  export interface Feat {
3
2
  start: number;
4
3
  end: number;
@@ -25,5 +24,3 @@ export interface ErrorState {
25
24
  export declare function filterSuccessiveElementsWithSameStartAndEndCoord(list: Feat[]): Feat[];
26
25
  export declare function ellipses(slug: string): string;
27
26
  export declare function getStrandStr(strand: number | undefined): "" | "(+)" | "(-)";
28
- export declare const nullReplacer: (_: string, v: unknown) => {} | null;
29
- export declare function formatSubfeatures(obj: SerializedFeat, depth: number, parse: (obj: Record<string, unknown>) => void, currentDepth?: number): void;
@@ -12,20 +12,3 @@ export function ellipses(slug) {
12
12
  export function getStrandStr(strand) {
13
13
  return strand === -1 ? '(-)' : strand === 1 ? '(+)' : '';
14
14
  }
15
- // JSON only serializes null, not undefined; feature fields are hidden by a
16
- // formatDetails callback returning undefined (jexl can't produce null), so when
17
- // persisting we round-trip undefined to null to keep the field hidden after
18
- // reload (detail components filter with `!= null`). see config guide.
19
- export const nullReplacer = (_, v) => v === undefined ? null : v;
20
- // `depth` is how many levels of subfeature the `formatDetails.subfeatures`
21
- // callback runs on, counted from the clicked feature. The caller resolves it
22
- // across the session and track tiers and passes 0 when neither declares one, so
23
- // a config with no formatDetails schema formats nothing rather than every level
24
- export function formatSubfeatures(obj, depth, parse, currentDepth = 0) {
25
- if (currentDepth < depth) {
26
- for (const sub of obj.subfeatures ?? []) {
27
- formatSubfeatures(sub, depth, parse, currentDepth + 1);
28
- parse(sub);
29
- }
30
- }
31
- }
@@ -4,6 +4,9 @@ export interface PluginRecord {
4
4
  plugin: PluginConstructor;
5
5
  definition: PluginDefinition;
6
6
  }
7
+ export type ReExportRegistryLoader = () => Promise<{
8
+ default: Record<string, unknown>;
9
+ }>;
7
10
  export interface LoadedPlugin {
8
11
  default: PluginConstructor;
9
12
  }
@@ -27,19 +30,21 @@ export default class PluginLoader {
27
30
  default: PluginConstructor;
28
31
  }>;
29
32
  loadPlugin(def: PluginDefinition, baseUri?: string): Promise<PluginConstructor>;
30
- private reExportTarget;
33
+ private reExports;
31
34
  /**
32
35
  * Ask for the runtime ABI (`JBrowseExports`) to be published on `target`
33
- * before any plugin bundle is evaluated. Records the target; the registry
34
- * itself is fetched in `loadSettled` below.
36
+ * before any plugin bundle is evaluated. Records the target and the loader;
37
+ * `loadSettled` fetches the registry, a ~126 KB gzipped module only a runtime
38
+ * plugin can use (see `ReExports/registry.ts` for why it cannot shrink).
35
39
  *
36
- * The split is the point. Every product calls this at startup, synchronously,
37
- * whether or not the config names a plugin — so importing the registry here
38
- * put it in every host's first paint. It is a ~126 KB gzipped module (see
39
- * `ReExports/registry.ts` for why it cannot shrink) that only a runtime plugin
40
- * can use, and loading one is async anyway.
40
+ * `registry` is the product's generated map — `reExports.generated.ts` on
41
+ * the main thread, `workerReExports.generated.ts` in its worker — which
42
+ * serves every `@jbrowse` package the product bundles. The caller names it
43
+ * because the registry serves this module: an `import()` of it from here is
44
+ * a cycle rolldown keeps in any host bundling this file, whether or not
45
+ * anything loads a plugin (EAGER_BUNDLE.md §3).
41
46
  */
42
- installGlobalReExports(target: WindowOrWorkerGlobalScope): this;
47
+ installGlobalReExports(target: WindowOrWorkerGlobalScope, registry: ReExportRegistryLoader): this;
43
48
  private publishReExports;
44
49
  /**
45
50
  * Loads every definition and separates the ones that worked from the ones