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

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