@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.
- package/README.md +1476 -265
- package/esm/BaseFeatureWidget/BaseFeatureDetail/ArrayValue.d.ts +3 -2
- package/esm/BaseFeatureWidget/BaseFeatureDetail/ArrayValue.js +5 -3
- package/esm/BaseFeatureWidget/BaseFeatureDetail/Attributes.d.ts +3 -5
- package/esm/BaseFeatureWidget/BaseFeatureDetail/Attributes.js +34 -29
- package/esm/BaseFeatureWidget/BaseFeatureDetail/BaseCard.js +1 -4
- package/esm/BaseFeatureWidget/BaseFeatureDetail/BasicValue.d.ts +11 -0
- package/esm/BaseFeatureWidget/BaseFeatureDetail/BasicValue.js +16 -9
- package/esm/BaseFeatureWidget/BaseFeatureDetail/CoreDetails.d.ts +1 -1
- package/esm/BaseFeatureWidget/BaseFeatureDetail/CoreDetails.js +15 -31
- package/esm/BaseFeatureWidget/BaseFeatureDetail/FeatureDetails.d.ts +4 -3
- package/esm/BaseFeatureWidget/BaseFeatureDetail/FeatureDetails.js +12 -25
- package/esm/BaseFeatureWidget/BaseFeatureDetail/FeatureDetailsFrame.d.ts +11 -0
- package/esm/BaseFeatureWidget/BaseFeatureDetail/FeatureDetailsFrame.js +11 -0
- package/esm/BaseFeatureWidget/BaseFeatureDetail/FieldActionsButton.d.ts +8 -0
- package/esm/BaseFeatureWidget/BaseFeatureDetail/FieldActionsButton.js +24 -0
- package/esm/BaseFeatureWidget/BaseFeatureDetail/Formatter.js +6 -4
- package/esm/BaseFeatureWidget/BaseFeatureDetail/ParentFeatureLine.d.ts +4 -0
- package/esm/BaseFeatureWidget/BaseFeatureDetail/ParentFeatureLine.js +17 -0
- package/esm/BaseFeatureWidget/BaseFeatureDetail/SimpleField.d.ts +3 -2
- package/esm/BaseFeatureWidget/BaseFeatureDetail/SimpleField.js +5 -3
- package/esm/BaseFeatureWidget/BaseFeatureDetail/index.d.ts +6 -2
- package/esm/BaseFeatureWidget/BaseFeatureDetail/index.js +7 -18
- package/esm/BaseFeatureWidget/BaseFeatureDetail/jexlFilterActions.d.ts +16 -0
- package/esm/BaseFeatureWidget/BaseFeatureDetail/jexlFilterActions.js +50 -0
- package/esm/BaseFeatureWidget/BaseFeatureDetail/util.d.ts +0 -8
- package/esm/BaseFeatureWidget/BaseFeatureDetail/util.js +6 -29
- package/esm/BaseFeatureWidget/SequenceFeatureDetails/SequenceContents.js +7 -34
- package/esm/BaseFeatureWidget/SequenceFeatureDetails/SequenceFeaturePanel.d.ts +2 -2
- package/esm/BaseFeatureWidget/SequenceFeatureDetails/SequenceName.js +2 -2
- package/esm/BaseFeatureWidget/SequenceFeatureDetails/dialogs/TranscriptSelector.js +3 -1
- package/esm/BaseFeatureWidget/SequenceFeatureDetails/model.d.ts +12 -0
- package/esm/BaseFeatureWidget/SequenceFeatureDetails/model.js +12 -5
- package/esm/BaseFeatureWidget/configSchema.d.ts +1 -1
- package/esm/BaseFeatureWidget/formatDetails.d.ts +13 -29
- package/esm/BaseFeatureWidget/formatDetails.js +62 -83
- package/esm/BaseFeatureWidget/index.d.ts +2 -1
- package/esm/BaseFeatureWidget/stateModelFactory.d.ts +42 -29
- package/esm/BaseFeatureWidget/stateModelFactory.js +98 -98
- package/esm/BaseFeatureWidget/types.d.ts +12 -6
- package/esm/BaseFeatureWidget/util.d.ts +0 -10
- package/esm/BaseFeatureWidget/util.js +0 -17
- package/esm/CorePlugin.js +2 -2
- package/esm/PluginLoader.d.ts +24 -13
- package/esm/PluginLoader.js +167 -51
- package/esm/PluginManager.d.ts +130 -24
- package/esm/PluginManager.js +180 -32
- package/esm/ReExports/MuiDataGridReExports.d.ts +1 -0
- package/esm/ReExports/MuiDataGridReExports.js +2 -2
- package/esm/ReExports/coreModules.generated.d.ts +2 -0
- package/esm/ReExports/coreModules.generated.js +528 -0
- package/esm/ReExports/coreWorkerModules.generated.d.ts +2 -0
- package/esm/ReExports/coreWorkerModules.generated.js +488 -0
- package/esm/ReExports/frameworkModules.d.ts +2 -0
- package/esm/ReExports/frameworkModules.js +68 -0
- package/esm/ReExports/frameworkShared.d.ts +12 -0
- package/esm/ReExports/frameworkShared.js +16 -0
- package/esm/ReExports/frameworkWorkerModules.generated.d.ts +2 -0
- package/esm/ReExports/frameworkWorkerModules.generated.js +130 -0
- package/esm/ReExports/list.js +527 -79
- package/esm/ReExports/modules.d.ts +1 -1
- package/esm/ReExports/modules.js +10 -165
- package/esm/ReExports/registry.d.ts +1 -0
- package/esm/ReExports/registry.js +23 -5
- package/esm/ReExports/uiStub.d.ts +3 -0
- package/esm/ReExports/uiStub.js +33 -0
- package/esm/ReExports/workerModules.d.ts +2 -0
- package/esm/ReExports/workerModules.js +11 -0
- package/esm/TextSearch/TextSearchManager.d.ts +27 -13
- package/esm/TextSearch/TextSearchManager.js +77 -36
- package/esm/TextSearch/places.d.ts +12 -0
- package/esm/TextSearch/places.js +94 -0
- package/esm/assemblyManager/assembly.d.ts +21 -19
- package/esm/assemblyManager/assembly.js +28 -26
- package/esm/assemblyManager/assemblyAdapters.d.ts +1 -1
- package/esm/assemblyManager/assemblyAdapters.js +8 -2
- package/esm/assemblyManager/assemblyConfigSchema.d.ts +31 -90
- package/esm/assemblyManager/assemblyConfigSchema.js +35 -47
- package/esm/assemblyManager/assemblyManager.d.ts +35 -180
- package/esm/assemblyManager/assemblyManager.js +47 -51
- package/esm/assemblyManager/expandAssemblyConfigShorthand.d.ts +25 -18
- package/esm/assemblyManager/expandAssemblyConfigShorthand.js +78 -49
- package/esm/assemblyManager/geneticCodes.js +2 -5
- package/esm/assemblyManager/getSequenceAdapterConfig.d.ts +10 -0
- package/esm/assemblyManager/getSequenceAdapterConfig.js +10 -0
- package/esm/assemblyManager/indexAssemblyNames.d.ts +9 -0
- package/esm/assemblyManager/indexAssemblyNames.js +22 -0
- package/esm/assemblyManager/loadRefNameMap.d.ts +1 -1
- package/esm/assemblyManager/loadRefNameMap.js +4 -9
- package/esm/assemblyManager/refNameMapKey.d.ts +7 -0
- package/esm/assemblyManager/refNameMapKey.js +12 -0
- package/esm/checkPlugins.d.ts +2 -0
- package/esm/checkPlugins.js +38 -17
- package/esm/configuration/bamIndexFields.d.ts +49 -0
- package/esm/configuration/bamIndexFields.js +41 -0
- package/esm/configuration/configurationSchema.d.ts +101 -71
- package/esm/configuration/configurationSchema.js +207 -134
- package/esm/configuration/configurationSchemaUnion.d.ts +39 -0
- package/esm/configuration/configurationSchemaUnion.js +56 -0
- package/esm/configuration/configurationSlot.d.ts +150 -60
- package/esm/configuration/configurationSlot.js +103 -75
- package/esm/configuration/fillLocations.d.ts +14 -0
- package/esm/configuration/fillLocations.js +14 -0
- package/esm/configuration/formatAboutConfigSchema.d.ts +7 -21
- package/esm/configuration/formatDetailsConfigSchema.d.ts +11 -37
- package/esm/configuration/formatDetailsConfigSchema.js +10 -13
- package/esm/configuration/fullConfSnapshot.d.ts +4 -19
- package/esm/configuration/fullConfSnapshot.js +30 -52
- package/esm/configuration/getConf.d.ts +45 -41
- package/esm/configuration/getConf.js +111 -44
- package/esm/configuration/index.d.ts +24 -11
- package/esm/configuration/index.js +15 -7
- package/esm/configuration/indexType.d.ts +26 -0
- package/esm/configuration/indexType.js +38 -0
- package/esm/configuration/mergeFormatCallbacks.d.ts +6 -7
- package/esm/configuration/mergeFormatCallbacks.js +13 -10
- package/esm/configuration/readConfObject.d.ts +2 -24
- package/esm/configuration/readConfObject.js +20 -63
- package/esm/configuration/requirements.d.ts +37 -0
- package/esm/configuration/requirements.js +88 -0
- package/esm/configuration/schemaRegistry.d.ts +32 -15
- package/esm/configuration/schemaRegistry.js +33 -35
- package/esm/configuration/schemaTypes.d.ts +21 -5
- package/esm/configuration/schemaTypes.js +66 -55
- package/esm/configuration/slotFacade.d.ts +12 -29
- package/esm/configuration/slotFacade.js +44 -23
- package/esm/configuration/snapshotPreprocess.d.ts +43 -0
- package/esm/configuration/snapshotPreprocess.js +161 -0
- package/esm/configuration/tabixIndexFields.d.ts +30 -4
- package/esm/configuration/tabixIndexFields.js +21 -4
- package/esm/configuration/tabixShorthand.d.ts +34 -17
- package/esm/configuration/tabixShorthand.js +49 -22
- package/esm/configuration/types.d.ts +182 -43
- package/esm/configuration/uriShorthand.d.ts +9 -0
- package/esm/configuration/uriShorthand.js +16 -0
- package/esm/data_adapters/BaseAdapter/BaseAdapter.d.ts +13 -19
- package/esm/data_adapters/BaseAdapter/BaseAdapter.js +12 -19
- package/esm/data_adapters/BaseAdapter/BaseFeatureDataAdapter.d.ts +40 -2
- package/esm/data_adapters/BaseAdapter/BaseFeatureDataAdapter.js +68 -5
- package/esm/data_adapters/BaseAdapter/featureDensity.d.ts +40 -0
- package/esm/data_adapters/BaseAdapter/featureDensity.js +31 -0
- package/esm/data_adapters/BaseAdapter/index.d.ts +23 -3
- package/esm/data_adapters/BaseAdapter/index.js +1 -0
- package/esm/data_adapters/BaseAdapter/rowSources.d.ts +37 -0
- package/esm/data_adapters/BaseAdapter/rowSources.js +7 -0
- package/esm/data_adapters/BaseAdapter/stats.d.ts +33 -1
- package/esm/data_adapters/BaseAdapter/stats.js +52 -13
- package/esm/data_adapters/BaseAdapter/types.d.ts +8 -12
- package/esm/data_adapters/BaseAdapter/zoomRange.d.ts +10 -0
- package/esm/data_adapters/CytobandAdapter/CytobandAdapter.js +1 -1
- package/esm/data_adapters/CytobandAdapter/configSchema.d.ts +7 -11
- package/esm/data_adapters/CytobandAdapter/configSchema.js +3 -17
- package/esm/data_adapters/dataAdapterCache.d.ts +19 -2
- package/esm/data_adapters/dataAdapterCache.js +44 -10
- package/esm/data_adapters/getFeatureAdapter.d.ts +6 -4
- package/esm/data_adapters/getFeatureAdapter.js +8 -8
- package/esm/data_adapters/getSequenceSubAdapter.d.ts +7 -9
- package/esm/data_adapters/getSequenceSubAdapter.js +8 -10
- package/esm/pluggableElementTypes/AdapterType.d.ts +8 -8
- package/esm/pluggableElementTypes/AdapterType.js +1 -1
- package/esm/pluggableElementTypes/DisplayType.d.ts +46 -16
- package/esm/pluggableElementTypes/DisplayType.js +22 -12
- package/esm/pluggableElementTypes/LazyStateModelElement.d.ts +32 -0
- package/esm/pluggableElementTypes/LazyStateModelElement.js +77 -0
- package/esm/pluggableElementTypes/PluggableElementBase.d.ts +3 -5
- package/esm/pluggableElementTypes/PluggableElementBase.js +3 -5
- package/esm/pluggableElementTypes/RpcMethodType.d.ts +11 -1
- package/esm/pluggableElementTypes/RpcMethodType.js +25 -9
- package/esm/pluggableElementTypes/RpcMethodTypeWithFiltersAndRenameRegions.d.ts +1 -2
- package/esm/pluggableElementTypes/TextSearchAdapterType.d.ts +7 -7
- package/esm/pluggableElementTypes/ViewType.d.ts +20 -4
- package/esm/pluggableElementTypes/ViewType.js +32 -4
- package/esm/pluggableElementTypes/addMenuItems.d.ts +3 -2
- package/esm/pluggableElementTypes/extendElementType.d.ts +1 -2
- package/esm/pluggableElementTypes/extendElementType.js +9 -5
- package/esm/pluggableElementTypes/index.d.ts +2 -1
- package/esm/pluggableElementTypes/index.js +1 -1
- package/esm/pluggableElementTypes/models/BaseConnectionModelFactory.d.ts +19 -9
- package/esm/pluggableElementTypes/models/BaseDisplayModel.d.ts +65 -27
- package/esm/pluggableElementTypes/models/BaseDisplayModel.js +72 -10
- package/esm/pluggableElementTypes/models/BaseTrackModel.d.ts +65 -16
- package/esm/pluggableElementTypes/models/BaseTrackModel.js +179 -117
- package/esm/pluggableElementTypes/models/BaseViewModel.d.ts +85 -16
- package/esm/pluggableElementTypes/models/BaseViewModel.js +53 -10
- package/esm/pluggableElementTypes/models/InternetAccountModel.d.ts +26 -16
- package/esm/pluggableElementTypes/models/assertDisplayContract.d.ts +15 -11
- package/esm/pluggableElementTypes/models/assertDisplayContract.js +25 -32
- package/esm/pluggableElementTypes/models/baseConnectionConfig.d.ts +22 -18
- package/esm/pluggableElementTypes/models/baseConnectionConfig.js +5 -5
- package/esm/pluggableElementTypes/models/baseInternetAccountConfig.d.ts +26 -31
- package/esm/pluggableElementTypes/models/baseTrackConfig.d.ts +108 -147
- package/esm/pluggableElementTypes/models/baseTrackConfig.js +96 -73
- package/esm/pluggableElementTypes/models/components/SaveTrackData.js +4 -6
- package/esm/pluggableElementTypes/models/components/fetchTrackData.d.ts +3 -4
- package/esm/pluggableElementTypes/models/components/fetchTrackData.js +3 -3
- package/esm/pluggableElementTypes/models/expandTrackConfigShorthand.d.ts +23 -13
- package/esm/pluggableElementTypes/models/expandTrackConfigShorthand.js +80 -48
- package/esm/pluggableElementTypes/models/index.d.ts +2 -3
- package/esm/pluggableElementTypes/models/index.js +2 -3
- package/esm/pluggableElementTypes/models/migrateTrackConfig.d.ts +15 -1
- package/esm/pluggableElementTypes/models/migrateTrackConfig.js +85 -25
- package/esm/pluggableElementTypes/models/saveTrackFileTypes/genbank.d.ts +4 -3
- package/esm/pluggableElementTypes/models/saveTrackFileTypes/genbank.js +141 -19
- package/esm/pluggableElementTypes/models/saveTrackFileTypes/types.d.ts +3 -3
- package/esm/pluginDefinitions.d.ts +34 -7
- package/esm/pluginDefinitions.js +54 -20
- package/esm/rpc/BaseRpcDriver.d.ts +2 -2
- package/esm/rpc/BaseRpcDriver.js +25 -30
- package/esm/rpc/MainThreadRpcDriver.d.ts +2 -2
- package/esm/rpc/MainThreadRpcDriver.js +13 -8
- package/esm/rpc/RpcClient.d.ts +18 -6
- package/esm/rpc/RpcClient.js +51 -16
- package/esm/rpc/RpcManager.d.ts +14 -10
- package/esm/rpc/RpcManager.js +11 -1
- package/esm/rpc/RpcRegistry.d.ts +40 -7
- package/esm/rpc/RpcServer.d.ts +3 -1
- package/esm/rpc/RpcServer.js +19 -12
- package/esm/rpc/WebWorkerRpcDriver.d.ts +11 -4
- package/esm/rpc/WebWorkerRpcDriver.js +64 -68
- package/esm/rpc/byteBudget.d.ts +20 -5
- package/esm/rpc/byteBudget.js +16 -5
- package/esm/rpc/configSchema.d.ts +7 -21
- package/esm/rpc/coreRpcMethods.d.ts +4 -0
- package/esm/rpc/coreRpcMethods.js +4 -0
- package/esm/rpc/methods/CoreGetEncodedFeature.d.ts +13 -0
- package/esm/rpc/methods/CoreGetEncodedFeature.js +32 -0
- package/esm/rpc/methods/CoreGetEncodedLayers.d.ts +16 -0
- package/esm/rpc/methods/CoreGetEncodedLayers.js +59 -0
- package/esm/rpc/methods/CoreGetExportData.js +3 -4
- package/esm/rpc/methods/CoreGetFeatureDensity.d.ts +11 -0
- package/esm/rpc/methods/CoreGetFeatureDensity.js +22 -0
- package/esm/rpc/methods/CoreGetFeatures.js +3 -5
- package/esm/rpc/methods/CoreGetRefNames.js +2 -12
- package/esm/rpc/methods/CoreGetRegionByteEstimate.js +1 -1
- package/esm/rpc/methods/CoreGetSequence.js +2 -2
- package/esm/rpc/methods/CoreLoadAdapterCode.d.ts +13 -0
- package/esm/rpc/methods/CoreLoadAdapterCode.js +16 -0
- package/esm/rpc/methods/layerFeatures.d.ts +33 -0
- package/esm/rpc/methods/layerFeatures.js +29 -0
- package/esm/svg/SvgExport.js +6 -7
- package/esm/svg/SvgThemeProviders.d.ts +12 -0
- package/esm/svg/SvgThemeProviders.js +15 -0
- package/esm/svg/exportViewSvg.d.ts +28 -0
- package/esm/svg/exportViewSvg.js +13 -0
- package/esm/svg/normalizeSvgMarkup.d.ts +7 -0
- package/esm/svg/normalizeSvgMarkup.js +99 -0
- package/esm/svg/serializeSvg.d.ts +7 -0
- package/esm/svg/serializeSvg.js +11 -0
- package/esm/svg/svgId.d.ts +1 -1
- package/esm/svg/svgId.js +1 -1
- package/esm/svg/svgReady.d.ts +9 -7
- package/esm/svg/svgReady.js +8 -7
- package/esm/svg/trackNames.d.ts +7 -5
- package/esm/svg/trackNames.js +12 -9
- package/esm/svg/wrapSvgExport.js +6 -74
- package/esm/ui/AddCustomPluginDialog.js +3 -8
- package/esm/ui/AppReadyMarker.d.ts +45 -0
- package/esm/ui/AppReadyMarker.js +89 -0
- package/esm/ui/BaseExportSvgDialog.d.ts +1 -1
- package/esm/ui/CascadingMenu.js +181 -104
- package/esm/ui/DropDownMenu.js +2 -1
- package/esm/ui/ErrorBanner.js +1 -1
- package/esm/ui/ErrorBoundary.d.ts +2 -2
- package/esm/ui/ErrorMessageStackTraceContents.js +2 -1
- package/esm/ui/ErrorMessageStackTraceDialog.js +5 -11
- package/esm/ui/ExportSvgDialog.d.ts +1 -1
- package/esm/ui/FileDropZone.js +2 -1
- package/esm/ui/FileSelector/useInternetAccounts.d.ts +156 -96
- package/esm/ui/HoverMenu.d.ts +1 -2
- package/esm/ui/HoverMenu.js +6 -3
- package/esm/ui/JexlFilterDialog.d.ts +13 -10
- package/esm/ui/JexlFilterDialog.js +122 -49
- package/esm/ui/JexlFilterRowEditors.d.ts +15 -0
- package/esm/ui/JexlFilterRowEditors.js +90 -0
- package/esm/ui/LazyBaseTooltip.d.ts +4 -0
- package/esm/ui/LazyBaseTooltip.js +9 -0
- package/esm/ui/LegendSwatchGlyph.js +26 -21
- package/esm/ui/LoadingOverlay.d.ts +14 -0
- package/esm/ui/LoadingOverlay.js +4 -2
- package/esm/ui/MenuTypes.d.ts +23 -53
- package/esm/ui/MenuTypes.js +3 -0
- package/esm/ui/MonospaceTextField.d.ts +2 -1
- package/esm/ui/MonospaceTextField.js +23 -20
- package/esm/ui/PaletteContext.d.ts +10 -5
- package/esm/ui/PaletteContext.js +44 -6
- package/esm/ui/RefNameAutocomplete/SearchOption.d.ts +13 -0
- package/esm/ui/RefNameAutocomplete/SearchOption.js +45 -0
- package/esm/ui/RefNameAutocomplete/index.d.ts +1 -2
- package/esm/ui/RefNameAutocomplete/index.js +8 -2
- package/esm/ui/RefNameAutocomplete/util.d.ts +13 -0
- package/esm/ui/RefNameAutocomplete/util.js +42 -1
- package/esm/ui/ResizeHandle.d.ts +3 -1
- package/esm/ui/ResizeHandle.js +44 -11
- package/esm/ui/ScrollChrome.d.ts +13 -0
- package/esm/ui/ScrollChrome.js +11 -0
- package/esm/ui/ScrollEdgeShadow.d.ts +6 -9
- package/esm/ui/ScrollEdgeShadow.js +14 -35
- package/esm/ui/ScrollZoomToggle.d.ts +4 -27
- package/esm/ui/ScrollZoomToggle.js +34 -51
- package/esm/ui/SessionJsonPanel.d.ts +3 -0
- package/esm/ui/SessionJsonPanel.js +14 -0
- package/esm/ui/SettingsChangesTable.d.ts +1 -0
- package/esm/ui/SettingsChangesTable.js +49 -11
- package/esm/ui/ShareLinkField.d.ts +1 -3
- package/esm/ui/ShareLinkField.js +13 -40
- package/esm/ui/SizeSliderRow.d.ts +1 -3
- package/esm/ui/SizeSliderRow.js +4 -6
- package/esm/ui/SnackbarModel.js +79 -67
- package/esm/ui/StatusProgressBar.js +2 -2
- package/esm/ui/SvgColorLegend.d.ts +9 -4
- package/esm/ui/SvgColorLegend.js +82 -41
- package/esm/ui/VerticalScrollbar.d.ts +13 -34
- package/esm/ui/VerticalScrollbar.js +29 -83
- package/esm/ui/ViewLoadingScreen.d.ts +5 -4
- package/esm/ui/ViewLoadingScreen.js +8 -32
- package/esm/ui/colorScale.d.ts +92 -0
- package/esm/ui/colorScale.js +72 -0
- package/esm/ui/colors.d.ts +64 -0
- package/esm/ui/colors.js +230 -1
- package/esm/ui/hoverBoxStyle.d.ts +14 -2
- package/esm/ui/hoverBoxStyle.js +17 -2
- package/esm/ui/index.d.ts +12 -12
- package/esm/ui/index.js +14 -22
- package/esm/ui/launchViewMenu.js +15 -5
- package/esm/ui/legendMenuItem.d.ts +10 -32
- package/esm/ui/legendMenuItem.js +9 -36
- package/esm/ui/legendSpec.d.ts +15 -8
- package/esm/ui/legendSpec.js +14 -23
- package/esm/ui/makeSizeMenu.d.ts +0 -6
- package/esm/ui/makeSizeMenu.js +6 -30
- package/esm/ui/measureLegendText.js +1 -1
- package/esm/ui/menuItemAdornment.d.ts +9 -20
- package/esm/ui/menuItemAdornment.js +10 -32
- package/esm/ui/menuItems.d.ts +2 -7
- package/esm/ui/menuItems.js +1 -6
- package/esm/ui/multiTrackMenuItems.d.ts +6 -0
- package/esm/ui/palette.d.ts +118 -116
- package/esm/ui/palette.js +114 -75
- package/esm/ui/replaceViewAction.d.ts +1 -1
- package/esm/ui/replaceViewAction.js +1 -1
- package/esm/ui/theme.d.ts +43 -119
- package/esm/ui/theme.js +62 -78
- package/esm/ui/toggleMenuItems.d.ts +1 -3
- package/esm/ui/toggleMenuItems.js +6 -5
- package/esm/ui/useAssemblySelection.d.ts +4 -4
- package/esm/ui/viewHeaderHeight.d.ts +1 -0
- package/esm/ui/viewHeaderHeight.js +1 -0
- package/esm/util/Base1DUtils.d.ts +5 -3
- package/esm/util/Base1DUtils.js +14 -6
- package/esm/util/Base1DViewModel.d.ts +2 -1
- package/esm/util/Base1DViewModel.js +3 -2
- package/esm/util/SvgCanvas.d.ts +15 -13
- package/esm/util/SvgCanvas.js +76 -56
- package/esm/util/aborting.d.ts +39 -0
- package/esm/util/aborting.js +88 -6
- package/esm/util/adapterMetadata.d.ts +1 -1
- package/esm/util/adapterMetadata.js +6 -5
- package/esm/util/addAndShowTrack.d.ts +2 -5
- package/esm/util/addAndShowTrack.js +5 -1
- package/esm/util/addRelativeUris.d.ts +17 -5
- package/esm/util/addRelativeUris.js +46 -10
- package/esm/util/addTrackFromWidget.d.ts +2 -5
- package/esm/util/addTrackFromWidget.js +5 -4
- package/esm/util/aggregateFieldName.d.ts +10 -0
- package/esm/util/aggregateFieldName.js +8 -0
- package/esm/util/analytics.js +46 -13
- package/esm/util/animationAllowed.d.ts +9 -0
- package/esm/util/animationAllowed.js +13 -0
- package/esm/util/applyRowResizeWheel.d.ts +10 -5
- package/esm/util/applyRowResizeWheel.js +10 -21
- package/esm/util/bandHeight.d.ts +10 -0
- package/esm/util/bandHeight.js +29 -0
- package/esm/util/bandLayout.d.ts +4 -4
- package/esm/util/bandLayout.js +4 -4
- package/esm/util/bezierConnector.d.ts +4 -3
- package/esm/util/bezierConnector.js +38 -45
- package/esm/util/bgzfWorkerPool.d.ts +20 -74
- package/esm/util/bgzfWorkerPool.js +20 -74
- package/esm/util/binnedAggregate.d.ts +17 -0
- package/esm/util/binnedAggregate.js +275 -0
- package/esm/util/cacheBudgets.d.ts +22 -19
- package/esm/util/cacheBudgets.js +22 -19
- package/esm/util/cachedSetup.d.ts +1 -1
- package/esm/util/cachedSetup.js +2 -2
- package/esm/util/categoricalField.d.ts +56 -0
- package/esm/util/categoricalField.js +73 -0
- package/esm/util/clampToContig.d.ts +17 -0
- package/esm/util/clampToContig.js +19 -0
- package/esm/util/coarseStripHTML.js +1 -2
- package/esm/util/color/cssColorsLevel4.d.ts +1 -0
- package/esm/util/color/cssColorsLevel4.js +1 -0
- package/esm/util/color/index.d.ts +5 -3
- package/esm/util/color/index.js +7 -4
- package/esm/util/colorBits.d.ts +3 -3
- package/esm/util/colorBits.js +19 -44
- package/esm/util/colorRamp.d.ts +49 -5
- package/esm/util/colorRamp.js +169 -18
- package/esm/util/colorScale.d.ts +156 -0
- package/esm/util/colorScale.js +243 -0
- package/esm/util/colorSchemes.d.ts +21 -0
- package/esm/util/colorSchemes.js +30 -0
- package/esm/util/{createStopTokenRotation.d.ts → createAbortRotation.d.ts} +21 -23
- package/esm/util/{createStopTokenRotation.js → createAbortRotation.js} +21 -52
- package/esm/util/createSvgRasterCanvas.d.ts +10 -0
- package/esm/util/cssColorParse.d.ts +15 -0
- package/esm/util/cssColorParse.js +53 -0
- package/esm/util/diagonalizeRegions.d.ts +2 -3
- package/esm/util/diagonalizeRegions.js +8 -13
- package/esm/util/expandLooseSearchIndex.d.ts +19 -0
- package/esm/util/expandLooseSearchIndex.js +29 -0
- package/esm/util/featureTable.d.ts +224 -0
- package/esm/util/featureTable.js +366 -0
- package/esm/util/featureTransforms.d.ts +80 -0
- package/esm/util/featureTransforms.js +1579 -0
- package/esm/util/featureTypes.d.ts +24 -0
- package/esm/util/featureTypes.js +35 -0
- package/esm/util/fetchAndMaybeUnzip.js +16 -9
- package/esm/util/fetchContext.d.ts +7 -8
- package/esm/util/fetchContext.js +3 -3
- package/esm/util/fetchHub.d.ts +4 -2
- package/esm/util/fetchHub.js +2 -2
- package/esm/util/fetchPhases.d.ts +10 -10
- package/esm/util/fetchSeq.d.ts +2 -3
- package/esm/util/fetchSeq.js +2 -2
- package/esm/util/fieldReader.d.ts +17 -0
- package/esm/util/fieldReader.js +62 -0
- package/esm/util/freezeDeep.d.ts +8 -10
- package/esm/util/freezeDeep.js +8 -10
- package/esm/util/groupKeys.d.ts +77 -0
- package/esm/util/groupKeys.js +155 -0
- package/esm/util/highlights.d.ts +10 -6
- package/esm/util/highlights.js +12 -25
- package/esm/util/hooks.d.ts +31 -2
- package/esm/util/hooks.js +72 -3
- package/esm/util/index.d.ts +11 -11
- package/esm/util/index.js +11 -10
- package/esm/util/indexCandidates.d.ts +1 -31
- package/esm/util/indexCandidates.js +5 -63
- package/esm/util/installFetch.d.ts +77 -37
- package/esm/util/installFetch.js +65 -38
- package/esm/util/installInitAutorun.d.ts +14 -13
- package/esm/util/installInitAutorun.js +17 -17
- package/esm/util/installPrerequisiteFetch.d.ts +115 -0
- package/esm/util/installPrerequisiteFetch.js +111 -0
- package/esm/util/io/index.js +19 -14
- package/esm/util/isDataCurrent.d.ts +7 -5
- package/esm/util/isDataCurrent.js +9 -6
- package/esm/util/isTextEntryFocused.d.ts +7 -0
- package/esm/util/isTextEntryFocused.js +16 -0
- package/esm/util/jexl.js +24 -21
- package/esm/util/jexlFilterRows.d.ts +89 -0
- package/esm/util/jexlFilterRows.js +252 -0
- package/esm/util/jexlFilters.d.ts +20 -27
- package/esm/util/jexlFilters.js +23 -11
- package/esm/util/jexlStrings.d.ts +3 -4
- package/esm/util/jexlStrings.js +2 -3
- package/esm/util/layouts/GranularRectLayout.d.ts +8 -1
- package/esm/util/layouts/GranularRectLayout.js +25 -8
- package/esm/util/lazyAfterAttach.d.ts +13 -0
- package/esm/util/lazyAfterAttach.js +31 -0
- package/esm/util/lazyWithPreload.d.ts +19 -0
- package/esm/util/lazyWithPreload.js +27 -0
- package/esm/util/legendCandidates.d.ts +72 -0
- package/esm/util/legendCandidates.js +138 -0
- package/esm/util/localStorage.js +4 -4
- package/esm/util/markEncoding.d.ts +150 -0
- package/esm/util/markEncoding.js +845 -0
- package/esm/util/markEncodingTypes.d.ts +588 -0
- package/esm/util/markEncodingTypes.js +8 -0
- package/esm/util/mst-reflection.d.ts +2 -20
- package/esm/util/mst-reflection.js +3 -53
- package/esm/util/mstUtils.d.ts +31 -23
- package/esm/util/mstUtils.js +39 -24
- package/esm/util/numericUtils.d.ts +7 -0
- package/esm/util/numericUtils.js +16 -0
- package/esm/util/numericValue.d.ts +14 -0
- package/esm/util/numericValue.js +34 -0
- package/esm/util/openFeatureWidget.d.ts +5 -0
- package/esm/util/openFeatureWidget.js +2 -2
- package/esm/util/openViews.d.ts +17 -0
- package/esm/util/openViews.js +22 -0
- package/esm/util/parentWalk.d.ts +1 -1
- package/esm/util/parentWalk.js +1 -1
- package/esm/util/parseLineByLine.d.ts +4 -5
- package/esm/util/parseLineByLine.js +8 -14
- package/esm/util/pluginStore.d.ts +6 -8
- package/esm/util/pluginStore.js +17 -16
- package/esm/util/preloadComponent.d.ts +5 -0
- package/esm/util/preloadComponent.js +11 -0
- package/esm/util/progress.d.ts +22 -22
- package/esm/util/progress.js +27 -26
- package/esm/util/quantileExtent.d.ts +49 -0
- package/esm/util/quantileExtent.js +162 -0
- package/esm/util/range.d.ts +13 -9
- package/esm/util/range.js +17 -8
- package/esm/util/renameRegions.d.ts +26 -6
- package/esm/util/renameRegions.js +68 -54
- package/esm/util/renderToStaticMarkup.js +24 -14
- package/esm/util/rxjs.d.ts +23 -8
- package/esm/util/rxjs.js +61 -15
- package/esm/util/samplesTsv.d.ts +49 -0
- package/esm/util/samplesTsv.js +86 -0
- package/esm/util/scheduleDetachedDestroy.d.ts +18 -0
- package/esm/util/scheduleDetachedDestroy.js +24 -0
- package/esm/util/scrollLatch.d.ts +1 -0
- package/esm/util/scrollLatch.js +8 -0
- package/esm/util/selectEncodedFeature.d.ts +16 -0
- package/esm/util/selectEncodedFeature.js +34 -0
- package/esm/util/sessionSharing.d.ts +7 -5
- package/esm/util/sessionSharing.js +23 -23
- package/esm/util/shapeNameList.d.ts +2 -0
- package/esm/util/shapeNameList.js +6 -0
- package/esm/util/shapeNames.d.ts +7 -0
- package/esm/util/shapeNames.js +11 -0
- package/esm/util/simpleFeature.d.ts +0 -1
- package/esm/util/starFusion.d.ts +26 -0
- package/esm/util/starFusion.js +37 -0
- package/esm/util/stepTables.d.ts +82 -0
- package/esm/util/stepTables.js +243 -0
- package/esm/util/svAlt.d.ts +145 -0
- package/esm/util/svAlt.js +364 -0
- package/esm/util/svgColorProps.d.ts +11 -0
- package/esm/util/svgColorProps.js +28 -1
- package/esm/util/systemColorScheme.d.ts +12 -0
- package/esm/util/systemColorScheme.js +27 -0
- package/esm/util/tabix.d.ts +13 -8
- package/esm/util/tabix.js +17 -12
- package/esm/util/thresholdScale.d.ts +91 -0
- package/esm/util/thresholdScale.js +166 -0
- package/esm/util/timeGate.d.ts +4 -5
- package/esm/util/timeGate.js +4 -5
- package/esm/util/trackConfigDelta.d.ts +26 -26
- package/esm/util/trackConfigDelta.js +63 -47
- package/esm/util/tracks.d.ts +121 -40
- package/esm/util/tracks.js +497 -112
- package/esm/util/translateTranscript.d.ts +44 -0
- package/esm/util/translateTranscript.js +102 -0
- package/esm/util/types/data.d.ts +0 -2
- package/esm/util/types/index.d.ts +121 -22
- package/esm/util/types/index.js +9 -0
- package/esm/util/types/mst.d.ts +3 -0
- package/esm/util/types/mst.js +4 -0
- package/esm/util/types/renameIds.d.ts +1 -0
- package/esm/util/types/renameIds.js +29 -0
- package/esm/util/types/services.d.ts +1 -1
- package/esm/util/unknownSnapshotKeys.d.ts +51 -0
- package/esm/util/unknownSnapshotKeys.js +82 -0
- package/esm/util/useFeatureSequence.js +5 -5
- package/esm/util/useFetch.d.ts +3 -4
- package/esm/util/useFetch.js +19 -10
- package/esm/util/useFetchPlugins.d.ts +6 -2
- package/esm/util/useFetchPlugins.js +7 -3
- package/esm/util/usePanelVirtualScroll.d.ts +7 -35
- package/esm/util/usePanelVirtualScroll.js +9 -36
- package/esm/util/useRowVirtualScroll.d.ts +6 -29
- package/esm/util/useRowVirtualScroll.js +8 -49
- package/esm/util/useVirtualScrollWheel.d.ts +20 -4
- package/esm/util/useVirtualScrollWheel.js +40 -74
- package/esm/util/viewHighlights.d.ts +3 -0
- package/esm/util/viewHighlights.js +5 -0
- package/esm/util/viewStatus.d.ts +47 -15
- package/esm/util/viewStatus.js +34 -0
- package/esm/util/wheelZoom.d.ts +7 -1
- package/esm/util/wheelZoom.js +85 -19
- package/esm/util/whenViewSettled.d.ts +55 -8
- package/esm/util/whenViewSettled.js +56 -7
- package/esm/util/withLaunchInput.d.ts +174 -0
- package/esm/util/withLaunchInput.js +274 -0
- package/package.json +70 -20
- package/esm/BaseFeatureWidget/BaseFeatureDetail/Position.d.ts +0 -2
- package/esm/BaseFeatureWidget/BaseFeatureDetail/Position.js +0 -8
- package/esm/BaseFeatureWidget/BaseFeatureDetail/types.d.ts +0 -8
- package/esm/BaseFeatureWidget/SequenceFeatureDetails/test_data/DLGAP3.d.ts +0 -80
- package/esm/BaseFeatureWidget/SequenceFeatureDetails/test_data/DLGAP3.js +0 -583
- package/esm/BaseFeatureWidget/SequenceFeatureDetails/test_data/NCDN.d.ts +0 -141
- package/esm/BaseFeatureWidget/SequenceFeatureDetails/test_data/NCDN.js +0 -1116
- package/esm/ReExports/BaseFeatureDetails.d.ts +0 -1
- package/esm/ReExports/BaseFeatureDetails.js +0 -10
- package/esm/ReExports/index.d.ts +0 -1
- package/esm/ReExports/index.js +0 -1
- package/esm/ReExports/publicUtil.d.ts +0 -1
- package/esm/ReExports/publicUtil.js +0 -28
- package/esm/configuration/promotableDefaults.d.ts +0 -199
- package/esm/configuration/promotableDefaults.js +0 -326
- package/esm/configuration/promotablePin.d.ts +0 -55
- package/esm/configuration/promotablePin.js +0 -1
- package/esm/configuration/promotableResolve.d.ts +0 -108
- package/esm/configuration/promotableResolve.js +0 -117
- package/esm/configuration/promotableSlots.d.ts +0 -12
- package/esm/configuration/promotableSlots.js +0 -45
- package/esm/configuration/slotShape.d.ts +0 -12
- package/esm/configuration/slotShape.js +0 -84
- package/esm/pluggableElementTypes/models/HighlightsMixin.d.ts +0 -51
- package/esm/pluggableElementTypes/models/HighlightsMixin.js +0 -78
- package/esm/ui/PinAdornment.d.ts +0 -5
- package/esm/ui/PinAdornment.js +0 -79
- package/esm/ui/SvgGradientLegend.d.ts +0 -26
- package/esm/ui/SvgGradientLegend.js +0 -26
- package/esm/ui/highlightChipReveal.d.ts +0 -32
- package/esm/ui/highlightChipReveal.js +0 -39
- package/esm/ui/promotableMenuItems.d.ts +0 -19
- package/esm/ui/promotableMenuItems.js +0 -89
- package/esm/ui/promotablePinCoverage.d.ts +0 -44
- package/esm/ui/promotablePinCoverage.js +0 -87
- package/esm/util/applyInitSettings.d.ts +0 -79
- package/esm/util/applyInitSettings.js +0 -91
- package/esm/util/openDisplays.d.ts +0 -23
- package/esm/util/openDisplays.js +0 -79
- package/esm/util/stopToken.d.ts +0 -211
- package/esm/util/stopToken.js +0 -438
- /package/esm/{BaseFeatureWidget/BaseFeatureDetail/types.js → data_adapters/BaseAdapter/zoomRange.js} +0 -0
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Classification of a feature from its `type` string alone, for the plugins
|
|
3
|
+
* that decide something about a feature they did not parse. A type is the only
|
|
4
|
+
* thing a display, a menu or a widget can ask about a feature without knowing
|
|
5
|
+
* which adapter produced it, so these live in core rather than beside any one
|
|
6
|
+
* of their callers.
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* Whether the type names a unit of transcription — a gene, a transcript, or an
|
|
10
|
+
* RNA, including the pseudogene and V(D)J segment spellings. This is the
|
|
11
|
+
* question "does this feature have exons", not "can this feature be spliced":
|
|
12
|
+
* an alignment splices too and is deliberately not gene-like, because a caller
|
|
13
|
+
* that means to launch a protein view or read a CDS would be wrong about it.
|
|
14
|
+
*/
|
|
15
|
+
export declare function isGeneLikeType(type: string | undefined): boolean;
|
|
16
|
+
/**
|
|
17
|
+
* Whether the type names a sequence alignment — SO `match` and its subtypes
|
|
18
|
+
* (`cDNA_match`, `EST_match`, `nucleotide_match`, `protein_match`,
|
|
19
|
+
* `translated_nucleotide_match`), whose `match_part` children are the aligned
|
|
20
|
+
* blocks and whose gaps between them are introns when the aligned sequence was
|
|
21
|
+
* a transcript. Separate from `isGeneLikeType` on purpose: an EST alignment is
|
|
22
|
+
* evidence for a gene, not one.
|
|
23
|
+
*/
|
|
24
|
+
export declare function isSequenceMatchType(type: string | undefined): boolean;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Classification of a feature from its `type` string alone, for the plugins
|
|
3
|
+
* that decide something about a feature they did not parse. A type is the only
|
|
4
|
+
* thing a display, a menu or a widget can ask about a feature without knowing
|
|
5
|
+
* which adapter produced it, so these live in core rather than beside any one
|
|
6
|
+
* of their callers.
|
|
7
|
+
*/
|
|
8
|
+
// Anchored at the end so 'intergenic_region' is not a gene, 'rnapol_binding_site'
|
|
9
|
+
// is not an RNA, and 'transcriptional_cis_regulatory_region' is not a
|
|
10
|
+
// transcript.
|
|
11
|
+
const GENE_LIKE_TYPE = /gene(_segment)?$|rna$|transcript$/;
|
|
12
|
+
/**
|
|
13
|
+
* Whether the type names a unit of transcription — a gene, a transcript, or an
|
|
14
|
+
* RNA, including the pseudogene and V(D)J segment spellings. This is the
|
|
15
|
+
* question "does this feature have exons", not "can this feature be spliced":
|
|
16
|
+
* an alignment splices too and is deliberately not gene-like, because a caller
|
|
17
|
+
* that means to launch a protein view or read a CDS would be wrong about it.
|
|
18
|
+
*/
|
|
19
|
+
export function isGeneLikeType(type) {
|
|
20
|
+
return type !== undefined && GENE_LIKE_TYPE.test(type.toLowerCase());
|
|
21
|
+
}
|
|
22
|
+
// SO `match` and every subtype of it is spelled `<something>_match`, so the
|
|
23
|
+
// suffix is the family. `match_part`, the child, is excluded by the anchor.
|
|
24
|
+
const SEQUENCE_MATCH_TYPE = /(^|_)match$/;
|
|
25
|
+
/**
|
|
26
|
+
* Whether the type names a sequence alignment — SO `match` and its subtypes
|
|
27
|
+
* (`cDNA_match`, `EST_match`, `nucleotide_match`, `protein_match`,
|
|
28
|
+
* `translated_nucleotide_match`), whose `match_part` children are the aligned
|
|
29
|
+
* blocks and whose gaps between them are introns when the aligned sequence was
|
|
30
|
+
* a transcript. Separate from `isGeneLikeType` on purpose: an EST alignment is
|
|
31
|
+
* evidence for a gene, not one.
|
|
32
|
+
*/
|
|
33
|
+
export function isSequenceMatchType(type) {
|
|
34
|
+
return type !== undefined && SEQUENCE_MATCH_TYPE.test(type.toLowerCase());
|
|
35
|
+
}
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { redactSource } from './getLocationUri.js';
|
|
2
2
|
import { downloadStatus, phaseOf, updateStatus } from './progress.js';
|
|
3
|
-
|
|
3
|
+
function loadInflater() {
|
|
4
|
+
return import('@gmod/bgzf-filehandle');
|
|
5
|
+
}
|
|
4
6
|
export function isGzip(buf) {
|
|
5
7
|
return buf[0] === 31 && buf[1] === 139 && buf[2] === 8;
|
|
6
8
|
}
|
|
@@ -36,22 +38,27 @@ label = 'Downloading file') {
|
|
|
36
38
|
const phase = loc.source === undefined
|
|
37
39
|
? label
|
|
38
40
|
: { message: phaseOf(label), source: redactSource(loc.source) };
|
|
39
|
-
const { statusCallback,
|
|
40
|
-
// the stop token becomes the read's signal, so a cancelled whole-file load
|
|
41
|
-
// drops at the socket rather than downloading a multi-GB body to completion
|
|
42
|
-
const buf = await withStopTokenSignal(stopToken, signal => downloadStatus(phase, statusCallback, onProgress => loc.readFile({ ...opts, onProgress, signal })));
|
|
41
|
+
const { statusCallback, signal } = opts;
|
|
43
42
|
// the inflater is imported dynamically because this module is reachable from
|
|
44
43
|
// the core/util barrel, so a static import put bgzf-filehandle + pako
|
|
45
|
-
// (~180KB) on the startup path of every page load
|
|
46
|
-
//
|
|
44
|
+
// (~180KB) on the startup path of every page load. A name ending .gz starts
|
|
45
|
+
// that import beside the download instead of after it; the bytes still decide
|
|
46
|
+
// whether to inflate.
|
|
47
|
+
const inflater = /\.gz($|[?#])/.test(loc.source ?? '')
|
|
48
|
+
? loadInflater()
|
|
49
|
+
: undefined;
|
|
50
|
+
inflater?.catch(() => { });
|
|
51
|
+
// the signal reaches the read, so a cancelled whole-file load drops at the
|
|
52
|
+
// socket rather than downloading a multi-GB body to completion
|
|
53
|
+
const buf = await downloadStatus(phase, statusCallback, onProgress => loc.readFile({ ...opts, onProgress, signal }));
|
|
47
54
|
return isGzip(buf)
|
|
48
55
|
? await updateStatus('Unzipping', statusCallback, async () => {
|
|
49
|
-
const { unzip } = await
|
|
56
|
+
const { unzip } = await (inflater ?? loadInflater());
|
|
50
57
|
return unzip(buf);
|
|
51
58
|
},
|
|
52
59
|
// a cancel landing here is otherwise discovered only by whatever parses
|
|
53
60
|
// the result, after a whole-file inflate has run to completion
|
|
54
|
-
|
|
61
|
+
signal)
|
|
55
62
|
: buf;
|
|
56
63
|
}
|
|
57
64
|
export async function fetchAndMaybeUnzipText(loc, opts, label) {
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import type { RpcCallArgs, RpcCallReturn } from '../rpc/RpcRegistry.ts';
|
|
2
2
|
import type { StatusCallback } from './progress.ts';
|
|
3
|
-
import type { StopToken } from './stopToken.ts';
|
|
4
3
|
import type { IStateTreeNode } from '@jbrowse/mobx-state-tree';
|
|
5
4
|
export interface FetchContext {
|
|
6
|
-
|
|
5
|
+
signal: AbortSignal;
|
|
7
6
|
isStale: () => boolean;
|
|
8
7
|
/**
|
|
9
8
|
* The RPC `statusCallback` for the work this context describes: guarded to
|
|
@@ -24,23 +23,23 @@ export interface FetchContext {
|
|
|
24
23
|
/**
|
|
25
24
|
* The one way a fetch calls an RPC: the registry-typed
|
|
26
25
|
* `rpcManager.call(rpcSessionId, method, args)` with this context's
|
|
27
|
-
* `
|
|
26
|
+
* `signal` and `statusCallback` injected. Both used to be hand-threaded
|
|
28
27
|
* at every fetch site, and forgetting either was silent — no cancellation
|
|
29
28
|
* for that display, or no progress — which is exactly the failure class the
|
|
30
29
|
* envelope makes inexpressible: a fetch cannot issue an RPC the cancel and
|
|
31
30
|
* the status bar don't know about.
|
|
32
31
|
*
|
|
33
32
|
* Declared with a `this` parameter so it reads the *holding* context's
|
|
34
|
-
*
|
|
33
|
+
* signal and callback — the fan-out copies rebind it to their own status
|
|
35
34
|
* slot by construction — and so destructuring it off the context is a type
|
|
36
35
|
* error rather than a stale binding.
|
|
37
36
|
*/
|
|
38
|
-
callRpc: <M extends string>(this: FetchContext, method: M, args: Omit<RpcCallArgs<M>, '
|
|
37
|
+
callRpc: <M extends string>(this: FetchContext, method: M, args: Omit<RpcCallArgs<M>, 'signal' | 'statusCallback'>) => Promise<RpcCallReturn<M>>;
|
|
39
38
|
}
|
|
40
39
|
/**
|
|
41
40
|
* Build a {@link FetchContext} over a live fetch's primitives. One
|
|
42
|
-
* constructor, so every context — `runFetch`'s
|
|
43
|
-
* carries the same `callRpc` envelope.
|
|
41
|
+
* constructor, so every context — `FetchMixin.runFetch`'s and `runFetchOnce`'s
|
|
42
|
+
* alike — carries the same `callRpc` envelope.
|
|
44
43
|
*
|
|
45
44
|
* **`self` has to be somewhere `getRpcSessionId` can find one, which in practice
|
|
46
45
|
* means a track or something under it.** `rpcSessionId` is declared by
|
|
@@ -52,7 +51,7 @@ export interface FetchContext {
|
|
|
52
51
|
* track, which is what the breakpoint split view's overlay fetch does.
|
|
53
52
|
*/
|
|
54
53
|
export declare function makeFetchContext(self: IStateTreeNode, base: {
|
|
55
|
-
|
|
54
|
+
signal: AbortSignal;
|
|
56
55
|
isStale: () => boolean;
|
|
57
56
|
statusCallback: StatusCallback;
|
|
58
57
|
}): FetchContext;
|
package/esm/util/fetchContext.js
CHANGED
|
@@ -3,8 +3,8 @@ import { createStatusFanOut } from './progress.js';
|
|
|
3
3
|
import { getRpcHost } from './sessionServices.js';
|
|
4
4
|
/**
|
|
5
5
|
* Build a {@link FetchContext} over a live fetch's primitives. One
|
|
6
|
-
* constructor, so every context — `runFetch`'s
|
|
7
|
-
* carries the same `callRpc` envelope.
|
|
6
|
+
* constructor, so every context — `FetchMixin.runFetch`'s and `runFetchOnce`'s
|
|
7
|
+
* alike — carries the same `callRpc` envelope.
|
|
8
8
|
*
|
|
9
9
|
* **`self` has to be somewhere `getRpcSessionId` can find one, which in practice
|
|
10
10
|
* means a track or something under it.** `rpcSessionId` is declared by
|
|
@@ -21,7 +21,7 @@ export function makeFetchContext(self, base) {
|
|
|
21
21
|
callRpc(method, args) {
|
|
22
22
|
return getRpcHost(self).rpcManager.call(getRpcSessionId(self), method, {
|
|
23
23
|
...args,
|
|
24
|
-
|
|
24
|
+
signal: this.signal,
|
|
25
25
|
statusCallback: this.statusCallback,
|
|
26
26
|
});
|
|
27
27
|
},
|
package/esm/util/fetchHub.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export interface HubConfig {
|
|
2
2
|
assemblies?: Record<string, unknown>[];
|
|
3
|
-
aggregateTextSearchAdapters?: Record<string, unknown>[];
|
|
3
|
+
aggregateTextSearchAdapters?: (string | Record<string, unknown>)[];
|
|
4
4
|
tracks?: Record<string, unknown>[];
|
|
5
5
|
[key: string]: unknown;
|
|
6
6
|
}
|
|
@@ -12,4 +12,6 @@ export declare function hubUrl(hub: string): string;
|
|
|
12
12
|
* the name straight to `createLinearGenomeView({ assembly: 'hg38' })` for the
|
|
13
13
|
* common case; call this directly only to cherry-pick tracks from the catalog.
|
|
14
14
|
*/
|
|
15
|
-
export declare function fetchHub(hub: string
|
|
15
|
+
export declare function fetchHub(hub: string, { signal }?: {
|
|
16
|
+
signal?: AbortSignal;
|
|
17
|
+
}): Promise<HubConfig>;
|
package/esm/util/fetchHub.js
CHANGED
|
@@ -15,9 +15,9 @@ export function hubUrl(hub) {
|
|
|
15
15
|
* the name straight to `createLinearGenomeView({ assembly: 'hg38' })` for the
|
|
16
16
|
* common case; call this directly only to cherry-pick tracks from the catalog.
|
|
17
17
|
*/
|
|
18
|
-
export async function fetchHub(hub) {
|
|
18
|
+
export async function fetchHub(hub, { signal } = {}) {
|
|
19
19
|
const url = hubUrl(hub);
|
|
20
|
-
const response = await fetch(url);
|
|
20
|
+
const response = await fetch(url, { signal });
|
|
21
21
|
if (response.ok) {
|
|
22
22
|
const config = (await response.json());
|
|
23
23
|
// hosted configs reference their data relative to the config's own location
|
|
@@ -4,10 +4,10 @@
|
|
|
4
4
|
* remembered.
|
|
5
5
|
*
|
|
6
6
|
* The shared `installFetch` skeleton takes this shape, and so does the LGV
|
|
7
|
-
* global family (`installGlobalFetchAutorun`, over
|
|
8
|
-
* was the same contract declared twice, with the same three rules
|
|
9
|
-
* twice, which is a drift axis over rules whose whole value is being
|
|
10
|
-
* everywhere.
|
|
7
|
+
* global family (`installGlobalFetchAutorun`, a declaration over that same
|
|
8
|
+
* skeleton). It was the same contract declared twice, with the same three rules
|
|
9
|
+
* explained twice, which is a drift axis over rules whose whole value is being
|
|
10
|
+
* the same everywhere.
|
|
11
11
|
*
|
|
12
12
|
* `TCtx` is what a family hands its `run`: a `FetchContext` for most of them, a
|
|
13
13
|
* `ComparativeFetchContext` (that plus adapter config and refName rename) for
|
|
@@ -43,7 +43,7 @@ export interface FetchPhases<TArgs, TResult, TCtx> {
|
|
|
43
43
|
* gets a dead Retry button — see there.
|
|
44
44
|
*
|
|
45
45
|
* What it must **not** do is move a trigger read of its own under a bail-out.
|
|
46
|
-
* See
|
|
46
|
+
* See reference/FETCH_SKELETON.md §"The global-fetch trigger list must be read
|
|
47
47
|
* unconditionally".
|
|
48
48
|
*/
|
|
49
49
|
prepare: () => TArgs | undefined;
|
|
@@ -56,11 +56,11 @@ export interface FetchPhases<TArgs, TResult, TCtx> {
|
|
|
56
56
|
* **Nothing it reads is tracked**, so the payload it assembles cannot widen
|
|
57
57
|
* the autorun's dependency set the way calling `rpcProps()` in the body would.
|
|
58
58
|
* Being async is not what buys that — `run` is *called* synchronously, so its
|
|
59
|
-
* own prefix down to its first `await` runs wherever the caller was.
|
|
60
|
-
*
|
|
61
|
-
*
|
|
62
|
-
*
|
|
63
|
-
*
|
|
59
|
+
* own prefix down to its first `await` runs wherever the caller was. The
|
|
60
|
+
* `installFetch` skeleton calls it inside `untracked`, which covers the
|
|
61
|
+
* global and comparative families with it; the per-region family reaches its
|
|
62
|
+
* work through `FetchMixin.runFetch`, an MST flow and so an action, which
|
|
63
|
+
* MobX runs untracked.
|
|
64
64
|
*/
|
|
65
65
|
run: (args: TArgs, ctx: TCtx) => Promise<TResult | undefined>;
|
|
66
66
|
/**
|
package/esm/util/fetchSeq.d.ts
CHANGED
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
import type { StatusCallback } from './progress.ts';
|
|
2
|
-
import type { StopToken } from './stopToken.ts';
|
|
3
2
|
import type { AbstractSessionModel } from './types/index.ts';
|
|
4
|
-
export declare function fetchSeq({ start, end, refName, assemblyName, session,
|
|
3
|
+
export declare function fetchSeq({ start, end, refName, assemblyName, session, signal, statusCallback, }: {
|
|
5
4
|
start: number;
|
|
6
5
|
end: number;
|
|
7
6
|
refName: string;
|
|
8
7
|
assemblyName: string;
|
|
9
8
|
session: AbstractSessionModel;
|
|
10
|
-
|
|
9
|
+
signal?: AbortSignal;
|
|
11
10
|
statusCallback?: StatusCallback;
|
|
12
11
|
}): Promise<string>;
|
package/esm/util/fetchSeq.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { getSequenceAdapterConfig } from '../assemblyManager/getSequenceAdapterConfig.js';
|
|
2
|
-
export async function fetchSeq({ start, end, refName, assemblyName, session,
|
|
2
|
+
export async function fetchSeq({ start, end, refName, assemblyName, session, signal, statusCallback, }) {
|
|
3
3
|
const { rpcManager, assemblyManager } = session;
|
|
4
4
|
const assembly = await assemblyManager.waitForAssembly(assemblyName);
|
|
5
5
|
if (!assembly) {
|
|
@@ -28,7 +28,7 @@ export async function fetchSeq({ start, end, refName, assemblyName, session, sto
|
|
|
28
28
|
refName: seqAdapterRefName,
|
|
29
29
|
assemblyName,
|
|
30
30
|
},
|
|
31
|
-
|
|
31
|
+
signal,
|
|
32
32
|
statusCallback,
|
|
33
33
|
});
|
|
34
34
|
return seq ?? '';
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { JexlInstance } from './jexlStrings.ts';
|
|
2
|
+
import type { Feature } from './simpleFeature.ts';
|
|
3
|
+
/**
|
|
4
|
+
* #api
|
|
5
|
+
* What a channel reads off a feature: a field by name, a dotted path into a
|
|
6
|
+
* structured field where no field carries the whole name (`INFO.SVTYPE` on a
|
|
7
|
+
* VCF record), or a `jexl:` expression over `feature`. A jexl expression that
|
|
8
|
+
* does not compile throws here, once, rather than on every feature.
|
|
9
|
+
*/
|
|
10
|
+
export declare function fieldReader(ref: string, jexl: JexlInstance | undefined): (feature: Feature) => unknown;
|
|
11
|
+
/**
|
|
12
|
+
* #api
|
|
13
|
+
* Whether a field ref is a bare name: what `feature.get` answers on its own,
|
|
14
|
+
* with no path to walk and no expression to evaluate. A loop over a plain name
|
|
15
|
+
* keeps the direct call, and only a config that writes a path pays for one.
|
|
16
|
+
*/
|
|
17
|
+
export declare function isPlainFieldRef(ref: string): ref is never;
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { isJexl, stringToJexlExpression } from './jexlStrings.js';
|
|
2
|
+
import { buildJexlContext } from './simpleFeature.js';
|
|
3
|
+
/**
|
|
4
|
+
* #api
|
|
5
|
+
* What a channel reads off a feature: a field by name, a dotted path into a
|
|
6
|
+
* structured field where no field carries the whole name (`INFO.SVTYPE` on a
|
|
7
|
+
* VCF record), or a `jexl:` expression over `feature`. A jexl expression that
|
|
8
|
+
* does not compile throws here, once, rather than on every feature.
|
|
9
|
+
*/
|
|
10
|
+
export function fieldReader(ref, jexl) {
|
|
11
|
+
const path = ref.includes('.') ? ref.split('.') : undefined;
|
|
12
|
+
const rests = path?.map((_, i) => path.slice(i).join('.'));
|
|
13
|
+
if (isJexl(ref)) {
|
|
14
|
+
if (!jexl) {
|
|
15
|
+
throw new Error(`a jexl: field needs a jexl instance (${ref})`);
|
|
16
|
+
}
|
|
17
|
+
const expr = stringToJexlExpression(ref, jexl);
|
|
18
|
+
return feature => expr.eval(buildJexlContext({ feature }));
|
|
19
|
+
}
|
|
20
|
+
return feature => {
|
|
21
|
+
const value = feature.get(ref);
|
|
22
|
+
return value === undefined && path && rests
|
|
23
|
+
? readPath(feature.get(path[0]), path, rests)
|
|
24
|
+
: value;
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* #api
|
|
29
|
+
* Whether a field ref is a bare name: what `feature.get` answers on its own,
|
|
30
|
+
* with no path to walk and no expression to evaluate. A loop over a plain name
|
|
31
|
+
* keeps the direct call, and only a config that writes a path pays for one.
|
|
32
|
+
*/
|
|
33
|
+
export function isPlainFieldRef(ref) {
|
|
34
|
+
return !ref.includes('.') && !isJexl(ref);
|
|
35
|
+
}
|
|
36
|
+
function readPath(root, path, rests) {
|
|
37
|
+
let value = root;
|
|
38
|
+
for (let i = 1; i < path.length; i++) {
|
|
39
|
+
value =
|
|
40
|
+
typeof value === 'object' && value !== null
|
|
41
|
+
? Reflect.get(value, path[i])
|
|
42
|
+
: undefined;
|
|
43
|
+
}
|
|
44
|
+
return value ?? readWholeRest(root, path, rests);
|
|
45
|
+
}
|
|
46
|
+
// A path that read nothing by descending tries each level's rest as one key,
|
|
47
|
+
// so `INFO.AF.EAS` reaches a key named `AF.EAS`, which VCF 4.3 allows. Only a
|
|
48
|
+
// miss pays for it: a path that resolves is the plain walk above.
|
|
49
|
+
function readWholeRest(root, path, rests) {
|
|
50
|
+
let value = root;
|
|
51
|
+
for (let i = 1; i < path.length - 1; i++) {
|
|
52
|
+
if (typeof value !== 'object' || value === null) {
|
|
53
|
+
return undefined;
|
|
54
|
+
}
|
|
55
|
+
const whole = Reflect.get(value, rests[i]);
|
|
56
|
+
if (whole !== undefined) {
|
|
57
|
+
return whole ?? undefined;
|
|
58
|
+
}
|
|
59
|
+
value = Reflect.get(value, path[i]);
|
|
60
|
+
}
|
|
61
|
+
return undefined;
|
|
62
|
+
}
|
package/esm/util/freezeDeep.d.ts
CHANGED
|
@@ -1,20 +1,18 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Freeze `value` and everything reachable from it, in place, and return it.
|
|
3
3
|
*
|
|
4
|
-
* For a value handed to consumers **by reference on purpose**: a
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
* following display). Sharing the reference is load-bearing in both cases —
|
|
8
|
-
* `===` stability is what lets a display's cached MobX computed re-resolve
|
|
4
|
+
* For a value handed to consumers **by reference on purpose**: a stored user
|
|
5
|
+
* preference, read by everything that follows it. Sharing the reference is
|
|
6
|
+
* load-bearing — `===` stability is what lets a cached MobX computed re-derive
|
|
9
7
|
* without waking anything downstream — so handing out a defensive copy per read
|
|
10
8
|
* would trade a silent hazard for a real re-render on every read. Freezing keeps
|
|
11
9
|
* the identity and makes "nothing mutates this" throw rather than quietly
|
|
12
|
-
* rewriting a value every other
|
|
10
|
+
* rewriting a value every other reader sees.
|
|
13
11
|
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
12
|
+
* The caller freezes once, at the store write, over a value that has to survive
|
|
13
|
+
* `postMessage` anyway — so the recursion is over small JSON and costs nothing
|
|
14
|
+
* per read. Cyclic input terminates: each object is frozen before its children
|
|
15
|
+
* are visited.
|
|
18
16
|
*
|
|
19
17
|
* **Unconditional, deliberately unlike MST's own `deepFreeze`** (whose body this
|
|
20
18
|
* otherwise mirrors), which is gated on `devMode()`. MST gates because it freezes
|
package/esm/util/freezeDeep.js
CHANGED
|
@@ -6,20 +6,18 @@ function isObjectLike(value) {
|
|
|
6
6
|
/**
|
|
7
7
|
* Freeze `value` and everything reachable from it, in place, and return it.
|
|
8
8
|
*
|
|
9
|
-
* For a value handed to consumers **by reference on purpose**: a
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
* following display). Sharing the reference is load-bearing in both cases —
|
|
13
|
-
* `===` stability is what lets a display's cached MobX computed re-resolve
|
|
9
|
+
* For a value handed to consumers **by reference on purpose**: a stored user
|
|
10
|
+
* preference, read by everything that follows it. Sharing the reference is
|
|
11
|
+
* load-bearing — `===` stability is what lets a cached MobX computed re-derive
|
|
14
12
|
* without waking anything downstream — so handing out a defensive copy per read
|
|
15
13
|
* would trade a silent hazard for a real re-render on every read. Freezing keeps
|
|
16
14
|
* the identity and makes "nothing mutates this" throw rather than quietly
|
|
17
|
-
* rewriting a value every other
|
|
15
|
+
* rewriting a value every other reader sees.
|
|
18
16
|
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
17
|
+
* The caller freezes once, at the store write, over a value that has to survive
|
|
18
|
+
* `postMessage` anyway — so the recursion is over small JSON and costs nothing
|
|
19
|
+
* per read. Cyclic input terminates: each object is frozen before its children
|
|
20
|
+
* are visited.
|
|
23
21
|
*
|
|
24
22
|
* **Unconditional, deliberately unlike MST's own `deepFreeze`** (whose body this
|
|
25
23
|
* otherwise mirrors), which is gated on `devMode()`. MST gates because it freezes
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The ordering every in-track group-by shares, whatever partitioned the
|
|
3
|
+
* features: named groups first, then the `''` catch-all a dimension files its
|
|
4
|
+
* unanswerable features under, then the overflow bucket a capped partition
|
|
5
|
+
* merged its tail into.
|
|
6
|
+
*/
|
|
7
|
+
export declare const OVERFLOW_GROUP_KEY = "\0overflow";
|
|
8
|
+
export declare const MAX_GROUPS = 40;
|
|
9
|
+
/**
|
|
10
|
+
* The text a field value groups, colors and labels by: a missing value is the
|
|
11
|
+
* `''` catch-all, a VCF's `.` among them, which `@gmod/vcf` hands over as
|
|
12
|
+
* `[undefined]`, and a multi-valued attribute joins, so two features carrying
|
|
13
|
+
* the same list land together.
|
|
14
|
+
*/
|
|
15
|
+
export declare function valueText(value: unknown): string;
|
|
16
|
+
/**
|
|
17
|
+
* Numbers first by value, then every other key run by run with digit runs by
|
|
18
|
+
* magnitude, so -1 before 1 and chr2 before chr10. The two classes never
|
|
19
|
+
* interleave: a signed or decimal number read run by run orders differently
|
|
20
|
+
* than by value, and letting them mix made the order intransitive.
|
|
21
|
+
*/
|
|
22
|
+
export declare function compareGroupKeys(a: string, b: string): number;
|
|
23
|
+
/**
|
|
24
|
+
* The order a facet stacks its sections in. `domain` is the channel's
|
|
25
|
+
* declared order: the keys it lists come first, in that order, and the rest
|
|
26
|
+
* follow under `compareGroupKeys`. Every categorical channel in the tree
|
|
27
|
+
* reads its domain this way, so a listed value is a placement and an
|
|
28
|
+
* unlisted one is not an error.
|
|
29
|
+
*/
|
|
30
|
+
export declare function groupKeyComparator(domain?: readonly string[]): typeof compareGroupKeys;
|
|
31
|
+
/**
|
|
32
|
+
* The domain a re-pick keeps: a facet set from a menu or dialog names no
|
|
33
|
+
* domain, so one naming the field the current facet already reads carries
|
|
34
|
+
* the current order along. A reorder names its own domain and passes
|
|
35
|
+
* through, an empty one included.
|
|
36
|
+
*/
|
|
37
|
+
export declare function carryGroupDomain<T extends {
|
|
38
|
+
field: string;
|
|
39
|
+
domain?: readonly string[];
|
|
40
|
+
}>(next: T | undefined, current: T | undefined): T | undefined;
|
|
41
|
+
/**
|
|
42
|
+
* The overflow bucket's chip. Says MERGED because that lane is the one entry
|
|
43
|
+
* in a stack that is not a value, and this label is the only place a reader
|
|
44
|
+
* is told the cap fired at all.
|
|
45
|
+
*/
|
|
46
|
+
export declare function overflowLabel(count: number): string;
|
|
47
|
+
/**
|
|
48
|
+
* Which section each key stacks into once the cap applies: the first
|
|
49
|
+
* `limit` keys (`MAX_GROUPS` by default) in natural order keep their own and
|
|
50
|
+
* the rest fold into the overflow section; `Infinity` folds none. The
|
|
51
|
+
* catch-all `''` is held out of the merge, since "lacking the value" is an
|
|
52
|
+
* answer users look for. A domain orders the
|
|
53
|
+
* sections and never decides which exist, so reordering them changes no
|
|
54
|
+
* key's section.
|
|
55
|
+
*/
|
|
56
|
+
export declare function capGroupKeys(keys: Iterable<string>, limit?: number): {
|
|
57
|
+
mergedCount: number;
|
|
58
|
+
sectionOf: (key: string) => string;
|
|
59
|
+
};
|
|
60
|
+
/**
|
|
61
|
+
* A group's stable identity: its sort key and the label its chip shows.
|
|
62
|
+
*/
|
|
63
|
+
export interface GroupId {
|
|
64
|
+
key: string;
|
|
65
|
+
label: string;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Identity of the key space a facet hands out keys in: its field. A key means
|
|
69
|
+
* nothing on its own, since `''` is both the ungrouped section and every
|
|
70
|
+
* field's catch-all, so anything keyed by group key is dropped when this
|
|
71
|
+
* moves. The `domain` only orders the keys and is no part of the space, so a
|
|
72
|
+
* reorder keeps what a reader hid.
|
|
73
|
+
*/
|
|
74
|
+
export declare function groupKeySpaceOf(facet: {
|
|
75
|
+
field: string;
|
|
76
|
+
domain?: readonly string[];
|
|
77
|
+
} | undefined): string;
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The ordering every in-track group-by shares, whatever partitioned the
|
|
3
|
+
* features: named groups first, then the `''` catch-all a dimension files its
|
|
4
|
+
* unanswerable features under, then the overflow bucket a capped partition
|
|
5
|
+
* merged its tail into.
|
|
6
|
+
*/
|
|
7
|
+
// '\0' cannot collide with a real tag value or refName, and the rank below
|
|
8
|
+
// pins it dead last so a merged tail never displaces a named group.
|
|
9
|
+
export const OVERFLOW_GROUP_KEY = '\u0000overflow';
|
|
10
|
+
// Hard ceiling on the sections one grouping may stack; the tail past it merges
|
|
11
|
+
// into the overflow section. A backstop for the dimensions that are not a
|
|
12
|
+
// closed set, a tag or an attribute, whose value space is the file's.
|
|
13
|
+
export const MAX_GROUPS = 40;
|
|
14
|
+
/**
|
|
15
|
+
* The text a field value groups, colors and labels by: a missing value is the
|
|
16
|
+
* `''` catch-all, a VCF's `.` among them, which `@gmod/vcf` hands over as
|
|
17
|
+
* `[undefined]`, and a multi-valued attribute joins, so two features carrying
|
|
18
|
+
* the same list land together.
|
|
19
|
+
*/
|
|
20
|
+
export function valueText(value) {
|
|
21
|
+
return value === undefined || value === null
|
|
22
|
+
? ''
|
|
23
|
+
: Array.isArray(value)
|
|
24
|
+
? value
|
|
25
|
+
.filter(v => v !== undefined && v !== null)
|
|
26
|
+
.map(String)
|
|
27
|
+
.join(',')
|
|
28
|
+
: String(value);
|
|
29
|
+
}
|
|
30
|
+
function groupKeyRank(key) {
|
|
31
|
+
return key === '' ? 1 : key === OVERFLOW_GROUP_KEY ? 2 : 0;
|
|
32
|
+
}
|
|
33
|
+
const NUMERIC = /^-?\d+(\.\d+)?$/;
|
|
34
|
+
const DIGIT_RUNS = /\d+|\D+/g;
|
|
35
|
+
function compareRuns(a, b) {
|
|
36
|
+
const runsA = a.match(DIGIT_RUNS) ?? [];
|
|
37
|
+
const runsB = b.match(DIGIT_RUNS) ?? [];
|
|
38
|
+
const shared = Math.min(runsA.length, runsB.length);
|
|
39
|
+
for (let i = 0; i < shared; i++) {
|
|
40
|
+
const x = runsA[i];
|
|
41
|
+
const y = runsB[i];
|
|
42
|
+
if (x === y) {
|
|
43
|
+
continue;
|
|
44
|
+
}
|
|
45
|
+
if (/^\d/.test(x) && /^\d/.test(y)) {
|
|
46
|
+
const nx = Number(x);
|
|
47
|
+
const ny = Number(y);
|
|
48
|
+
if (nx !== ny) {
|
|
49
|
+
return nx < ny ? -1 : 1;
|
|
50
|
+
}
|
|
51
|
+
return x.length < y.length ? -1 : 1;
|
|
52
|
+
}
|
|
53
|
+
return x < y ? -1 : 1;
|
|
54
|
+
}
|
|
55
|
+
return runsA.length - runsB.length;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Numbers first by value, then every other key run by run with digit runs by
|
|
59
|
+
* magnitude, so -1 before 1 and chr2 before chr10. The two classes never
|
|
60
|
+
* interleave: a signed or decimal number read run by run orders differently
|
|
61
|
+
* than by value, and letting them mix made the order intransitive.
|
|
62
|
+
*/
|
|
63
|
+
export function compareGroupKeys(a, b) {
|
|
64
|
+
const rankDiff = groupKeyRank(a) - groupKeyRank(b);
|
|
65
|
+
if (rankDiff !== 0 || a === b) {
|
|
66
|
+
return rankDiff;
|
|
67
|
+
}
|
|
68
|
+
const numA = NUMERIC.test(a);
|
|
69
|
+
const numB = NUMERIC.test(b);
|
|
70
|
+
if (numA !== numB) {
|
|
71
|
+
return numA ? -1 : 1;
|
|
72
|
+
}
|
|
73
|
+
if (numA) {
|
|
74
|
+
const diff = Number(a) - Number(b);
|
|
75
|
+
if (diff !== 0) {
|
|
76
|
+
return diff < 0 ? -1 : 1;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
return compareRuns(a, b);
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* The order a facet stacks its sections in. `domain` is the channel's
|
|
83
|
+
* declared order: the keys it lists come first, in that order, and the rest
|
|
84
|
+
* follow under `compareGroupKeys`. Every categorical channel in the tree
|
|
85
|
+
* reads its domain this way, so a listed value is a placement and an
|
|
86
|
+
* unlisted one is not an error.
|
|
87
|
+
*/
|
|
88
|
+
export function groupKeyComparator(domain) {
|
|
89
|
+
if (!domain?.length) {
|
|
90
|
+
return compareGroupKeys;
|
|
91
|
+
}
|
|
92
|
+
const rank = new Map();
|
|
93
|
+
domain.forEach((key, i) => {
|
|
94
|
+
if (!rank.has(key)) {
|
|
95
|
+
rank.set(key, i);
|
|
96
|
+
}
|
|
97
|
+
});
|
|
98
|
+
return (a, b) => {
|
|
99
|
+
const ra = rank.get(a) ?? Infinity;
|
|
100
|
+
const rb = rank.get(b) ?? Infinity;
|
|
101
|
+
return ra !== rb ? (ra < rb ? -1 : 1) : compareGroupKeys(a, b);
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* The domain a re-pick keeps: a facet set from a menu or dialog names no
|
|
106
|
+
* domain, so one naming the field the current facet already reads carries
|
|
107
|
+
* the current order along. A reorder names its own domain and passes
|
|
108
|
+
* through, an empty one included.
|
|
109
|
+
*/
|
|
110
|
+
export function carryGroupDomain(next, current) {
|
|
111
|
+
return next !== undefined &&
|
|
112
|
+
next.domain === undefined &&
|
|
113
|
+
current?.domain !== undefined &&
|
|
114
|
+
next.field === current.field
|
|
115
|
+
? { ...next, domain: current.domain }
|
|
116
|
+
: next;
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* The overflow bucket's chip. Says MERGED because that lane is the one entry
|
|
120
|
+
* in a stack that is not a value, and this label is the only place a reader
|
|
121
|
+
* is told the cap fired at all.
|
|
122
|
+
*/
|
|
123
|
+
export function overflowLabel(count) {
|
|
124
|
+
return `${count} merged values`;
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Which section each key stacks into once the cap applies: the first
|
|
128
|
+
* `limit` keys (`MAX_GROUPS` by default) in natural order keep their own and
|
|
129
|
+
* the rest fold into the overflow section; `Infinity` folds none. The
|
|
130
|
+
* catch-all `''` is held out of the merge, since "lacking the value" is an
|
|
131
|
+
* answer users look for. A domain orders the
|
|
132
|
+
* sections and never decides which exist, so reordering them changes no
|
|
133
|
+
* key's section.
|
|
134
|
+
*/
|
|
135
|
+
export function capGroupKeys(keys, limit = MAX_GROUPS) {
|
|
136
|
+
const ordered = [...new Set(keys)].sort(compareGroupKeys);
|
|
137
|
+
const hasUntagged = ordered.includes('');
|
|
138
|
+
const named = ordered.filter(key => key !== '');
|
|
139
|
+
const merged = ordered.length > limit ? named.slice(limit - (hasUntagged ? 2 : 1)) : [];
|
|
140
|
+
const mergedSet = new Set(merged);
|
|
141
|
+
return {
|
|
142
|
+
mergedCount: merged.length,
|
|
143
|
+
sectionOf: (key) => (mergedSet.has(key) ? OVERFLOW_GROUP_KEY : key),
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Identity of the key space a facet hands out keys in: its field. A key means
|
|
148
|
+
* nothing on its own, since `''` is both the ungrouped section and every
|
|
149
|
+
* field's catch-all, so anything keyed by group key is dropped when this
|
|
150
|
+
* moves. The `domain` only orders the keys and is no part of the space, so a
|
|
151
|
+
* reorder keeps what a reader hid.
|
|
152
|
+
*/
|
|
153
|
+
export function groupKeySpaceOf(facet) {
|
|
154
|
+
return facet?.field ?? '';
|
|
155
|
+
}
|