@jbrowse/core 5.0.0-beta.1 → 5.0.0-beta.10

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 (611) hide show
  1. package/README.md +1476 -265
  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 +34 -29
  6. package/esm/BaseFeatureWidget/BaseFeatureDetail/BaseCard.js +1 -4
  7. package/esm/BaseFeatureWidget/BaseFeatureDetail/BasicValue.d.ts +11 -0
  8. package/esm/BaseFeatureWidget/BaseFeatureDetail/BasicValue.js +16 -9
  9. package/esm/BaseFeatureWidget/BaseFeatureDetail/CoreDetails.d.ts +1 -1
  10. package/esm/BaseFeatureWidget/BaseFeatureDetail/CoreDetails.js +15 -31
  11. package/esm/BaseFeatureWidget/BaseFeatureDetail/FeatureDetails.d.ts +4 -3
  12. package/esm/BaseFeatureWidget/BaseFeatureDetail/FeatureDetails.js +12 -25
  13. package/esm/BaseFeatureWidget/BaseFeatureDetail/FeatureDetailsFrame.d.ts +11 -0
  14. package/esm/BaseFeatureWidget/BaseFeatureDetail/FeatureDetailsFrame.js +11 -0
  15. package/esm/BaseFeatureWidget/BaseFeatureDetail/FieldActionsButton.d.ts +8 -0
  16. package/esm/BaseFeatureWidget/BaseFeatureDetail/FieldActionsButton.js +24 -0
  17. package/esm/BaseFeatureWidget/BaseFeatureDetail/Formatter.js +6 -4
  18. package/esm/BaseFeatureWidget/BaseFeatureDetail/ParentFeatureLine.d.ts +4 -0
  19. package/esm/BaseFeatureWidget/BaseFeatureDetail/ParentFeatureLine.js +17 -0
  20. package/esm/BaseFeatureWidget/BaseFeatureDetail/SimpleField.d.ts +3 -2
  21. package/esm/BaseFeatureWidget/BaseFeatureDetail/SimpleField.js +5 -3
  22. package/esm/BaseFeatureWidget/BaseFeatureDetail/index.d.ts +6 -2
  23. package/esm/BaseFeatureWidget/BaseFeatureDetail/index.js +7 -18
  24. package/esm/BaseFeatureWidget/BaseFeatureDetail/jexlFilterActions.d.ts +16 -0
  25. package/esm/BaseFeatureWidget/BaseFeatureDetail/jexlFilterActions.js +50 -0
  26. package/esm/BaseFeatureWidget/BaseFeatureDetail/util.d.ts +0 -8
  27. package/esm/BaseFeatureWidget/BaseFeatureDetail/util.js +6 -29
  28. package/esm/BaseFeatureWidget/SequenceFeatureDetails/SequenceContents.js +7 -34
  29. package/esm/BaseFeatureWidget/SequenceFeatureDetails/SequenceFeaturePanel.d.ts +2 -2
  30. package/esm/BaseFeatureWidget/SequenceFeatureDetails/SequenceName.js +2 -2
  31. package/esm/BaseFeatureWidget/SequenceFeatureDetails/dialogs/TranscriptSelector.js +3 -1
  32. package/esm/BaseFeatureWidget/SequenceFeatureDetails/model.d.ts +12 -0
  33. package/esm/BaseFeatureWidget/SequenceFeatureDetails/model.js +12 -5
  34. package/esm/BaseFeatureWidget/configSchema.d.ts +1 -1
  35. package/esm/BaseFeatureWidget/formatDetails.d.ts +13 -29
  36. package/esm/BaseFeatureWidget/formatDetails.js +62 -83
  37. package/esm/BaseFeatureWidget/index.d.ts +2 -1
  38. package/esm/BaseFeatureWidget/stateModelFactory.d.ts +42 -29
  39. package/esm/BaseFeatureWidget/stateModelFactory.js +98 -98
  40. package/esm/BaseFeatureWidget/types.d.ts +12 -6
  41. package/esm/BaseFeatureWidget/util.d.ts +0 -10
  42. package/esm/BaseFeatureWidget/util.js +0 -17
  43. package/esm/CorePlugin.js +2 -2
  44. package/esm/PluginLoader.d.ts +24 -13
  45. package/esm/PluginLoader.js +167 -51
  46. package/esm/PluginManager.d.ts +130 -24
  47. package/esm/PluginManager.js +180 -32
  48. package/esm/ReExports/MuiDataGridReExports.d.ts +1 -0
  49. package/esm/ReExports/MuiDataGridReExports.js +2 -2
  50. package/esm/ReExports/coreModules.generated.d.ts +2 -0
  51. package/esm/ReExports/coreModules.generated.js +528 -0
  52. package/esm/ReExports/coreWorkerModules.generated.d.ts +2 -0
  53. package/esm/ReExports/coreWorkerModules.generated.js +488 -0
  54. package/esm/ReExports/frameworkModules.d.ts +2 -0
  55. package/esm/ReExports/frameworkModules.js +68 -0
  56. package/esm/ReExports/frameworkShared.d.ts +12 -0
  57. package/esm/ReExports/frameworkShared.js +16 -0
  58. package/esm/ReExports/frameworkWorkerModules.generated.d.ts +2 -0
  59. package/esm/ReExports/frameworkWorkerModules.generated.js +130 -0
  60. package/esm/ReExports/list.js +527 -79
  61. package/esm/ReExports/modules.d.ts +1 -1
  62. package/esm/ReExports/modules.js +10 -165
  63. package/esm/ReExports/registry.d.ts +1 -0
  64. package/esm/ReExports/registry.js +23 -5
  65. package/esm/ReExports/uiStub.d.ts +3 -0
  66. package/esm/ReExports/uiStub.js +33 -0
  67. package/esm/ReExports/workerModules.d.ts +2 -0
  68. package/esm/ReExports/workerModules.js +11 -0
  69. package/esm/TextSearch/TextSearchManager.d.ts +27 -13
  70. package/esm/TextSearch/TextSearchManager.js +77 -36
  71. package/esm/TextSearch/places.d.ts +12 -0
  72. package/esm/TextSearch/places.js +94 -0
  73. package/esm/assemblyManager/assembly.d.ts +21 -19
  74. package/esm/assemblyManager/assembly.js +28 -26
  75. package/esm/assemblyManager/assemblyAdapters.d.ts +1 -1
  76. package/esm/assemblyManager/assemblyAdapters.js +8 -2
  77. package/esm/assemblyManager/assemblyConfigSchema.d.ts +31 -90
  78. package/esm/assemblyManager/assemblyConfigSchema.js +35 -47
  79. package/esm/assemblyManager/assemblyManager.d.ts +35 -180
  80. package/esm/assemblyManager/assemblyManager.js +47 -51
  81. package/esm/assemblyManager/expandAssemblyConfigShorthand.d.ts +25 -18
  82. package/esm/assemblyManager/expandAssemblyConfigShorthand.js +78 -49
  83. package/esm/assemblyManager/geneticCodes.js +2 -5
  84. package/esm/assemblyManager/getSequenceAdapterConfig.d.ts +10 -0
  85. package/esm/assemblyManager/getSequenceAdapterConfig.js +10 -0
  86. package/esm/assemblyManager/indexAssemblyNames.d.ts +9 -0
  87. package/esm/assemblyManager/indexAssemblyNames.js +22 -0
  88. package/esm/assemblyManager/loadRefNameMap.d.ts +1 -1
  89. package/esm/assemblyManager/loadRefNameMap.js +4 -9
  90. package/esm/assemblyManager/refNameMapKey.d.ts +7 -0
  91. package/esm/assemblyManager/refNameMapKey.js +12 -0
  92. package/esm/checkPlugins.d.ts +2 -0
  93. package/esm/checkPlugins.js +38 -17
  94. package/esm/configuration/bamIndexFields.d.ts +49 -0
  95. package/esm/configuration/bamIndexFields.js +41 -0
  96. package/esm/configuration/configurationSchema.d.ts +101 -71
  97. package/esm/configuration/configurationSchema.js +207 -134
  98. package/esm/configuration/configurationSchemaUnion.d.ts +39 -0
  99. package/esm/configuration/configurationSchemaUnion.js +56 -0
  100. package/esm/configuration/configurationSlot.d.ts +150 -60
  101. package/esm/configuration/configurationSlot.js +103 -75
  102. package/esm/configuration/fillLocations.d.ts +14 -0
  103. package/esm/configuration/fillLocations.js +14 -0
  104. package/esm/configuration/formatAboutConfigSchema.d.ts +7 -21
  105. package/esm/configuration/formatDetailsConfigSchema.d.ts +11 -37
  106. package/esm/configuration/formatDetailsConfigSchema.js +10 -13
  107. package/esm/configuration/fullConfSnapshot.d.ts +4 -19
  108. package/esm/configuration/fullConfSnapshot.js +30 -52
  109. package/esm/configuration/getConf.d.ts +45 -41
  110. package/esm/configuration/getConf.js +111 -44
  111. package/esm/configuration/index.d.ts +24 -11
  112. package/esm/configuration/index.js +15 -7
  113. package/esm/configuration/indexType.d.ts +26 -0
  114. package/esm/configuration/indexType.js +38 -0
  115. package/esm/configuration/mergeFormatCallbacks.d.ts +6 -7
  116. package/esm/configuration/mergeFormatCallbacks.js +13 -10
  117. package/esm/configuration/readConfObject.d.ts +2 -24
  118. package/esm/configuration/readConfObject.js +20 -63
  119. package/esm/configuration/requirements.d.ts +37 -0
  120. package/esm/configuration/requirements.js +88 -0
  121. package/esm/configuration/schemaRegistry.d.ts +32 -15
  122. package/esm/configuration/schemaRegistry.js +33 -35
  123. package/esm/configuration/schemaTypes.d.ts +21 -5
  124. package/esm/configuration/schemaTypes.js +66 -55
  125. package/esm/configuration/slotFacade.d.ts +12 -29
  126. package/esm/configuration/slotFacade.js +44 -23
  127. package/esm/configuration/snapshotPreprocess.d.ts +43 -0
  128. package/esm/configuration/snapshotPreprocess.js +161 -0
  129. package/esm/configuration/tabixIndexFields.d.ts +30 -4
  130. package/esm/configuration/tabixIndexFields.js +21 -4
  131. package/esm/configuration/tabixShorthand.d.ts +34 -17
  132. package/esm/configuration/tabixShorthand.js +49 -22
  133. package/esm/configuration/types.d.ts +182 -43
  134. package/esm/configuration/uriShorthand.d.ts +9 -0
  135. package/esm/configuration/uriShorthand.js +16 -0
  136. package/esm/data_adapters/BaseAdapter/BaseAdapter.d.ts +13 -19
  137. package/esm/data_adapters/BaseAdapter/BaseAdapter.js +12 -19
  138. package/esm/data_adapters/BaseAdapter/BaseFeatureDataAdapter.d.ts +40 -2
  139. package/esm/data_adapters/BaseAdapter/BaseFeatureDataAdapter.js +68 -5
  140. package/esm/data_adapters/BaseAdapter/featureDensity.d.ts +40 -0
  141. package/esm/data_adapters/BaseAdapter/featureDensity.js +31 -0
  142. package/esm/data_adapters/BaseAdapter/index.d.ts +23 -3
  143. package/esm/data_adapters/BaseAdapter/index.js +1 -0
  144. package/esm/data_adapters/BaseAdapter/rowSources.d.ts +37 -0
  145. package/esm/data_adapters/BaseAdapter/rowSources.js +7 -0
  146. package/esm/data_adapters/BaseAdapter/stats.d.ts +33 -1
  147. package/esm/data_adapters/BaseAdapter/stats.js +52 -13
  148. package/esm/data_adapters/BaseAdapter/types.d.ts +8 -12
  149. package/esm/data_adapters/BaseAdapter/zoomRange.d.ts +10 -0
  150. package/esm/data_adapters/CytobandAdapter/CytobandAdapter.js +1 -1
  151. package/esm/data_adapters/CytobandAdapter/configSchema.d.ts +7 -11
  152. package/esm/data_adapters/CytobandAdapter/configSchema.js +3 -17
  153. package/esm/data_adapters/dataAdapterCache.d.ts +19 -2
  154. package/esm/data_adapters/dataAdapterCache.js +44 -10
  155. package/esm/data_adapters/getFeatureAdapter.d.ts +6 -4
  156. package/esm/data_adapters/getFeatureAdapter.js +8 -8
  157. package/esm/data_adapters/getSequenceSubAdapter.d.ts +7 -9
  158. package/esm/data_adapters/getSequenceSubAdapter.js +8 -10
  159. package/esm/pluggableElementTypes/AdapterType.d.ts +8 -8
  160. package/esm/pluggableElementTypes/AdapterType.js +1 -1
  161. package/esm/pluggableElementTypes/DisplayType.d.ts +46 -16
  162. package/esm/pluggableElementTypes/DisplayType.js +22 -12
  163. package/esm/pluggableElementTypes/LazyStateModelElement.d.ts +32 -0
  164. package/esm/pluggableElementTypes/LazyStateModelElement.js +77 -0
  165. package/esm/pluggableElementTypes/PluggableElementBase.d.ts +3 -5
  166. package/esm/pluggableElementTypes/PluggableElementBase.js +3 -5
  167. package/esm/pluggableElementTypes/RpcMethodType.d.ts +11 -1
  168. package/esm/pluggableElementTypes/RpcMethodType.js +25 -9
  169. package/esm/pluggableElementTypes/RpcMethodTypeWithFiltersAndRenameRegions.d.ts +1 -2
  170. package/esm/pluggableElementTypes/TextSearchAdapterType.d.ts +7 -7
  171. package/esm/pluggableElementTypes/ViewType.d.ts +20 -4
  172. package/esm/pluggableElementTypes/ViewType.js +32 -4
  173. package/esm/pluggableElementTypes/addMenuItems.d.ts +3 -2
  174. package/esm/pluggableElementTypes/extendElementType.d.ts +1 -2
  175. package/esm/pluggableElementTypes/extendElementType.js +9 -5
  176. package/esm/pluggableElementTypes/index.d.ts +2 -1
  177. package/esm/pluggableElementTypes/index.js +1 -1
  178. package/esm/pluggableElementTypes/models/BaseConnectionModelFactory.d.ts +19 -9
  179. package/esm/pluggableElementTypes/models/BaseDisplayModel.d.ts +65 -27
  180. package/esm/pluggableElementTypes/models/BaseDisplayModel.js +72 -10
  181. package/esm/pluggableElementTypes/models/BaseTrackModel.d.ts +65 -16
  182. package/esm/pluggableElementTypes/models/BaseTrackModel.js +179 -117
  183. package/esm/pluggableElementTypes/models/BaseViewModel.d.ts +85 -16
  184. package/esm/pluggableElementTypes/models/BaseViewModel.js +53 -10
  185. package/esm/pluggableElementTypes/models/InternetAccountModel.d.ts +26 -16
  186. package/esm/pluggableElementTypes/models/assertDisplayContract.d.ts +15 -11
  187. package/esm/pluggableElementTypes/models/assertDisplayContract.js +25 -32
  188. package/esm/pluggableElementTypes/models/baseConnectionConfig.d.ts +22 -18
  189. package/esm/pluggableElementTypes/models/baseConnectionConfig.js +5 -5
  190. package/esm/pluggableElementTypes/models/baseInternetAccountConfig.d.ts +26 -31
  191. package/esm/pluggableElementTypes/models/baseTrackConfig.d.ts +108 -147
  192. package/esm/pluggableElementTypes/models/baseTrackConfig.js +96 -73
  193. package/esm/pluggableElementTypes/models/components/SaveTrackData.js +4 -6
  194. package/esm/pluggableElementTypes/models/components/fetchTrackData.d.ts +3 -4
  195. package/esm/pluggableElementTypes/models/components/fetchTrackData.js +3 -3
  196. package/esm/pluggableElementTypes/models/expandTrackConfigShorthand.d.ts +23 -13
  197. package/esm/pluggableElementTypes/models/expandTrackConfigShorthand.js +80 -48
  198. package/esm/pluggableElementTypes/models/index.d.ts +2 -3
  199. package/esm/pluggableElementTypes/models/index.js +2 -3
  200. package/esm/pluggableElementTypes/models/migrateTrackConfig.d.ts +15 -1
  201. package/esm/pluggableElementTypes/models/migrateTrackConfig.js +85 -25
  202. package/esm/pluggableElementTypes/models/saveTrackFileTypes/genbank.d.ts +4 -3
  203. package/esm/pluggableElementTypes/models/saveTrackFileTypes/genbank.js +141 -19
  204. package/esm/pluggableElementTypes/models/saveTrackFileTypes/types.d.ts +3 -3
  205. package/esm/pluginDefinitions.d.ts +34 -7
  206. package/esm/pluginDefinitions.js +54 -20
  207. package/esm/rpc/BaseRpcDriver.d.ts +2 -2
  208. package/esm/rpc/BaseRpcDriver.js +25 -30
  209. package/esm/rpc/MainThreadRpcDriver.d.ts +2 -2
  210. package/esm/rpc/MainThreadRpcDriver.js +13 -8
  211. package/esm/rpc/RpcClient.d.ts +18 -6
  212. package/esm/rpc/RpcClient.js +51 -16
  213. package/esm/rpc/RpcManager.d.ts +14 -10
  214. package/esm/rpc/RpcManager.js +11 -1
  215. package/esm/rpc/RpcRegistry.d.ts +40 -7
  216. package/esm/rpc/RpcServer.d.ts +3 -1
  217. package/esm/rpc/RpcServer.js +19 -12
  218. package/esm/rpc/WebWorkerRpcDriver.d.ts +11 -4
  219. package/esm/rpc/WebWorkerRpcDriver.js +64 -68
  220. package/esm/rpc/byteBudget.d.ts +20 -5
  221. package/esm/rpc/byteBudget.js +16 -5
  222. package/esm/rpc/configSchema.d.ts +7 -21
  223. package/esm/rpc/coreRpcMethods.d.ts +4 -0
  224. package/esm/rpc/coreRpcMethods.js +4 -0
  225. package/esm/rpc/methods/CoreGetEncodedFeature.d.ts +13 -0
  226. package/esm/rpc/methods/CoreGetEncodedFeature.js +32 -0
  227. package/esm/rpc/methods/CoreGetEncodedLayers.d.ts +16 -0
  228. package/esm/rpc/methods/CoreGetEncodedLayers.js +59 -0
  229. package/esm/rpc/methods/CoreGetExportData.js +3 -4
  230. package/esm/rpc/methods/CoreGetFeatureDensity.d.ts +11 -0
  231. package/esm/rpc/methods/CoreGetFeatureDensity.js +22 -0
  232. package/esm/rpc/methods/CoreGetFeatures.js +3 -5
  233. package/esm/rpc/methods/CoreGetRefNames.js +2 -12
  234. package/esm/rpc/methods/CoreGetRegionByteEstimate.js +1 -1
  235. package/esm/rpc/methods/CoreGetSequence.js +2 -2
  236. package/esm/rpc/methods/CoreLoadAdapterCode.d.ts +13 -0
  237. package/esm/rpc/methods/CoreLoadAdapterCode.js +16 -0
  238. package/esm/rpc/methods/layerFeatures.d.ts +33 -0
  239. package/esm/rpc/methods/layerFeatures.js +29 -0
  240. package/esm/svg/SvgExport.js +6 -7
  241. package/esm/svg/SvgThemeProviders.d.ts +12 -0
  242. package/esm/svg/SvgThemeProviders.js +15 -0
  243. package/esm/svg/exportViewSvg.d.ts +28 -0
  244. package/esm/svg/exportViewSvg.js +13 -0
  245. package/esm/svg/normalizeSvgMarkup.d.ts +7 -0
  246. package/esm/svg/normalizeSvgMarkup.js +99 -0
  247. package/esm/svg/serializeSvg.d.ts +7 -0
  248. package/esm/svg/serializeSvg.js +11 -0
  249. package/esm/svg/svgId.d.ts +1 -1
  250. package/esm/svg/svgId.js +1 -1
  251. package/esm/svg/svgReady.d.ts +9 -7
  252. package/esm/svg/svgReady.js +8 -7
  253. package/esm/svg/trackNames.d.ts +7 -5
  254. package/esm/svg/trackNames.js +12 -9
  255. package/esm/svg/wrapSvgExport.js +6 -74
  256. package/esm/ui/AddCustomPluginDialog.js +3 -8
  257. package/esm/ui/AppReadyMarker.d.ts +45 -0
  258. package/esm/ui/AppReadyMarker.js +89 -0
  259. package/esm/ui/BaseExportSvgDialog.d.ts +1 -1
  260. package/esm/ui/CascadingMenu.js +181 -104
  261. package/esm/ui/DropDownMenu.js +2 -1
  262. package/esm/ui/ErrorBanner.js +1 -1
  263. package/esm/ui/ErrorBoundary.d.ts +2 -2
  264. package/esm/ui/ErrorMessageStackTraceContents.js +2 -1
  265. package/esm/ui/ErrorMessageStackTraceDialog.js +5 -11
  266. package/esm/ui/ExportSvgDialog.d.ts +1 -1
  267. package/esm/ui/FileDropZone.js +2 -1
  268. package/esm/ui/FileSelector/useInternetAccounts.d.ts +156 -96
  269. package/esm/ui/HoverMenu.d.ts +1 -2
  270. package/esm/ui/HoverMenu.js +6 -3
  271. package/esm/ui/JexlFilterDialog.d.ts +13 -10
  272. package/esm/ui/JexlFilterDialog.js +122 -49
  273. package/esm/ui/JexlFilterRowEditors.d.ts +15 -0
  274. package/esm/ui/JexlFilterRowEditors.js +90 -0
  275. package/esm/ui/LazyBaseTooltip.d.ts +4 -0
  276. package/esm/ui/LazyBaseTooltip.js +9 -0
  277. package/esm/ui/LegendSwatchGlyph.js +26 -21
  278. package/esm/ui/LoadingOverlay.d.ts +14 -0
  279. package/esm/ui/LoadingOverlay.js +4 -2
  280. package/esm/ui/MenuTypes.d.ts +23 -53
  281. package/esm/ui/MenuTypes.js +3 -0
  282. package/esm/ui/MonospaceTextField.d.ts +2 -1
  283. package/esm/ui/MonospaceTextField.js +23 -20
  284. package/esm/ui/PaletteContext.d.ts +10 -5
  285. package/esm/ui/PaletteContext.js +44 -6
  286. package/esm/ui/RefNameAutocomplete/SearchOption.d.ts +13 -0
  287. package/esm/ui/RefNameAutocomplete/SearchOption.js +45 -0
  288. package/esm/ui/RefNameAutocomplete/index.d.ts +1 -2
  289. package/esm/ui/RefNameAutocomplete/index.js +8 -2
  290. package/esm/ui/RefNameAutocomplete/util.d.ts +13 -0
  291. package/esm/ui/RefNameAutocomplete/util.js +42 -1
  292. package/esm/ui/ResizeHandle.d.ts +3 -1
  293. package/esm/ui/ResizeHandle.js +44 -11
  294. package/esm/ui/ScrollChrome.d.ts +13 -0
  295. package/esm/ui/ScrollChrome.js +11 -0
  296. package/esm/ui/ScrollEdgeShadow.d.ts +6 -9
  297. package/esm/ui/ScrollEdgeShadow.js +14 -35
  298. package/esm/ui/ScrollZoomToggle.d.ts +4 -27
  299. package/esm/ui/ScrollZoomToggle.js +34 -51
  300. package/esm/ui/SessionJsonPanel.d.ts +3 -0
  301. package/esm/ui/SessionJsonPanel.js +14 -0
  302. package/esm/ui/SettingsChangesTable.d.ts +1 -0
  303. package/esm/ui/SettingsChangesTable.js +49 -11
  304. package/esm/ui/ShareLinkField.d.ts +1 -3
  305. package/esm/ui/ShareLinkField.js +13 -40
  306. package/esm/ui/SizeSliderRow.d.ts +1 -3
  307. package/esm/ui/SizeSliderRow.js +4 -6
  308. package/esm/ui/SnackbarModel.js +79 -67
  309. package/esm/ui/StatusProgressBar.js +2 -2
  310. package/esm/ui/SvgColorLegend.d.ts +9 -4
  311. package/esm/ui/SvgColorLegend.js +82 -41
  312. package/esm/ui/VerticalScrollbar.d.ts +13 -34
  313. package/esm/ui/VerticalScrollbar.js +29 -83
  314. package/esm/ui/ViewLoadingScreen.d.ts +5 -4
  315. package/esm/ui/ViewLoadingScreen.js +8 -32
  316. package/esm/ui/colorScale.d.ts +92 -0
  317. package/esm/ui/colorScale.js +72 -0
  318. package/esm/ui/colors.d.ts +64 -0
  319. package/esm/ui/colors.js +230 -1
  320. package/esm/ui/hoverBoxStyle.d.ts +14 -2
  321. package/esm/ui/hoverBoxStyle.js +17 -2
  322. package/esm/ui/index.d.ts +12 -12
  323. package/esm/ui/index.js +14 -22
  324. package/esm/ui/launchViewMenu.js +15 -5
  325. package/esm/ui/legendMenuItem.d.ts +10 -32
  326. package/esm/ui/legendMenuItem.js +9 -36
  327. package/esm/ui/legendSpec.d.ts +15 -8
  328. package/esm/ui/legendSpec.js +14 -23
  329. package/esm/ui/makeSizeMenu.d.ts +0 -6
  330. package/esm/ui/makeSizeMenu.js +6 -30
  331. package/esm/ui/measureLegendText.js +1 -1
  332. package/esm/ui/menuItemAdornment.d.ts +9 -20
  333. package/esm/ui/menuItemAdornment.js +10 -32
  334. package/esm/ui/menuItems.d.ts +2 -7
  335. package/esm/ui/menuItems.js +1 -6
  336. package/esm/ui/multiTrackMenuItems.d.ts +6 -0
  337. package/esm/ui/palette.d.ts +118 -116
  338. package/esm/ui/palette.js +114 -75
  339. package/esm/ui/replaceViewAction.d.ts +1 -1
  340. package/esm/ui/replaceViewAction.js +1 -1
  341. package/esm/ui/theme.d.ts +43 -119
  342. package/esm/ui/theme.js +62 -78
  343. package/esm/ui/toggleMenuItems.d.ts +1 -3
  344. package/esm/ui/toggleMenuItems.js +6 -5
  345. package/esm/ui/useAssemblySelection.d.ts +4 -4
  346. package/esm/ui/viewHeaderHeight.d.ts +1 -0
  347. package/esm/ui/viewHeaderHeight.js +1 -0
  348. package/esm/util/Base1DUtils.d.ts +5 -3
  349. package/esm/util/Base1DUtils.js +14 -6
  350. package/esm/util/Base1DViewModel.d.ts +2 -1
  351. package/esm/util/Base1DViewModel.js +3 -2
  352. package/esm/util/SvgCanvas.d.ts +15 -13
  353. package/esm/util/SvgCanvas.js +76 -56
  354. package/esm/util/aborting.d.ts +39 -0
  355. package/esm/util/aborting.js +88 -6
  356. package/esm/util/adapterMetadata.d.ts +1 -1
  357. package/esm/util/adapterMetadata.js +6 -5
  358. package/esm/util/addAndShowTrack.d.ts +2 -5
  359. package/esm/util/addAndShowTrack.js +5 -1
  360. package/esm/util/addRelativeUris.d.ts +17 -5
  361. package/esm/util/addRelativeUris.js +46 -10
  362. package/esm/util/addTrackFromWidget.d.ts +2 -5
  363. package/esm/util/addTrackFromWidget.js +5 -4
  364. package/esm/util/aggregateFieldName.d.ts +10 -0
  365. package/esm/util/aggregateFieldName.js +8 -0
  366. package/esm/util/analytics.js +46 -13
  367. package/esm/util/animationAllowed.d.ts +9 -0
  368. package/esm/util/animationAllowed.js +13 -0
  369. package/esm/util/applyRowResizeWheel.d.ts +10 -5
  370. package/esm/util/applyRowResizeWheel.js +10 -21
  371. package/esm/util/bandHeight.d.ts +10 -0
  372. package/esm/util/bandHeight.js +29 -0
  373. package/esm/util/bandLayout.d.ts +4 -4
  374. package/esm/util/bandLayout.js +4 -4
  375. package/esm/util/bezierConnector.d.ts +4 -3
  376. package/esm/util/bezierConnector.js +38 -45
  377. package/esm/util/bgzfWorkerPool.d.ts +20 -74
  378. package/esm/util/bgzfWorkerPool.js +20 -74
  379. package/esm/util/binnedAggregate.d.ts +17 -0
  380. package/esm/util/binnedAggregate.js +275 -0
  381. package/esm/util/cacheBudgets.d.ts +22 -19
  382. package/esm/util/cacheBudgets.js +22 -19
  383. package/esm/util/cachedSetup.d.ts +1 -1
  384. package/esm/util/cachedSetup.js +2 -2
  385. package/esm/util/categoricalField.d.ts +56 -0
  386. package/esm/util/categoricalField.js +73 -0
  387. package/esm/util/clampToContig.d.ts +17 -0
  388. package/esm/util/clampToContig.js +19 -0
  389. package/esm/util/coarseStripHTML.js +1 -2
  390. package/esm/util/color/cssColorsLevel4.d.ts +1 -0
  391. package/esm/util/color/cssColorsLevel4.js +1 -0
  392. package/esm/util/color/index.d.ts +5 -3
  393. package/esm/util/color/index.js +7 -4
  394. package/esm/util/colorBits.d.ts +3 -3
  395. package/esm/util/colorBits.js +19 -44
  396. package/esm/util/colorRamp.d.ts +49 -5
  397. package/esm/util/colorRamp.js +169 -18
  398. package/esm/util/colorScale.d.ts +156 -0
  399. package/esm/util/colorScale.js +243 -0
  400. package/esm/util/colorSchemes.d.ts +21 -0
  401. package/esm/util/colorSchemes.js +30 -0
  402. package/esm/util/{createStopTokenRotation.d.ts → createAbortRotation.d.ts} +21 -23
  403. package/esm/util/{createStopTokenRotation.js → createAbortRotation.js} +21 -52
  404. package/esm/util/createSvgRasterCanvas.d.ts +10 -0
  405. package/esm/util/cssColorParse.d.ts +15 -0
  406. package/esm/util/cssColorParse.js +53 -0
  407. package/esm/util/diagonalizeRegions.d.ts +2 -3
  408. package/esm/util/diagonalizeRegions.js +8 -13
  409. package/esm/util/expandLooseSearchIndex.d.ts +19 -0
  410. package/esm/util/expandLooseSearchIndex.js +29 -0
  411. package/esm/util/featureTable.d.ts +224 -0
  412. package/esm/util/featureTable.js +366 -0
  413. package/esm/util/featureTransforms.d.ts +80 -0
  414. package/esm/util/featureTransforms.js +1579 -0
  415. package/esm/util/featureTypes.d.ts +24 -0
  416. package/esm/util/featureTypes.js +35 -0
  417. package/esm/util/fetchAndMaybeUnzip.js +16 -9
  418. package/esm/util/fetchContext.d.ts +7 -8
  419. package/esm/util/fetchContext.js +3 -3
  420. package/esm/util/fetchHub.d.ts +4 -2
  421. package/esm/util/fetchHub.js +2 -2
  422. package/esm/util/fetchPhases.d.ts +10 -10
  423. package/esm/util/fetchSeq.d.ts +2 -3
  424. package/esm/util/fetchSeq.js +2 -2
  425. package/esm/util/fieldReader.d.ts +17 -0
  426. package/esm/util/fieldReader.js +62 -0
  427. package/esm/util/freezeDeep.d.ts +8 -10
  428. package/esm/util/freezeDeep.js +8 -10
  429. package/esm/util/groupKeys.d.ts +77 -0
  430. package/esm/util/groupKeys.js +155 -0
  431. package/esm/util/highlights.d.ts +10 -6
  432. package/esm/util/highlights.js +12 -25
  433. package/esm/util/hooks.d.ts +31 -2
  434. package/esm/util/hooks.js +72 -3
  435. package/esm/util/index.d.ts +11 -11
  436. package/esm/util/index.js +11 -10
  437. package/esm/util/indexCandidates.d.ts +1 -31
  438. package/esm/util/indexCandidates.js +5 -63
  439. package/esm/util/installFetch.d.ts +77 -37
  440. package/esm/util/installFetch.js +65 -38
  441. package/esm/util/installInitAutorun.d.ts +14 -13
  442. package/esm/util/installInitAutorun.js +17 -17
  443. package/esm/util/installPrerequisiteFetch.d.ts +115 -0
  444. package/esm/util/installPrerequisiteFetch.js +111 -0
  445. package/esm/util/io/index.js +19 -14
  446. package/esm/util/isDataCurrent.d.ts +7 -5
  447. package/esm/util/isDataCurrent.js +9 -6
  448. package/esm/util/isTextEntryFocused.d.ts +7 -0
  449. package/esm/util/isTextEntryFocused.js +16 -0
  450. package/esm/util/jexl.js +24 -21
  451. package/esm/util/jexlFilterRows.d.ts +89 -0
  452. package/esm/util/jexlFilterRows.js +252 -0
  453. package/esm/util/jexlFilters.d.ts +20 -27
  454. package/esm/util/jexlFilters.js +23 -11
  455. package/esm/util/jexlStrings.d.ts +3 -4
  456. package/esm/util/jexlStrings.js +2 -3
  457. package/esm/util/layouts/GranularRectLayout.d.ts +8 -1
  458. package/esm/util/layouts/GranularRectLayout.js +25 -8
  459. package/esm/util/lazyAfterAttach.d.ts +13 -0
  460. package/esm/util/lazyAfterAttach.js +31 -0
  461. package/esm/util/lazyWithPreload.d.ts +19 -0
  462. package/esm/util/lazyWithPreload.js +27 -0
  463. package/esm/util/legendCandidates.d.ts +72 -0
  464. package/esm/util/legendCandidates.js +138 -0
  465. package/esm/util/localStorage.js +4 -4
  466. package/esm/util/markEncoding.d.ts +150 -0
  467. package/esm/util/markEncoding.js +845 -0
  468. package/esm/util/markEncodingTypes.d.ts +588 -0
  469. package/esm/util/markEncodingTypes.js +8 -0
  470. package/esm/util/mst-reflection.d.ts +2 -20
  471. package/esm/util/mst-reflection.js +3 -53
  472. package/esm/util/mstUtils.d.ts +31 -23
  473. package/esm/util/mstUtils.js +39 -24
  474. package/esm/util/numericUtils.d.ts +7 -0
  475. package/esm/util/numericUtils.js +16 -0
  476. package/esm/util/numericValue.d.ts +14 -0
  477. package/esm/util/numericValue.js +34 -0
  478. package/esm/util/openFeatureWidget.d.ts +5 -0
  479. package/esm/util/openFeatureWidget.js +2 -2
  480. package/esm/util/openViews.d.ts +17 -0
  481. package/esm/util/openViews.js +22 -0
  482. package/esm/util/parentWalk.d.ts +1 -1
  483. package/esm/util/parentWalk.js +1 -1
  484. package/esm/util/parseLineByLine.d.ts +4 -5
  485. package/esm/util/parseLineByLine.js +8 -14
  486. package/esm/util/pluginStore.d.ts +6 -8
  487. package/esm/util/pluginStore.js +17 -16
  488. package/esm/util/preloadComponent.d.ts +5 -0
  489. package/esm/util/preloadComponent.js +11 -0
  490. package/esm/util/progress.d.ts +22 -22
  491. package/esm/util/progress.js +27 -26
  492. package/esm/util/quantileExtent.d.ts +49 -0
  493. package/esm/util/quantileExtent.js +162 -0
  494. package/esm/util/range.d.ts +13 -9
  495. package/esm/util/range.js +17 -8
  496. package/esm/util/renameRegions.d.ts +26 -6
  497. package/esm/util/renameRegions.js +68 -54
  498. package/esm/util/renderToStaticMarkup.js +24 -14
  499. package/esm/util/rxjs.d.ts +23 -8
  500. package/esm/util/rxjs.js +61 -15
  501. package/esm/util/samplesTsv.d.ts +49 -0
  502. package/esm/util/samplesTsv.js +86 -0
  503. package/esm/util/scheduleDetachedDestroy.d.ts +18 -0
  504. package/esm/util/scheduleDetachedDestroy.js +24 -0
  505. package/esm/util/scrollLatch.d.ts +1 -0
  506. package/esm/util/scrollLatch.js +8 -0
  507. package/esm/util/selectEncodedFeature.d.ts +16 -0
  508. package/esm/util/selectEncodedFeature.js +34 -0
  509. package/esm/util/sessionSharing.d.ts +7 -5
  510. package/esm/util/sessionSharing.js +23 -23
  511. package/esm/util/shapeNameList.d.ts +2 -0
  512. package/esm/util/shapeNameList.js +6 -0
  513. package/esm/util/shapeNames.d.ts +7 -0
  514. package/esm/util/shapeNames.js +11 -0
  515. package/esm/util/simpleFeature.d.ts +0 -1
  516. package/esm/util/starFusion.d.ts +26 -0
  517. package/esm/util/starFusion.js +37 -0
  518. package/esm/util/stepTables.d.ts +82 -0
  519. package/esm/util/stepTables.js +243 -0
  520. package/esm/util/svAlt.d.ts +145 -0
  521. package/esm/util/svAlt.js +364 -0
  522. package/esm/util/svgColorProps.d.ts +11 -0
  523. package/esm/util/svgColorProps.js +28 -1
  524. package/esm/util/systemColorScheme.d.ts +12 -0
  525. package/esm/util/systemColorScheme.js +27 -0
  526. package/esm/util/tabix.d.ts +13 -8
  527. package/esm/util/tabix.js +17 -12
  528. package/esm/util/thresholdScale.d.ts +91 -0
  529. package/esm/util/thresholdScale.js +166 -0
  530. package/esm/util/timeGate.d.ts +4 -5
  531. package/esm/util/timeGate.js +4 -5
  532. package/esm/util/trackConfigDelta.d.ts +26 -26
  533. package/esm/util/trackConfigDelta.js +63 -47
  534. package/esm/util/tracks.d.ts +121 -40
  535. package/esm/util/tracks.js +497 -112
  536. package/esm/util/translateTranscript.d.ts +44 -0
  537. package/esm/util/translateTranscript.js +102 -0
  538. package/esm/util/types/data.d.ts +0 -2
  539. package/esm/util/types/index.d.ts +121 -22
  540. package/esm/util/types/index.js +9 -0
  541. package/esm/util/types/mst.d.ts +3 -0
  542. package/esm/util/types/mst.js +4 -0
  543. package/esm/util/types/renameIds.d.ts +1 -0
  544. package/esm/util/types/renameIds.js +29 -0
  545. package/esm/util/types/services.d.ts +1 -1
  546. package/esm/util/unknownSnapshotKeys.d.ts +51 -0
  547. package/esm/util/unknownSnapshotKeys.js +82 -0
  548. package/esm/util/useFeatureSequence.js +5 -5
  549. package/esm/util/useFetch.d.ts +3 -4
  550. package/esm/util/useFetch.js +19 -10
  551. package/esm/util/useFetchPlugins.d.ts +6 -2
  552. package/esm/util/useFetchPlugins.js +7 -3
  553. package/esm/util/usePanelVirtualScroll.d.ts +7 -35
  554. package/esm/util/usePanelVirtualScroll.js +9 -36
  555. package/esm/util/useRowVirtualScroll.d.ts +6 -29
  556. package/esm/util/useRowVirtualScroll.js +8 -49
  557. package/esm/util/useVirtualScrollWheel.d.ts +20 -4
  558. package/esm/util/useVirtualScrollWheel.js +40 -74
  559. package/esm/util/viewHighlights.d.ts +3 -0
  560. package/esm/util/viewHighlights.js +5 -0
  561. package/esm/util/viewStatus.d.ts +47 -15
  562. package/esm/util/viewStatus.js +34 -0
  563. package/esm/util/wheelZoom.d.ts +7 -1
  564. package/esm/util/wheelZoom.js +85 -19
  565. package/esm/util/whenViewSettled.d.ts +55 -8
  566. package/esm/util/whenViewSettled.js +56 -7
  567. package/esm/util/withLaunchInput.d.ts +174 -0
  568. package/esm/util/withLaunchInput.js +274 -0
  569. package/package.json +70 -20
  570. package/esm/BaseFeatureWidget/BaseFeatureDetail/Position.d.ts +0 -2
  571. package/esm/BaseFeatureWidget/BaseFeatureDetail/Position.js +0 -8
  572. package/esm/BaseFeatureWidget/BaseFeatureDetail/types.d.ts +0 -8
  573. package/esm/BaseFeatureWidget/SequenceFeatureDetails/test_data/DLGAP3.d.ts +0 -80
  574. package/esm/BaseFeatureWidget/SequenceFeatureDetails/test_data/DLGAP3.js +0 -583
  575. package/esm/BaseFeatureWidget/SequenceFeatureDetails/test_data/NCDN.d.ts +0 -141
  576. package/esm/BaseFeatureWidget/SequenceFeatureDetails/test_data/NCDN.js +0 -1116
  577. package/esm/ReExports/BaseFeatureDetails.d.ts +0 -1
  578. package/esm/ReExports/BaseFeatureDetails.js +0 -10
  579. package/esm/ReExports/index.d.ts +0 -1
  580. package/esm/ReExports/index.js +0 -1
  581. package/esm/ReExports/publicUtil.d.ts +0 -1
  582. package/esm/ReExports/publicUtil.js +0 -28
  583. package/esm/configuration/promotableDefaults.d.ts +0 -199
  584. package/esm/configuration/promotableDefaults.js +0 -326
  585. package/esm/configuration/promotablePin.d.ts +0 -55
  586. package/esm/configuration/promotablePin.js +0 -1
  587. package/esm/configuration/promotableResolve.d.ts +0 -108
  588. package/esm/configuration/promotableResolve.js +0 -117
  589. package/esm/configuration/promotableSlots.d.ts +0 -12
  590. package/esm/configuration/promotableSlots.js +0 -45
  591. package/esm/configuration/slotShape.d.ts +0 -12
  592. package/esm/configuration/slotShape.js +0 -84
  593. package/esm/pluggableElementTypes/models/HighlightsMixin.d.ts +0 -51
  594. package/esm/pluggableElementTypes/models/HighlightsMixin.js +0 -78
  595. package/esm/ui/PinAdornment.d.ts +0 -5
  596. package/esm/ui/PinAdornment.js +0 -79
  597. package/esm/ui/SvgGradientLegend.d.ts +0 -26
  598. package/esm/ui/SvgGradientLegend.js +0 -26
  599. package/esm/ui/highlightChipReveal.d.ts +0 -32
  600. package/esm/ui/highlightChipReveal.js +0 -39
  601. package/esm/ui/promotableMenuItems.d.ts +0 -19
  602. package/esm/ui/promotableMenuItems.js +0 -89
  603. package/esm/ui/promotablePinCoverage.d.ts +0 -44
  604. package/esm/ui/promotablePinCoverage.js +0 -87
  605. package/esm/util/applyInitSettings.d.ts +0 -79
  606. package/esm/util/applyInitSettings.js +0 -91
  607. package/esm/util/openDisplays.d.ts +0 -23
  608. package/esm/util/openDisplays.js +0 -79
  609. package/esm/util/stopToken.d.ts +0 -211
  610. package/esm/util/stopToken.js +0 -438
  611. /package/esm/{BaseFeatureWidget/BaseFeatureDetail/types.js → data_adapters/BaseAdapter/zoomRange.js} +0 -0
@@ -8,13 +8,16 @@ export { getFileName } from './getFileName.js';
8
8
  // it. `fetchContext.ts` takes it from mstUtils instead, which is what keeps the
9
9
  // configuration schemas this file pulls in out of the fetch harness's graph.
10
10
  export { getRpcSessionId } from './parentWalk.js';
11
- import { getParent, getSnapshot, isStateTreeNode, } from '@jbrowse/mobx-state-tree';
11
+ import { asModelType, getParent, getSnapshot, getType, hasParent, isAlive, isStateTreeNode, } from '@jbrowse/mobx-state-tree';
12
12
  import { observable, runInAction, untracked } from 'mobx';
13
- import { isConfigurationSlot, preProcessSlotValues, readConfObject, } from '../configuration/index.js';
13
+ import { readConfObject } from '../configuration/index.js';
14
+ import { adapterConfigCacheKey } from '../data_adapters/dataAdapterCache.js';
15
+ import { displayCandidates, displayTypesFedBy, } from '../pluggableElementTypes/models/baseTrackConfig.js';
14
16
  import { getFileHandle, storeFileHandle, verifyPermission, } from './fileHandleStore.js';
15
17
  import { getFileName } from './getFileName.js';
16
18
  import { getContainingView, getEnv, getSession, objectHash, } from './mstUtils.js';
17
19
  import { isViewModel } from './types/index.js';
20
+ import { setterOnlyMessage, unknownKeysMessage } from './unknownSnapshotKeys.js';
18
21
  // Deliberately uncached. This used to memoize on a permanent WeakMap keyed by
19
22
  // track, but every caller reads it from inside a reactive getter or autorun: the
20
23
  // memo meant the reaction never subscribed to the config, so editing
@@ -76,12 +79,22 @@ export function isSameAssemblyName(a, b, assemblyManager) {
76
79
  * `ReferenceSequenceTrack` does not — its schema omits the slot deliberately
77
80
  * (see `createReferenceSeqTrackConfig`), because the assembly config holding it
78
81
  * IS its assembly, so the name is read off the parent instead.
82
+ *
83
+ * That makes a sequence track's assembly **positional**, so a copy of one that
84
+ * is not inside its assembly cannot answer at all — and a detached config is
85
+ * what every hydration path produces (`hydrateTrackConfig`, and the working
86
+ * copy a non-admin's edits would go to, ADR-032). `hasParent` is the guard:
87
+ * without it the walk raises MST's "Failed to find the parent" from a helper
88
+ * whose other two failure modes are a plain `undefined`.
79
89
  */
80
90
  function confAssemblyNames(conf) {
81
91
  const trackAssemblyNames = readConfObject(conf, 'assemblyNames');
82
92
  if (trackAssemblyNames) {
83
93
  return trackAssemblyNames;
84
94
  }
95
+ if (!hasParent(conf)) {
96
+ return undefined;
97
+ }
85
98
  const parent = getParent(conf);
86
99
  return 'sequence' in parent
87
100
  ? [readConfObject(parent, 'name')]
@@ -108,6 +121,15 @@ export function getConfAssemblyNames(conf) {
108
121
  export function getConfAssemblyNamesOrNone(conf) {
109
122
  return confAssemblyNames(conf) ?? [];
110
123
  }
124
+ /**
125
+ * The RPC session id a track's own requests go out under, from its config:
126
+ * what `BaseTrackModel.rpcSessionId` computes, for a caller holding no model.
127
+ * A call under any other id lands on another worker, which builds a second
128
+ * copy of the adapter that nothing frees.
129
+ */
130
+ export function getConfRpcSessionId(conf) {
131
+ return adapterConfigCacheKey(readConfObject(conf, 'adapter'));
132
+ }
111
133
  export const UNKNOWN = 'UNKNOWN';
112
134
  export const UNSUPPORTED = 'UNSUPPORTED';
113
135
  let blobMap = {};
@@ -368,8 +390,12 @@ export function guessAdapter(file, index, adapterHint, model) {
368
390
  }
369
391
  export function guessTrackType(adapterType, model, file) {
370
392
  if (model) {
371
- const session = getSession(model);
372
- const trackTypeGuesser = getEnv(session).pluginManager.evaluateExtensionPoint(
393
+ // getEnv(model), not getEnv(getSession(model)): the env is tree-wide, so
394
+ // the session hop only narrowed what may be passed here — a session itself
395
+ // has no session ancestor, so guessAdapter above accepted one and this
396
+ // threw on it
397
+ const { pluginManager } = getEnv(model);
398
+ const trackTypeGuesser = pluginManager.evaluateExtensionPoint(
373
399
  /** #extensionPoint Core-guessTrackTypeForLocation | sync | Guess a track type from a file location */
374
400
  'Core-guessTrackTypeForLocation', () => undefined);
375
401
  const trackType = trackTypeGuesser(adapterType, file);
@@ -391,25 +417,37 @@ export function guessTrackType(adapterType, model, file) {
391
417
  * the caller can ask for a full config instead.
392
418
  */
393
419
  export function guessTrackConf(input, pluginManager, assemblyName) {
394
- const { uri, index, ...extra } = typeof input === 'string' ? { uri: input } : input;
395
- const file = { uri, locationType: 'UriLocation' };
396
- const indexLocation = index
397
- ? { uri: index, locationType: 'UriLocation' }
398
- : undefined;
420
+ const { uri, index, baseUri, ...extra } = typeof input === 'string' ? { uri: input } : input;
421
+ const base = baseUri ? { baseUri } : {};
422
+ return {
423
+ ...guessTrackConfForLocation({ uri, locationType: 'UriLocation', ...base }, index ? { uri: index, locationType: 'UriLocation', ...base } : undefined, pluginManager, assemblyName),
424
+ ...extra,
425
+ };
426
+ }
427
+ /**
428
+ * {@link guessTrackConf} over an already-built {@link FileLocation}, for a
429
+ * caller holding a location the loose `{ uri }` vocabulary cannot spell — a
430
+ * desktop local path. Kept separate so `LooseTrackInput` stays URI-only: it
431
+ * sits on the track-config union and the root config's `tracks`, where a
432
+ * local path would be a config a web deployment could not open.
433
+ *
434
+ * The `trackId` is a content hash of the adapter, not a timestamp, so adding
435
+ * the same file twice is idempotent — `addToSession` dedupes on it.
436
+ */
437
+ export function guessTrackConfForLocation(file, index, pluginManager, assemblyName) {
399
438
  const adapterGuesser = pluginManager.evaluateExtensionPoint('Core-guessAdapterForLocation', () => undefined);
400
- const adapter = adapterGuesser(file, indexLocation, undefined);
439
+ const adapter = adapterGuesser(file, index, undefined);
440
+ const name = getFileName(file);
401
441
  if (!adapter || adapter.type === UNKNOWN) {
402
- throw new Error(`could not infer a track type from "${uri}"; pass a full track config instead`);
442
+ throw new Error(`could not infer a track type from "${name}"; pass a full track config instead`);
403
443
  }
404
444
  const trackTypeGuesser = pluginManager.evaluateExtensionPoint('Core-guessTrackTypeForLocation', () => undefined);
405
- const name = getFileName(file);
406
445
  return {
407
446
  trackId: `${name}-${objectHash(adapter).slice(0, 8)}`,
408
447
  type: trackTypeGuesser(adapter.type, file) ?? 'FeatureTrack',
409
448
  name,
410
449
  assemblyNames: assemblyName ? [assemblyName] : [],
411
450
  adapter,
412
- ...extra,
413
451
  };
414
452
  }
415
453
  /**
@@ -476,27 +514,83 @@ export function getTrackName(conf, session) {
476
514
  : (conf.trackId ?? '');
477
515
  return trackName || trackId;
478
516
  }
479
- /**
480
- * Which display a track opens with in a given view, and the display config that
481
- * display must use: `{ type, conf }`, or undefined when the view supports none
482
- * of the track's displays.
483
- *
484
- * Two decisions, in this order, and the order is the point. The **type** is what
485
- * the caller asked for, else the track's first declared display the view
486
- * supports, else the track type's first supported display. The **config** is
487
- * then whichever declared entry has that type — never "the first supported one",
488
- * which is what let a display be created wearing another display's config node
489
- * (a multi-sample VCF declares both the matrix and the regular display, so the
490
- * regular one inherited the matrix's 20px connector-line zone and drew its
491
- * clustering tree offset from the rows it labels). `display.type ===
492
- * display.configuration.type` is the invariant `DisplayConfigurationReference`
493
- * already assumes when it falls back to resolving a display config by type; this
494
- * is where it has to hold.
495
- *
496
- * `conf` is undefined when the track config declares no entry of that type;
497
- * `baseTrackConfig.preProcessSnapshot` injects one for every registered display
498
- * type, so the caller's `${trackId}-${type}` id resolves to it.
499
- */
517
+ // The first-show path spreads the same settings into the display's `create()`
518
+ // snapshot, so a DECLARED PROP (`resolution` on the wiggle displays) has
519
+ // already landed by the time applyDisplaySettings reports it took no slot.
520
+ // Only a declared prop: MST restores nothing else from a snapshot, so a
521
+ // volatile or a getter of the same name (`scrollTop`) did not land and the
522
+ // caller has to hear about it.
523
+ function didNotLand(unapplied, display) {
524
+ const model = display ? asModelType(getType(display)) : undefined;
525
+ const props = model ? Object.keys(model.properties) : [];
526
+ return unapplied.filter(entry => !props.includes(entry.key));
527
+ }
528
+ function notifySettingsReport(session, trackId, displayType, unapplied, failed) {
529
+ const label = `${displayType} for track "${trackId}"`;
530
+ const keys = (of) => of.map(entry => entry.key);
531
+ const setterOnly = unapplied.filter(e => e.reason === 'setter-only');
532
+ const unknown = unapplied.filter(e => e.reason !== 'setter-only');
533
+ if (unknown.length) {
534
+ session.notifyError(unknownKeysMessage(label, keys(unknown)));
535
+ }
536
+ if (setterOnly.length) {
537
+ session.notifyError(setterOnlyMessage(label, keys(setterOnly)));
538
+ }
539
+ if (failed.length) {
540
+ session.notifyError(`Track "${trackId}" rejected ${failed.map(f => `${f.key}: ${f.error}`).join('; ')}`);
541
+ }
542
+ }
543
+ // The display a shown track switches to for a `type` it is not drawn as.
544
+ function displaySwitch(self, trackId, track, requested) {
545
+ if (requested === undefined) {
546
+ return undefined;
547
+ }
548
+ const { pluginManager } = getEnv(self);
549
+ const type = pluginManager.resolveDisplayTypeRecord(requested)?.name;
550
+ if (type === track.activeDisplay.type) {
551
+ return undefined;
552
+ }
553
+ const target = track.compatibleDisplays.find(d => d.type === type);
554
+ if (!target) {
555
+ const view = isViewModel(self) ? self : getContainingView(self);
556
+ throw new Error(`Track "${trackId}" cannot be shown as "${requested}" in a ${view.type}. It takes: ${track.compatibleDisplays.map(d => d.type).join(', ')}`);
557
+ }
558
+ return target;
559
+ }
560
+ // A switch carries the settings in the new display's snapshot, as a first show
561
+ // does, and hands off to the async launch while that display's state model is
562
+ // still a dynamic import.
563
+ function restyleShown(self, trackId, found, displayInitialSnapshot) {
564
+ const { pluginManager } = getEnv(self);
565
+ const session = getSession(self);
566
+ const track = found;
567
+ const { type, ...settings } = displayInitialSnapshot;
568
+ try {
569
+ const target = displaySwitch(self, trackId, track, type);
570
+ if (target) {
571
+ const record = pluginManager.resolveDisplayTypeRecord(target.type);
572
+ if (record && !record.isStateModelLoaded) {
573
+ void launchTrackGeneric(self, trackId, {}, displayInitialSnapshot);
574
+ return undefined;
575
+ }
576
+ track.replaceDisplay(track.activeDisplay.configuration.displayId, target.displayId, {
577
+ ...track.activeDisplay.getPortableSettings?.(target.displayId),
578
+ ...settings,
579
+ });
580
+ }
581
+ if (Object.keys(settings).length && track.applyDisplaySettings) {
582
+ const report = track.applyDisplaySettings(settings);
583
+ notifySettingsReport(session, trackId, track.activeDisplay.type, target
584
+ ? didNotLand(report.unapplied, track.displays[0])
585
+ : report.unapplied, report.failed);
586
+ }
587
+ return found;
588
+ }
589
+ catch (e) {
590
+ session.notifyError(`${e}`, e);
591
+ return undefined;
592
+ }
593
+ }
500
594
  /**
501
595
  * The display type names a view can render, as a lookup set. Built once per
502
596
  * view and handed to {@link viewCanDisplayTrack} for every track, rather than
@@ -506,17 +600,10 @@ export function viewDisplayNames(pluginManager, viewType) {
506
600
  return new Set(pluginManager.getViewType(viewType).displayTypes.map(d => d.name));
507
601
  }
508
602
  /**
509
- * Whether a view rendering `viewDisplays` can open a track of this type at all
510
- * — does the track type declare a display the view draws. The coarse half of
511
- * the question {@link pickDisplayForView} answers precisely: a picker that
512
- * offers a track this says no to is offering one `showTrackGeneric` will
513
- * refuse.
514
- *
515
- * Reads the *track type's* registered displays rather than a config's own
516
- * `displays` array, which is both cheaper and the only form available on an
517
- * un-hydrated frozen track config (ADR-032). The two agree, since
518
- * `preprocessTrackConfigSnapshot` injects a stub display for every display the
519
- * track type registers.
603
+ * Whether a view rendering `viewDisplays` can open a track at all: does the
604
+ * track's adapter feed a display the view draws. The coarse half of the
605
+ * question {@link pickDisplayForView} answers precisely, over the same
606
+ * candidates, so a picker never offers a track `showTrackGeneric` will refuse.
520
607
  *
521
608
  * Two answers that are easy to get wrong, and both have been:
522
609
  *
@@ -530,20 +617,101 @@ export function viewDisplayNames(pluginManager, viewType) {
530
617
  * every track passes. That is a policy rather than a fact, and it lives here
531
618
  * so the pickers agree on it.
532
619
  */
533
- export function viewCanDisplayTrack(pluginManager, viewDisplays, trackType) {
534
- if (!pluginManager.trackTypes.has(trackType)) {
620
+ export function viewCanDisplayTrack(pluginManager, viewDisplays, track) {
621
+ if (!pluginManager.trackTypes.has(track.type)) {
535
622
  return false;
536
623
  }
537
624
  return (viewDisplays.size === 0 ||
538
- pluginManager
539
- .getTrackType(trackType)
540
- .displayTypes.some(d => viewDisplays.has(d.name)));
625
+ displayTypesFedBy(pluginManager, track.type, track.adapter).some(name => viewDisplays.has(name)));
541
626
  }
542
- export function pickDisplayForView({ declaredDisplays, requestedType, trackDisplayTypes, viewDisplayTypes, }) {
627
+ /**
628
+ * Whether every name in `subset` appears in `superset`. An absent superset
629
+ * contains nothing; an absent subset is contained by anything.
630
+ */
631
+ function containsAll(superset = [], subset = []) {
632
+ const s = new Set(superset);
633
+ return subset.every(x => s.has(x));
634
+ }
635
+ /**
636
+ * The tracks a view can be offered: those that support every assembly it
637
+ * displays, and that declare a display it can draw. The track selector's tree
638
+ * and every other picker that opens a track into a view read this one answer,
639
+ * or one of them offers a track the next hides.
640
+ */
641
+ export function filterTracks(tracks, self) {
642
+ const { view } = self;
643
+ if (!view) {
644
+ return [];
645
+ }
646
+ const { assemblyManager } = getSession(view);
647
+ const { pluginManager } = getEnv(view);
648
+ const canonical = (names) => canonicalAssemblyNames(names, assemblyManager);
649
+ const viewAssemblyNames = canonical(self.assemblyNames);
650
+ const viewDisplays = viewDisplayNames(pluginManager, view.type);
651
+ return tracks.filter(c => {
652
+ const trackAssemblyNames = readConfObject(c, 'assemblyNames');
653
+ return (
654
+ // a view that declares no assemblies (one still initializing) constrains
655
+ // nothing; otherwise the track must cover every one of them
656
+ (viewAssemblyNames.length === 0 ||
657
+ containsAll(trackAssemblyNames && canonical(trackAssemblyNames), viewAssemblyNames)) &&
658
+ viewCanDisplayTrack(pluginManager, viewDisplays, {
659
+ type: c.type,
660
+ adapter: c.adapter,
661
+ }));
662
+ });
663
+ }
664
+ /**
665
+ * The assembly's own sequence track, when the view can draw one. It is in no
666
+ * track list — the config lives on the assembly (see {@link getConfAssemblyNames}
667
+ * on why a sequence track's assembly is positional) — so a picker that walks
668
+ * `session.tracks` alone cannot offer the track most views open first.
669
+ */
670
+ function refSeqTrackConf(assemblyName, view) {
671
+ const { assemblyManager } = getSession(view);
672
+ const { pluginManager } = getEnv(view);
673
+ const conf = assemblyManager.get(assemblyName)?.configuration.sequence;
674
+ // the same display-compatibility question filterTracks asks of every other
675
+ // track, so a view that cannot draw a sequence is not offered one
676
+ return conf &&
677
+ viewCanDisplayTrack(pluginManager, viewDisplayNames(pluginManager, view.type), { type: conf.type, adapter: conf.adapter })
678
+ ? conf
679
+ : undefined;
680
+ }
681
+ /**
682
+ * Every track config a view can be offered, each assembly's sequence track
683
+ * first and then {@link filterTracks} over the list handed in.
684
+ */
685
+ export function offeredTracks(tracks, self) {
686
+ const { view, assemblyNames } = self;
687
+ if (!view) {
688
+ return [];
689
+ }
690
+ return [
691
+ ...assemblyNames.map(name => refSeqTrackConf(name, view)),
692
+ ...filterTracks(tracks, self),
693
+ ].filter(conf => conf !== undefined);
694
+ }
695
+ /**
696
+ * Which display a track opens with in a given view, and the declared entry
697
+ * that configures it: `{ type, conf }`, or undefined when the view draws none
698
+ * of the candidates or the requested type is not among them.
699
+ *
700
+ * The **type** is the requested one, checked rather than taken on faith (an
701
+ * unchecked one resolved its dangling `<trackId>-<type>` id back to the
702
+ * track's default display, and the caller was told it got what it asked for),
703
+ * else the first candidate among the view's own display types, else the first
704
+ * it draws at all. The **config** is then the declared entry of that type,
705
+ * never another one the view supports: `display.type ===
706
+ * display.configuration.type` is the invariant `DisplayConfigurationReference`
707
+ * assumes when it falls back to resolving by type.
708
+ */
709
+ export function pickDisplayForView({ candidates, declaredDisplays, requestedType, viewDisplayTypes, preferredDisplayTypes = new Set(), }) {
543
710
  const supported = new Set(viewDisplayTypes);
544
- const type = requestedType ??
545
- declaredDisplays.find(d => supported.has(d.type))?.type ??
546
- trackDisplayTypes.find(name => supported.has(name));
711
+ const drawable = candidates.filter(name => supported.has(name));
712
+ const type = requestedType === undefined
713
+ ? (drawable.find(name => preferredDisplayTypes.has(name)) ?? drawable[0])
714
+ : drawable.find(name => name === requestedType);
547
715
  return type === undefined
548
716
  ? undefined
549
717
  : { type, conf: declaredDisplays.find(d => d.type === type) };
@@ -572,6 +740,79 @@ export function normalizeTrackInit(t) {
572
740
  };
573
741
  }
574
742
  }
743
+ function resolveTrackDisplayChoice(self, trackId, displayInitialSnapshot, inlineConf) {
744
+ const { pluginManager } = getEnv(self);
745
+ const session = getSession(self);
746
+ // `trackId` seeds the expansion because `guessTrackConf` otherwise
747
+ // synthesizes one from the filename, and the dedupe in the callers and
748
+ // `hideTrackGeneric` both look the track up by the id the caller passed.
749
+ // Only for the loose form: spreading a live MST node (SvInspector's
750
+ // circular track) would flatten it out of the `isStateTreeNode` branch.
751
+ const inlineRawConf = isLooseTrackConfig(inlineConf)
752
+ ? expandLooseTrackConfig({ trackId, ...inlineConf }, pluginManager)
753
+ : inlineConf;
754
+ const rawConf = inlineRawConf ?? session.getTrackById(trackId);
755
+ if (!rawConf) {
756
+ throw new Error(`Could not resolve identifier "${trackId}"`);
757
+ }
758
+ const confSnapshot = structuredClone(isStateTreeNode(rawConf) ? getSnapshot(rawConf) : rawConf);
759
+ // `& { type: string }` because `rawConf` unions a live node with a loose
760
+ // `Record<string, unknown>`, and the node's `type: string` widens back to
761
+ // `unknown` across that union
762
+ const conf = pluginManager.evaluateExtensionPoint('Core-preProcessTrackConfig', confSnapshot);
763
+ const trackType = pluginManager.getTrackType(conf.type);
764
+ // Validate only a conf that is not already in the tree. `configSchema.create`
765
+ // here builds an entire config node and throws it away purely to surface a
766
+ // nice error; its preProcessSnapshot also re-runs Core-preProcessTrackConfig
767
+ // on a snapshot this function just preprocessed. A conf that is a state tree
768
+ // node was validated when MST created it, so all of that is pure waste on
769
+ // the common showTrack path.
770
+ if (!isStateTreeNode(rawConf)) {
771
+ try {
772
+ trackType.configSchema.create(conf, getEnv(self));
773
+ }
774
+ catch (e) {
775
+ throw new Error(`Track "${trackId}" has an invalid configuration: ${e}`, {
776
+ cause: e,
777
+ });
778
+ }
779
+ }
780
+ // A track container that isn't itself a view — a synteny level, which owns
781
+ // a track list but has no width and no registered view type — takes the
782
+ // display choice from the view it sits in, which is the same node
783
+ // getContainingView already resolves to for everything else beneath it.
784
+ const view = isViewModel(self) ? self : getContainingView(self);
785
+ const viewType = pluginManager.getViewType(view.type);
786
+ const candidates = displayCandidates(pluginManager, conf);
787
+ const viewDisplayTypes = viewType.displayTypes.map(d => d.name);
788
+ // Aliases resolve first, so a caller or a config naming a pre-consolidation
789
+ // display type (`LinearPileupDisplay`) reaches the type that replaced it; a
790
+ // name no display answers to stays as written, for the refusal to quote.
791
+ const canonical = (name) => pluginManager.resolveDisplayTypeRecord(name)?.name ?? name;
792
+ const requested = displayInitialSnapshot.type;
793
+ const declaredDisplays = conf.displays ?? [];
794
+ const picked = pickDisplayForView({
795
+ candidates,
796
+ declaredDisplays: declaredDisplays.map(d => ({
797
+ ...d,
798
+ type: canonical(d.type),
799
+ })),
800
+ requestedType: requested === undefined ? undefined : canonical(requested),
801
+ viewDisplayTypes,
802
+ preferredDisplayTypes: new Set(viewType.displayTypes
803
+ .filter(d => d.viewType === view.type)
804
+ .map(d => d.name)),
805
+ });
806
+ if (!picked) {
807
+ const drawable = candidates.filter(name => viewDisplayTypes.includes(name));
808
+ throw new Error(requested === undefined
809
+ ? `Could not find a compatible display for view type ${view.type}`
810
+ : `Track "${trackId}" cannot be shown as "${requested}" in a ${view.type}. ${drawable.length > 0
811
+ ? `It takes: ${drawable.join(', ')}`
812
+ : 'This view draws none of its display types'}`);
813
+ }
814
+ return { rawConf, conf, trackType, picked };
815
+ }
575
816
  export function showTrackGeneric(self, trackId,
576
817
  // `object`, annotated, rather than inferred from the default. A bare `{}`
577
818
  // accepts every non-nullish value, numbers included, which is how a synteny
@@ -591,85 +832,60 @@ inlineConf) {
591
832
  const session = getSession(self);
592
833
  const found = self.tracks.find(t => t.configuration.trackId === trackId);
593
834
  if (found) {
594
- return found;
835
+ return restyleShown(self, trackId, found, displayInitialSnapshot);
595
836
  }
596
837
  // Single choke point for all "open a track" paths — errors surface as
597
838
  // snackbars. Config is validated before the push so the open set never holds
598
839
  // a broken track.
599
840
  try {
600
- const rawConf = (inlineConf && expandLooseTrackConfig(inlineConf, pluginManager)) ??
601
- session.getTrackById(trackId);
602
- if (!rawConf) {
603
- throw new Error(`Could not resolve identifier "${trackId}"`);
604
- }
605
- const confSnapshot = structuredClone(isStateTreeNode(rawConf) ? getSnapshot(rawConf) : rawConf);
606
- const conf = pluginManager.evaluateExtensionPoint('Core-preProcessTrackConfig', confSnapshot);
607
- const trackType = pluginManager.getTrackType(conf.type);
608
- // Validate only a conf that is not already in the tree. `configSchema.create`
609
- // here builds an entire config node and throws it away purely to surface a
610
- // nice error; its preProcessSnapshot also re-runs Core-preProcessTrackConfig
611
- // on a snapshot this function just preprocessed. A conf that is a state tree
612
- // node was validated when MST created it, so all of that is pure waste on
613
- // the common showTrack path.
614
- if (!isStateTreeNode(rawConf)) {
615
- try {
616
- trackType.configSchema.create(conf, getEnv(self));
617
- }
618
- catch (e) {
619
- throw new Error(`Track "${trackId}" has an invalid configuration: ${e}`, { cause: e });
620
- }
621
- }
622
- // A track container that isn't itself a view — a synteny level, which owns
623
- // a track list but has no width and no registered view type — takes the
624
- // display choice from the view it sits in, which is the same node
625
- // getContainingView already resolves to for everything else beneath it.
626
- const view = isViewModel(self) ? self : getContainingView(self);
627
- const viewType = pluginManager.getViewType(view.type);
628
- const picked = pickDisplayForView({
629
- declaredDisplays: conf.displays ?? [],
630
- requestedType: displayInitialSnapshot.type,
631
- trackDisplayTypes: trackType.displayTypes.map(d => d.name),
632
- viewDisplayTypes: viewType.displayTypes.map(d => d.name),
633
- });
634
- if (!picked) {
635
- throw new Error(`Could not find a compatible display for view type ${view.type}`);
636
- }
841
+ const { rawConf, conf, trackType, picked } = resolveTrackDisplayChoice(self, trackId, displayInitialSnapshot, inlineConf);
637
842
  const { type: displayType, conf: displayConf } = picked;
638
843
  const displayId = displayConf?.displayId ?? `${trackId}-${displayType}`;
844
+ // a registered display whose model is not loaded yet: the load re-enters
845
+ // through the view's own showTrack action, so a synchronous caller gets the
846
+ // track a tick late; a caller that needs it back awaits launchTrack
847
+ const displayRecord = pluginManager.resolveDisplayTypeRecord(displayType);
848
+ if (displayRecord && !displayRecord.isStateModelLoaded) {
849
+ void launchTrackGeneric(self, trackId, initialSnapshot, displayInitialSnapshot, inlineConf);
850
+ return undefined;
851
+ }
639
852
  const track = trackType.stateModel.create({
640
853
  ...initialSnapshot,
641
854
  type: conf.type,
642
- configuration: inlineConf ?? trackId,
855
+ // `rawConf`, not the caller's `inlineConf`: the loose `{ trackId, uri }`
856
+ // form has no `type` for the config schema to dispatch on, and the
857
+ // concrete schema this lands on carries no loose preprocessor — that one
858
+ // is on `pluggableConfigSchemaType('track')`, which a track model's
859
+ // `ConfigurationReference` is not. Not `conf` either: that has already
860
+ // run Core-preProcessTrackConfig, which the schema's own
861
+ // preProcessSnapshot runs again.
862
+ configuration: inlineConf ? rawConf : trackId,
643
863
  displays: [
644
864
  {
645
865
  ...displayConf,
646
- type: displayType,
647
866
  configuration: displayId,
648
867
  ...displayInitialSnapshot,
868
+ type: displayType,
649
869
  },
650
870
  ],
651
871
  });
652
872
  self.tracks.push(track);
653
873
  // Display settings (height, color, …) are config slots now, not display
654
874
  // instance props — passed in the display snapshot they'd be dropped as
655
- // unknown MST keys. Route the ones that are real slots onto the persistent
656
- // display config so they take effect and survive hide/retick (#5591). Runs
657
- // after the push so the display's config reference can resolve.
658
- //
659
- // preProcessSlotValues first, so a display schema's shorthand expansions
660
- // and legacy-key migrations reach this path too: a session spec, share
661
- // link, or embed writes slots here rather than creating a config from a
662
- // snapshot, and those two surfaces are meant to speak the same vocabulary.
663
- const display = track.displays[0];
664
- const displaySlots = preProcessSlotValues(display.configuration, displayInitialSnapshot);
665
- for (const [key, value] of Object.entries(displaySlots)) {
666
- if (key !== 'type' && isConfigurationSlot(display.configuration, key)) {
667
- // the key comes from a snapshot at runtime, and setConf's slot name is
668
- // a compile-time type
669
- // eslint-disable-next-line no-restricted-syntax
670
- display.configuration.setSlot(key, value);
671
- }
672
- }
875
+ // unknown MST keys. applyDisplaySettings routes the ones that are real
876
+ // slots onto the persistent display config so they take effect and
877
+ // survive hide/retick (#5591), running the schema's preProcessSnapshot
878
+ // first so shorthand expansions and legacy-key migrations reach this path
879
+ // too — a session spec, share link, or embed writes slots here rather
880
+ // than creating a config from a snapshot, and those surfaces are meant to
881
+ // speak the same vocabulary. Runs after the push so the display's config
882
+ // reference can resolve. Slots only, deliberately: this is the
883
+ // declarative surface, and `allowSetters` stays off so a spec key cannot
884
+ // reach internal display actions.
885
+ const displaySettings = Object.fromEntries(Object.entries(displayInitialSnapshot).filter(([key]) => key !== 'type'));
886
+ const report = track.applyDisplaySettings(displaySettings);
887
+ const drawn = track.displays[0];
888
+ notifySettingsReport(session, trackId, displayType, didNotLand(report.unapplied, drawn), report.failed);
673
889
  // if this track came from a connection, persist its config so it survives
674
890
  // reload without re-establishing the connection (no-op otherwise)
675
891
  session.captureConnectionTrack?.(trackId);
@@ -708,6 +924,137 @@ export function toggleTrackGeneric(self, trackId) {
708
924
  ? false
709
925
  : !!showTrackGeneric(self, trackId);
710
926
  }
927
+ /**
928
+ * Start loading the state model and component of the display a track would
929
+ * open with, without opening it, for a caller that knows the track is coming.
930
+ * Anything that fails here is the launch's to report.
931
+ */
932
+ export function warmTrackDisplayGeneric(self, trackId, displayInitialSnapshot = {}, assemblyName) {
933
+ const { pluginManager } = getEnv(self);
934
+ try {
935
+ const { picked } = resolveTrackDisplayChoice(self, trackId, displayInitialSnapshot);
936
+ pluginManager
937
+ .resolveDisplayTypeRecord(picked.type)
938
+ ?.loadStateModel()
939
+ .catch(() => { });
940
+ warmTrackAdapter(self, trackId, assemblyName);
941
+ }
942
+ catch {
943
+ // the launch reports an unresolvable track
944
+ }
945
+ }
946
+ function adapterTypesIn(value, pluginManager, found = new Set()) {
947
+ if (typeof value === 'object' && value !== null) {
948
+ const { type } = value;
949
+ if (typeof type === 'string' && pluginManager.hasAdapterType(type)) {
950
+ found.add(type);
951
+ }
952
+ for (const child of Object.values(value)) {
953
+ adapterTypesIn(child, pluginManager, found);
954
+ }
955
+ }
956
+ return found;
957
+ }
958
+ /**
959
+ * Load the track's adapter code and read its index in the worker, beside the
960
+ * assembly load the track's first request waits for.
961
+ *
962
+ * Sent under the id the track's own requests will use, so it reaches, and
963
+ * boots, the worker that serves them. That id hashes the adapter config as the
964
+ * track's config node reads it, so a frozen config.json entry is read through a
965
+ * node of its type: its raw adapter snapshot hashes to another worker.
966
+ *
967
+ * `assemblyName` is the one the view is launching on. The track's own
968
+ * `assemblyNames[0]` is not that: a reference-reading adapter is built for the
969
+ * genome its request names, and warming it for the config's first assembly
970
+ * would build an instance the view never reads.
971
+ */
972
+ function declaresLanes(adapterConfig, pluginManager) {
973
+ const { type } = adapterConfig;
974
+ return (typeof type === 'string' &&
975
+ pluginManager.hasAdapterType(type) &&
976
+ pluginManager
977
+ .getAdapterType(type)
978
+ .adapterCapabilities.includes('headerLanes'));
979
+ }
980
+ function warmTrackAdapter(self, trackId, assemblyName) {
981
+ const { pluginManager } = getEnv(self);
982
+ const session = getSession(self);
983
+ const raw = session.getTrackById(trackId);
984
+ const conf = isStateTreeNode(raw)
985
+ ? raw
986
+ : typeof raw?.type === 'string'
987
+ ? pluginManager
988
+ .getTrackType(raw.type)
989
+ .configSchema.create(raw, { pluginManager })
990
+ : undefined;
991
+ if (conf) {
992
+ const adapterConfig = readConfObject(conf, 'adapter');
993
+ const sessionId = getConfRpcSessionId(conf);
994
+ session.rpcManager
995
+ // eslint-disable-next-line no-restricted-syntax -- a code download the track's first request would make anyway: nothing to show, and nothing a user can move on from
996
+ .call(sessionId, 'CoreLoadAdapterCode', {
997
+ adapterTypes: [...adapterTypesIn(adapterConfig, pluginManager)],
998
+ })
999
+ .catch(() => { });
1000
+ // a source that declares its lanes reads an index per lane asked about,
1001
+ // and only its display knows which; asked about none it would read all
1002
+ if (assemblyName && !declaresLanes(adapterConfig, pluginManager)) {
1003
+ session.rpcManager
1004
+ // eslint-disable-next-line no-restricted-syntax -- an index read the track's first request would make anyway: nothing to show, and nothing a user can move on from
1005
+ .call(sessionId, 'CoreGetRefNames', {
1006
+ adapterConfig,
1007
+ assemblyName,
1008
+ signal: undefined,
1009
+ })
1010
+ .catch(() => { });
1011
+ }
1012
+ }
1013
+ }
1014
+ export async function launchTrackGeneric(self, trackId, initialSnapshot = {}, displayInitialSnapshot = {}, inlineConf) {
1015
+ const { pluginManager } = getEnv(self);
1016
+ const session = getSession(self);
1017
+ const found = self.tracks.find(t => t.configuration.trackId === trackId);
1018
+ if (found) {
1019
+ let target;
1020
+ try {
1021
+ target = displaySwitch(self, trackId, found, displayInitialSnapshot.type);
1022
+ if (target) {
1023
+ await pluginManager
1024
+ .resolveDisplayTypeRecord(target.type)
1025
+ ?.loadStateModel();
1026
+ }
1027
+ }
1028
+ catch (e) {
1029
+ session.notifyError(`${e}`, e);
1030
+ return undefined;
1031
+ }
1032
+ if (!target) {
1033
+ return restyleShown(self, trackId, found, displayInitialSnapshot);
1034
+ }
1035
+ return isAlive(self) && isAlive(found)
1036
+ ? self.showTrack?.(trackId, initialSnapshot, displayInitialSnapshot, inlineConf)
1037
+ : undefined;
1038
+ }
1039
+ try {
1040
+ const { picked } = resolveTrackDisplayChoice(self, trackId, displayInitialSnapshot, inlineConf);
1041
+ await pluginManager.resolveDisplayTypeRecord(picked.type)?.loadStateModel();
1042
+ }
1043
+ catch (e) {
1044
+ session.notifyError(`${e}`, e);
1045
+ return undefined;
1046
+ }
1047
+ if (!isAlive(self)) {
1048
+ return undefined;
1049
+ }
1050
+ return self.showTrack?.(trackId, initialSnapshot, displayInitialSnapshot, inlineConf);
1051
+ }
1052
+ // the hide runs in the synchronous prologue, so it keeps action context
1053
+ export async function launchToggleTrackGeneric(self, trackId) {
1054
+ return hideTrackGeneric(self, trackId)
1055
+ ? false
1056
+ : !!(await launchTrackGeneric(self, trackId));
1057
+ }
711
1058
  /**
712
1059
  * Every track config the session can show, connection-supplied ones included.
713
1060
  *
@@ -726,3 +1073,41 @@ export function allSessionTracks(session) {
726
1073
  ? [...session.tracks, ...connectionTracks]
727
1074
  : session.tracks;
728
1075
  }
1076
+ /**
1077
+ * The session's annotation for `assemblyName`, as trackIds: what a view opened
1078
+ * on another genome starts with. Only FeatureTracks, not everything configured
1079
+ * for the assembly — an alignments track turned on behind the user's back
1080
+ * fetches data nobody asked for, and a FeatureTrack over a few kb is one tabix
1081
+ * range query.
1082
+ */
1083
+ export function annotationTrackIds(session, assemblyName) {
1084
+ return allSessionTracks(session).flatMap(track => readConfObject(track, 'type') === 'FeatureTrack' &&
1085
+ readConfObject(track, 'assemblyNames').some(name => isSameAssemblyName(name, assemblyName, session.assemblyManager))
1086
+ ? [readConfObject(track, 'trackId')]
1087
+ : []);
1088
+ }
1089
+ function isNavigableView(view) {
1090
+ return 'navToLocString' in view;
1091
+ }
1092
+ /**
1093
+ * One assembly on its own in a linear genome view, at `loc`. Keyed on `id`:
1094
+ * following several alignments to one genome re-navigates the view rather than
1095
+ * stacking a new one each time.
1096
+ */
1097
+ export async function openAssemblyInLinearView({ session, id, assemblyName, loc, tracks, }) {
1098
+ const view = session.views.find(v => v.id === id);
1099
+ if (view && isNavigableView(view)) {
1100
+ await view.navToLocString(loc, assemblyName);
1101
+ }
1102
+ else {
1103
+ session.addView('LinearGenomeView', {
1104
+ id,
1105
+ assembly: assemblyName,
1106
+ loc,
1107
+ tracks,
1108
+ });
1109
+ }
1110
+ }
1111
+ export function openMateLabel(assemblyName) {
1112
+ return `Open ${assemblyName} at the matching region`;
1113
+ }