@jbrowse/core 5.0.0-beta.11 → 5.0.0-beta.14
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 +450 -132
- package/esm/BaseFeatureWidget/BaseFeatureDetail/ArrayValue.d.ts +3 -2
- package/esm/BaseFeatureWidget/BaseFeatureDetail/ArrayValue.js +4 -2
- package/esm/BaseFeatureWidget/BaseFeatureDetail/Attributes.d.ts +6 -2
- package/esm/BaseFeatureWidget/BaseFeatureDetail/Attributes.js +18 -3
- package/esm/BaseFeatureWidget/BaseFeatureDetail/BaseAttributes.d.ts +2 -1
- package/esm/BaseFeatureWidget/BaseFeatureDetail/BaseAttributes.js +4 -2
- package/esm/BaseFeatureWidget/BaseFeatureDetail/BaseCard.d.ts +2 -1
- package/esm/BaseFeatureWidget/BaseFeatureDetail/BaseCard.js +4 -2
- package/esm/BaseFeatureWidget/BaseFeatureDetail/BaseCoreDetails.d.ts +2 -1
- package/esm/BaseFeatureWidget/BaseFeatureDetail/BaseCoreDetails.js +4 -2
- package/esm/BaseFeatureWidget/BaseFeatureDetail/BasicValue.d.ts +5 -4
- package/esm/BaseFeatureWidget/BaseFeatureDetail/BasicValue.js +6 -4
- package/esm/BaseFeatureWidget/BaseFeatureDetail/CoreDetails.d.ts +2 -1
- package/esm/BaseFeatureWidget/BaseFeatureDetail/CoreDetails.js +4 -2
- package/esm/BaseFeatureWidget/BaseFeatureDetail/DataGridDetails.d.ts +3 -2
- package/esm/BaseFeatureWidget/BaseFeatureDetail/DataGridDetails.js +4 -2
- package/esm/BaseFeatureWidget/BaseFeatureDetail/FeatureDetails.js +2 -2
- package/esm/BaseFeatureWidget/BaseFeatureDetail/FeatureWash.d.ts +3 -2
- package/esm/BaseFeatureWidget/BaseFeatureDetail/FeatureWash.js +4 -2
- package/esm/BaseFeatureWidget/BaseFeatureDetail/FieldActionsButton.d.ts +3 -2
- package/esm/BaseFeatureWidget/BaseFeatureDetail/FieldActionsButton.js +4 -2
- package/esm/BaseFeatureWidget/BaseFeatureDetail/FieldName.d.ts +3 -2
- package/esm/BaseFeatureWidget/BaseFeatureDetail/FieldName.js +4 -2
- package/esm/BaseFeatureWidget/BaseFeatureDetail/Formatter.d.ts +3 -2
- package/esm/BaseFeatureWidget/BaseFeatureDetail/Formatter.js +4 -2
- package/esm/BaseFeatureWidget/BaseFeatureDetail/ParentFeatureLine.d.ts +3 -2
- package/esm/BaseFeatureWidget/BaseFeatureDetail/ParentFeatureLine.js +4 -2
- package/esm/BaseFeatureWidget/BaseFeatureDetail/SimpleField.d.ts +3 -2
- package/esm/BaseFeatureWidget/BaseFeatureDetail/SimpleField.js +4 -2
- package/esm/BaseFeatureWidget/BaseFeatureDetail/UriField.d.ts +3 -2
- package/esm/BaseFeatureWidget/BaseFeatureDetail/UriField.js +4 -2
- package/esm/BaseFeatureWidget/SequenceFeatureDetails/SequenceBody.d.ts +3 -2
- package/esm/BaseFeatureWidget/SequenceFeatureDetails/SequenceBody.js +4 -2
- package/esm/BaseFeatureWidget/SequenceFeatureDetails/SequenceFeatureDetails.d.ts +3 -1
- package/esm/BaseFeatureWidget/SequenceFeatureDetails/SequenceFeatureDetails.js +15 -24
- package/esm/BaseFeatureWidget/SequenceFeatureDetails/SequenceFeaturePanel.js +1 -1
- package/esm/BaseFeatureWidget/SequenceFeatureDetails/SequenceLegend.d.ts +3 -2
- package/esm/BaseFeatureWidget/SequenceFeatureDetails/SequenceLegend.js +4 -2
- package/esm/BaseFeatureWidget/SequenceFeatureDetails/SequencePanel.js +4 -4
- package/esm/BaseFeatureWidget/SequenceFeatureDetails/dialogs/FeatureSequenceDialog.d.ts +3 -1
- package/esm/BaseFeatureWidget/SequenceFeatureDetails/dialogs/FeatureSequenceDialog.js +2 -2
- package/esm/BaseFeatureWidget/SequenceFeatureDetails/dialogs/HelpDialog.d.ts +3 -2
- package/esm/BaseFeatureWidget/SequenceFeatureDetails/dialogs/HelpDialog.js +4 -2
- package/esm/BaseFeatureWidget/SequenceFeatureDetails/dialogs/SequenceDialog.d.ts +1 -2
- package/esm/BaseFeatureWidget/SequenceFeatureDetails/dialogs/SequenceDialog.js +2 -2
- package/esm/BaseFeatureWidget/SequenceFeatureDetails/dialogs/SequenceTypeSelector.d.ts +1 -2
- package/esm/BaseFeatureWidget/SequenceFeatureDetails/dialogs/SequenceTypeSelector.js +15 -36
- package/esm/BaseFeatureWidget/SequenceFeatureDetails/dialogs/TranscriptSelector.d.ts +3 -2
- package/esm/BaseFeatureWidget/SequenceFeatureDetails/dialogs/TranscriptSelector.js +4 -2
- package/esm/BaseFeatureWidget/SequenceFeatureDetails/featureTypeUtil.d.ts +4 -2
- package/esm/BaseFeatureWidget/SequenceFeatureDetails/featureTypeUtil.js +29 -20
- package/esm/BaseFeatureWidget/SequenceFeatureDetails/model.d.ts +13 -1
- package/esm/BaseFeatureWidget/SequenceFeatureDetails/model.js +28 -1
- package/esm/BaseFeatureWidget/SequenceFeatureDetails/seqtypes/CDNASequence.js +3 -3
- package/esm/BaseFeatureWidget/SequenceFeatureDetails/seqtypes/SequenceDisplay.js +2 -2
- package/esm/BaseFeatureWidget/stateModelFactory.d.ts +9 -0
- package/esm/BaseFeatureWidget/stateModelFactory.js +11 -0
- package/esm/BaseFeatureWidget/types.d.ts +2 -0
- package/esm/PluginManager.d.ts +7 -3
- package/esm/PluginManager.js +12 -3
- package/esm/ReExports/coreModules.generated.js +538 -518
- package/esm/ReExports/coreWorkerModules.generated.js +456 -438
- package/esm/ReExports/lazify.js +3 -2
- package/esm/ReExports/list.js +22 -6
- package/esm/ReExports/names.d.ts +1 -0
- package/esm/ReExports/names.generated.d.ts +2 -0
- package/esm/ReExports/names.generated.js +566 -0
- package/esm/ReExports/names.js +3 -0
- package/esm/TextSearch/TextSearchManager.d.ts +3 -3
- package/esm/TextSearch/TextSearchManager.js +6 -13
- package/esm/assemblyManager/assembly.d.ts +9 -0
- package/esm/assemblyManager/assembly.js +13 -0
- package/esm/assemblyManager/assemblyConfigSchema.d.ts +6 -1
- package/esm/assemblyManager/assemblyConfigSchema.js +23 -22
- package/esm/assemblyManager/assemblyManager.d.ts +11 -0
- package/esm/assemblyManager/assemblyManager.js +2 -0
- package/esm/assemblyManager/expandAssemblyConfigShorthand.d.ts +9 -0
- package/esm/assemblyManager/expandAssemblyConfigShorthand.js +23 -0
- package/esm/checkPlugins.js +10 -4
- package/esm/configuration/configurationSchema.d.ts +51 -100
- package/esm/configuration/configurationSchema.js +59 -225
- package/esm/configuration/configurationSchemaUnion.d.ts +2 -1
- package/esm/configuration/configurationSchemaUnion.js +2 -1
- package/esm/configuration/configurationSlot.d.ts +18 -64
- package/esm/configuration/configurationSlot.js +32 -98
- package/esm/configuration/fillLocations.d.ts +4 -2
- package/esm/configuration/fillLocations.js +9 -3
- package/esm/configuration/formatAboutConfigSchema.d.ts +2 -2
- package/esm/configuration/formatAboutConfigSchema.js +2 -2
- package/esm/configuration/formatDetailsConfigSchema.d.ts +2 -2
- package/esm/configuration/formatDetailsConfigSchema.js +7 -5
- package/esm/configuration/getConf.d.ts +7 -36
- package/esm/configuration/getConf.js +20 -41
- package/esm/configuration/index.d.ts +4 -3
- package/esm/configuration/index.js +3 -2
- package/esm/configuration/partitionAdvanced.d.ts +12 -0
- package/esm/configuration/partitionAdvanced.js +42 -0
- package/esm/configuration/plot.d.ts +6 -0
- package/esm/configuration/plot.js +56 -9
- package/esm/configuration/readConfObject.d.ts +15 -17
- package/esm/configuration/readConfObject.js +19 -50
- package/esm/configuration/schemaRegistry.d.ts +0 -2
- package/esm/configuration/schemaTypes.js +5 -1
- package/esm/configuration/slotFacade.js +2 -2
- package/esm/configuration/snapshotPreprocess.d.ts +42 -18
- package/esm/configuration/snapshotPreprocess.js +95 -37
- package/esm/configuration/tabixShorthand.js +1 -3
- package/esm/configuration/types.d.ts +60 -159
- package/esm/data_adapters/BaseAdapter/BaseAdapter.d.ts +7 -0
- package/esm/data_adapters/BaseAdapter/BaseAdapter.js +7 -0
- package/esm/data_adapters/BaseAdapter/BaseFeatureDataAdapter.d.ts +0 -22
- package/esm/data_adapters/BaseAdapter/BaseFeatureDataAdapter.js +0 -55
- package/esm/data_adapters/BaseAdapter/index.d.ts +0 -1
- package/esm/data_adapters/BaseAdapter/index.js +0 -1
- package/esm/data_adapters/BaseAdapter/rowSources.d.ts +2 -2
- package/esm/data_adapters/BaseAdapter/types.d.ts +1 -0
- package/esm/data_adapters/CytobandAdapter/configSchema.d.ts +2 -0
- package/esm/data_adapters/CytobandAdapter/configSchema.js +5 -0
- package/esm/data_adapters/dataAdapterCache.d.ts +25 -13
- package/esm/data_adapters/dataAdapterCache.js +68 -24
- package/esm/data_adapters/getFeatureAdapter.d.ts +9 -0
- package/esm/data_adapters/getFeatureAdapter.js +17 -0
- package/esm/pluggableElementTypes/DisplayType.d.ts +7 -0
- package/esm/pluggableElementTypes/DisplayType.js +7 -0
- package/esm/pluggableElementTypes/RpcMethodType.d.ts +7 -0
- package/esm/pluggableElementTypes/RpcMethodType.js +9 -0
- package/esm/pluggableElementTypes/addMenuItems.d.ts +2 -1
- package/esm/pluggableElementTypes/addMenuItems.js +2 -1
- package/esm/pluggableElementTypes/models/BaseConnectionModelFactory.d.ts +2 -0
- package/esm/pluggableElementTypes/models/BaseConnectionModelFactory.js +2 -0
- package/esm/pluggableElementTypes/models/BaseDisplayModel.d.ts +40 -5
- package/esm/pluggableElementTypes/models/BaseDisplayModel.js +57 -9
- package/esm/pluggableElementTypes/models/BaseTrackModel.d.ts +5 -7
- package/esm/pluggableElementTypes/models/BaseTrackModel.js +9 -10
- package/esm/pluggableElementTypes/models/BaseViewModel.d.ts +2 -0
- package/esm/pluggableElementTypes/models/BaseViewModel.js +2 -0
- package/esm/pluggableElementTypes/models/InternetAccountModel.d.ts +3 -0
- package/esm/pluggableElementTypes/models/InternetAccountModel.js +3 -0
- package/esm/pluggableElementTypes/models/baseConnectionConfig.d.ts +3 -0
- package/esm/pluggableElementTypes/models/baseConnectionConfig.js +3 -0
- package/esm/pluggableElementTypes/models/baseInternetAccountConfig.d.ts +3 -1
- package/esm/pluggableElementTypes/models/baseInternetAccountConfig.js +3 -1
- package/esm/pluggableElementTypes/models/baseTrackConfig.js +12 -1
- package/esm/pluggableElementTypes/models/components/SaveTrackData.js +2 -2
- package/esm/pluggableElementTypes/models/expandTrackConfigShorthand.d.ts +1 -1
- package/esm/pluggableElementTypes/models/expandTrackConfigShorthand.js +1 -1
- package/esm/pluginDefinitions.d.ts +7 -0
- package/esm/pluginDefinitions.js +20 -0
- package/esm/rpc/RpcRegistry.d.ts +2 -11
- package/esm/rpc/byteBudget.d.ts +15 -0
- package/esm/rpc/byteBudget.js +23 -0
- package/esm/rpc/configSchema.d.ts +2 -0
- package/esm/rpc/configSchema.js +3 -1
- package/esm/rpc/coreRpcMethods.d.ts +1 -2
- package/esm/rpc/coreRpcMethods.js +1 -2
- package/esm/rpc/explainTransferError.js +3 -3
- package/esm/rpc/methods/CoreGetEncodedLayers.d.ts +2 -2
- package/esm/rpc/methods/CoreGetEncodedLayers.js +7 -5
- package/esm/rpc/methods/CoreLoadTrackCode.d.ts +17 -0
- package/esm/rpc/methods/CoreLoadTrackCode.js +24 -0
- package/esm/rpc/methods/layerFeatures.d.ts +9 -6
- package/esm/rpc/methods/layerFeatures.js +21 -5
- package/esm/ui/ActionLink.d.ts +3 -2
- package/esm/ui/ActionLink.js +4 -2
- package/esm/ui/AddCustomPluginDialog.d.ts +3 -2
- package/esm/ui/AddCustomPluginDialog.js +6 -4
- package/esm/ui/AppLogo.js +43 -3
- package/esm/ui/BaseTooltip.d.ts +3 -2
- package/esm/ui/BaseTooltip.js +4 -2
- package/esm/ui/CascadingMenu.js +14 -12
- package/esm/ui/CascadingMenuButton.d.ts +2 -2
- package/esm/ui/CascadingMenuButton.js +5 -4
- package/esm/ui/CascadingMenuHelpDialog.d.ts +3 -2
- package/esm/ui/CascadingMenuHelpDialog.js +4 -2
- package/esm/ui/CascadingMenuHelpIconButton.d.ts +4 -3
- package/esm/ui/CascadingMenuHelpIconButton.js +9 -5
- package/esm/ui/ColorPicker.d.ts +5 -4
- package/esm/ui/ColorPicker.js +6 -4
- package/esm/ui/ContextMenu.d.ts +1 -1
- package/esm/ui/ContextMenu.js +1 -1
- package/esm/ui/CopyToClipboardButton.d.ts +3 -2
- package/esm/ui/CopyToClipboardButton.js +4 -2
- package/esm/ui/Crosshairs.js +13 -10
- package/esm/ui/DOMPurifySanitizedHTML.d.ts +3 -2
- package/esm/ui/DOMPurifySanitizedHTML.js +4 -2
- package/esm/ui/DataGridFlexContainer.d.ts +3 -2
- package/esm/ui/DataGridFlexContainer.js +4 -2
- package/esm/ui/Dialog.d.ts +1 -1
- package/esm/ui/Dialog.js +5 -4
- package/esm/ui/DropDownMenu.js +2 -2
- package/esm/ui/EditableTypography.d.ts +1 -1
- package/esm/ui/EditableTypography.js +3 -2
- package/esm/ui/ErrorActions.d.ts +3 -2
- package/esm/ui/ErrorActions.js +4 -2
- package/esm/ui/ErrorBanner.d.ts +2 -2
- package/esm/ui/ErrorBanner.js +3 -2
- package/esm/ui/ErrorBar.d.ts +3 -2
- package/esm/ui/ErrorBar.js +4 -2
- package/esm/ui/ErrorMessage.d.ts +3 -2
- package/esm/ui/ErrorMessage.js +4 -2
- package/esm/ui/ErrorMessageStackTraceContents.d.ts +3 -2
- package/esm/ui/ErrorMessageStackTraceContents.js +4 -2
- package/esm/ui/ErrorMessageStackTraceDialog.d.ts +3 -2
- package/esm/ui/ErrorMessageStackTraceDialog.js +4 -2
- package/esm/ui/ErrorOverlay.d.ts +3 -2
- package/esm/ui/ErrorOverlay.js +4 -2
- package/esm/ui/ExportSvgDialog.d.ts +3 -2
- package/esm/ui/ExportSvgDialog.js +4 -2
- package/esm/ui/ExternalLink.d.ts +2 -1
- package/esm/ui/ExternalLink.js +4 -2
- package/esm/ui/FactoryResetDialog.d.ts +3 -2
- package/esm/ui/FactoryResetDialog.js +4 -2
- package/esm/ui/FatalErrorDialog.d.ts +3 -2
- package/esm/ui/FatalErrorDialog.js +6 -4
- package/esm/ui/FileDropZone.d.ts +3 -2
- package/esm/ui/FileDropZone.js +4 -2
- package/esm/ui/FileSelector/LocalFileChooser.js +4 -4
- package/esm/ui/FileSelector/LocationInput.d.ts +3 -2
- package/esm/ui/FileSelector/LocationInput.js +4 -2
- package/esm/ui/FileSelector/SourceTypeSelector.d.ts +3 -2
- package/esm/ui/FileSelector/SourceTypeSelector.js +8 -6
- package/esm/ui/GpuFallbackButton.d.ts +3 -2
- package/esm/ui/GpuFallbackButton.js +4 -2
- package/esm/ui/HoverMenu.d.ts +2 -2
- package/esm/ui/HoverMenu.js +7 -3
- package/esm/ui/HoverTooltip.d.ts +3 -2
- package/esm/ui/HoverTooltip.js +4 -2
- package/esm/ui/Icons.d.ts +5 -5
- package/esm/ui/Icons.js +11 -10
- package/esm/ui/InlineMenuControls.d.ts +2 -2
- package/esm/ui/InlineMenuControls.js +4 -3
- package/esm/ui/JexlFilterRowEditors.d.ts +4 -4
- package/esm/ui/JexlFilterRowEditors.js +9 -8
- package/esm/ui/LabeledCheckbox.d.ts +3 -2
- package/esm/ui/LabeledCheckbox.js +4 -2
- package/esm/ui/LazyBaseTooltip.d.ts +12 -3
- package/esm/ui/LazyBaseTooltip.js +4 -2
- package/esm/ui/LegendSwatchGlyph.js +1 -0
- package/esm/ui/LoadingDots.d.ts +2 -1
- package/esm/ui/LoadingDots.js +4 -2
- package/esm/ui/LoadingEllipses.d.ts +5 -2
- package/esm/ui/LoadingEllipses.js +5 -3
- package/esm/ui/LoadingOverlay.d.ts +3 -2
- package/esm/ui/LoadingOverlay.js +4 -2
- package/esm/ui/LoadingProgress.d.ts +3 -2
- package/esm/ui/LoadingProgress.js +4 -2
- package/esm/ui/Logo.d.ts +2 -2
- package/esm/ui/Logo.js +9 -8
- package/esm/ui/MenuItemChevron.d.ts +2 -2
- package/esm/ui/MenuItemChevron.js +3 -2
- package/esm/ui/MenuItemEndDecoration.d.ts +2 -2
- package/esm/ui/MenuItemEndDecoration.js +3 -2
- package/esm/ui/MenuItemTrailing.d.ts +2 -2
- package/esm/ui/MenuItemTrailing.js +7 -6
- package/esm/ui/MenuTypes.d.ts +21 -1
- package/esm/ui/MenuTypes.js +20 -0
- package/esm/ui/MonospaceTextField.d.ts +3 -2
- package/esm/ui/MonospaceTextField.js +4 -2
- package/esm/ui/NumberTextField.d.ts +2 -2
- package/esm/ui/NumberTextField.js +4 -2
- package/esm/ui/PaletteContext.d.ts +11 -9
- package/esm/ui/PaletteContext.js +33 -18
- package/esm/ui/PluginStoreCard.d.ts +3 -2
- package/esm/ui/PluginStoreCard.js +4 -2
- package/esm/ui/PopoverPicker.d.ts +3 -2
- package/esm/ui/PopoverPicker.js +4 -2
- package/esm/ui/PrerenderedCanvas.d.ts +2 -2
- package/esm/ui/PrerenderedCanvas.js +3 -2
- package/esm/ui/RedErrorMessageBox.d.ts +3 -2
- package/esm/ui/RedErrorMessageBox.js +4 -2
- package/esm/ui/RefNameAutocomplete/EndAdornment.d.ts +3 -2
- package/esm/ui/RefNameAutocomplete/EndAdornment.js +4 -2
- package/esm/ui/RefNameAutocomplete/HelpDialog.d.ts +3 -2
- package/esm/ui/RefNameAutocomplete/HelpDialog.js +4 -2
- package/esm/ui/ReplaceCurrentViewButton.d.ts +3 -2
- package/esm/ui/ReplaceCurrentViewButton.js +4 -2
- package/esm/ui/ResizeHandle.d.ts +2 -2
- package/esm/ui/ResizeHandle.js +3 -2
- package/esm/ui/SanitizedHTML.d.ts +3 -2
- package/esm/ui/SanitizedHTML.js +6 -4
- package/esm/ui/ScrollChrome.d.ts +3 -2
- package/esm/ui/ScrollChrome.js +4 -2
- package/esm/ui/ScrollEdgeShadow.d.ts +2 -2
- package/esm/ui/ScrollEdgeShadow.js +2 -2
- package/esm/ui/SessionJsonPanel.d.ts +3 -2
- package/esm/ui/SessionJsonPanel.js +4 -2
- package/esm/ui/ShareLinkField.d.ts +3 -2
- package/esm/ui/ShareLinkField.js +4 -2
- package/esm/ui/SingleSlider.d.ts +2 -2
- package/esm/ui/SingleSlider.js +4 -2
- package/esm/ui/SliderTooltip.d.ts +2 -1
- package/esm/ui/SliderTooltip.js +4 -2
- package/esm/ui/SnackbarContents.d.ts +3 -2
- package/esm/ui/SnackbarContents.js +4 -2
- package/esm/ui/SnackbarModel.d.ts +2 -0
- package/esm/ui/SnackbarModel.js +2 -0
- package/esm/ui/StackTraceButton.d.ts +3 -2
- package/esm/ui/StackTraceButton.js +4 -2
- package/esm/ui/StatusProgressBar.d.ts +3 -2
- package/esm/ui/StatusProgressBar.js +4 -2
- package/esm/ui/SubmitForm.d.ts +2 -1
- package/esm/ui/SubmitForm.js +4 -2
- package/esm/ui/SvgColorLegend.d.ts +3 -4
- package/esm/ui/SvgColorLegend.js +27 -18
- package/esm/ui/TagTextField.d.ts +2 -2
- package/esm/ui/TagTextField.js +4 -2
- package/esm/ui/ViewLoadingScreen.d.ts +3 -2
- package/esm/ui/ViewLoadingScreen.js +4 -2
- package/esm/ui/buildExtraTrackMenuItems.d.ts +2 -2
- package/esm/ui/colorScale.d.ts +5 -1
- package/esm/ui/colorScale.js +12 -10
- package/esm/ui/colors.d.ts +42 -31
- package/esm/ui/colors.js +85 -48
- package/esm/ui/filterMenuItems.d.ts +10 -31
- package/esm/ui/filterMenuItems.js +13 -14
- package/esm/ui/index.d.ts +1 -1
- package/esm/ui/index.js +1 -1
- package/esm/ui/launchTargetsMenuItem.js +9 -13
- package/esm/ui/legendMenuItem.d.ts +4 -4
- package/esm/ui/legendMenuItem.js +4 -4
- package/esm/ui/menuItemAdornment.d.ts +1 -1
- package/esm/ui/menuItemAdornment.js +1 -1
- package/esm/ui/menuItems.d.ts +1 -1
- package/esm/ui/menuItems.js +1 -1
- package/esm/ui/menuLabels.d.ts +2 -2
- package/esm/ui/menuLabels.js +2 -2
- package/esm/ui/multiTrackMenuItems.d.ts +2 -2
- package/esm/ui/palette.d.ts +2 -2
- package/esm/ui/palette.js +10 -10
- package/esm/ui/radioSubMenu.d.ts +5 -3
- package/esm/ui/radioSubMenu.js +2 -2
- package/esm/ui/rampKey.d.ts +15 -0
- package/esm/ui/rampKey.js +17 -0
- package/esm/ui/showSubMenu.d.ts +0 -5
- package/esm/ui/showSubMenu.js +6 -15
- package/esm/ui/theme.d.ts +2 -2
- package/esm/ui/theme.js +1 -1
- package/esm/ui/useAssemblySelection.d.ts +2 -0
- package/esm/ui/useMouseTracking.d.ts +8 -20
- package/esm/ui/useMouseTracking.js +23 -62
- package/esm/ui/usePlacedMenuFocus.d.ts +19 -0
- package/esm/ui/usePlacedMenuFocus.js +28 -0
- package/esm/util/Base1DViewModel.d.ts +5 -3
- package/esm/util/Base1DViewModel.js +5 -3
- package/esm/util/SvgCanvas.js +1 -1
- package/esm/util/aggregateFieldName.d.ts +1 -10
- package/esm/util/aggregateFieldName.js +1 -8
- package/esm/util/alignedBytes.d.ts +19 -0
- package/esm/util/alignedBytes.js +37 -0
- package/esm/util/analytics.d.ts +6 -9
- package/esm/util/analytics.js +148 -15
- package/esm/util/bezierConnector.d.ts +20 -0
- package/esm/util/bezierConnector.js +34 -96
- package/esm/util/cacheBudgets.d.ts +3 -0
- package/esm/util/cacheBudgets.js +3 -0
- package/esm/util/categoricalField.d.ts +24 -4
- package/esm/util/categoricalField.js +38 -5
- package/esm/util/cellMatches.js +14 -14
- package/esm/util/cellsStep.d.ts +3 -5
- package/esm/util/cellsStep.js +31 -29
- package/esm/util/color/index.d.ts +1 -1
- package/esm/util/color/index.js +2 -2
- package/esm/util/color-bits/bit.js +1 -1
- package/esm/util/color-bits/parse.js +28 -17
- package/esm/util/colorBits.d.ts +15 -4
- package/esm/util/colorBits.js +38 -15
- package/esm/util/colorRamp.d.ts +3 -3
- package/esm/util/colorRamp.js +20 -2
- package/esm/util/colorScale.d.ts +123 -22
- package/esm/util/colorScale.js +157 -28
- package/esm/util/colorSchemes.d.ts +7 -3
- package/esm/util/colorSchemes.js +8 -2
- package/esm/util/createSvgRasterCanvas.d.ts +14 -1
- package/esm/util/createSvgRasterCanvas.js +36 -12
- package/esm/util/diagonalizeRegions.js +18 -9
- package/esm/util/featureTransforms.d.ts +2 -2
- package/esm/util/featureTransforms.js +85 -135
- package/esm/util/fileHandleStore.js +5 -0
- package/esm/util/groupKeys.d.ts +5 -4
- package/esm/util/groupKeys.js +15 -9
- package/esm/util/index.js +1 -1
- package/esm/util/installFetch.d.ts +2 -2
- package/esm/util/installPrerequisiteFetch.d.ts +8 -3
- package/esm/util/installPrerequisiteFetch.js +9 -7
- package/esm/util/io/RemoteFileWithRangeCache.d.ts +1 -1
- package/esm/util/io/RemoteFileWithRangeCache.js +1 -1
- package/esm/util/isoformRank.d.ts +39 -0
- package/esm/util/isoformRank.js +118 -0
- package/esm/util/jexl.js +1 -1
- package/esm/util/layouts/GranularRectLayout.d.ts +19 -3
- package/esm/util/layouts/GranularRectLayout.js +57 -34
- package/esm/util/leadingEdgeAutorun.d.ts +9 -1
- package/esm/util/leadingEdgeAutorun.js +5 -2
- package/esm/util/markEncoding.d.ts +10 -8
- package/esm/util/markEncoding.js +50 -12
- package/esm/util/markEncodingTypes.d.ts +77 -21
- package/esm/util/originCut.d.ts +14 -0
- package/esm/util/originCut.js +19 -0
- package/esm/util/paintLayer.d.ts +1 -1
- package/esm/util/paintLayer.js +4 -3
- package/esm/util/pathSeries.d.ts +18 -0
- package/esm/util/pathSeries.js +143 -0
- package/esm/util/pressOwner.d.ts +20 -0
- package/esm/util/pressOwner.js +26 -0
- package/esm/util/quantileExtent.d.ts +23 -1
- package/esm/util/quantileExtent.js +25 -2
- package/esm/util/rowStackGeometry.d.ts +1 -1
- package/esm/util/rowStackGeometry.js +1 -1
- package/esm/util/sessionActivity.d.ts +36 -0
- package/esm/util/sessionActivity.js +88 -0
- package/esm/util/stepOutputs.d.ts +165 -0
- package/esm/util/stepOutputs.js +201 -0
- package/esm/util/stepTables.d.ts +7 -3
- package/esm/util/stepTables.js +86 -3
- package/esm/util/systemColorScheme.d.ts +4 -0
- package/esm/util/systemColorScheme.js +21 -0
- package/esm/util/tabix.d.ts +1 -1
- package/esm/util/tabix.js +1 -1
- package/esm/util/temporaryAssembly.d.ts +2 -2
- package/esm/util/temporaryAssembly.js +2 -3
- package/esm/util/thresholdScale.d.ts +1 -1
- package/esm/util/thresholdScale.js +1 -1
- package/esm/util/trackConfigDelta.d.ts +1 -1
- package/esm/util/tracks.d.ts +25 -15
- package/esm/util/tracks.js +68 -44
- package/esm/util/types/index.d.ts +15 -7
- package/esm/util/types/index.js +21 -2
- package/esm/util/usePanZoom.js +4 -10
- package/esm/util/useRowVirtualScroll.d.ts +1 -0
- package/esm/util/windowStep.d.ts +6 -0
- package/esm/util/windowStep.js +153 -0
- package/package.json +27 -16
- package/esm/data_adapters/BaseAdapter/featureDensity.d.ts +0 -40
- package/esm/data_adapters/BaseAdapter/featureDensity.js +0 -31
- package/esm/rpc/methods/CoreGetFeatureDensity.d.ts +0 -11
- package/esm/rpc/methods/CoreGetFeatureDensity.js +0 -22
- package/esm/rpc/methods/CoreLoadAdapterCode.d.ts +0 -13
- package/esm/rpc/methods/CoreLoadAdapterCode.js +0 -16
package/esm/util/analytics.js
CHANGED
|
@@ -1,14 +1,59 @@
|
|
|
1
1
|
import { effectiveRenderer, getGraphicsCapabilities, } from '@jbrowse/render-core/graphicsCapabilities';
|
|
2
2
|
import { readConfObject } from '../configuration/index.js';
|
|
3
3
|
import { isElectron, rIC } from '../util/index.js';
|
|
4
|
+
import { createSessionActivity, describeSession, tallyTypes, } from './sessionActivity.js';
|
|
5
|
+
import { getConfAssemblyNamesOrNone } from './tracks.js';
|
|
6
|
+
const analyticsUrl = 'https://analytics.jbrowse.org/api/v1';
|
|
7
|
+
// Ties a page load's end reports to its start report. It lives in memory only,
|
|
8
|
+
// so a reload gets a new one and nothing follows a user from load to load.
|
|
9
|
+
let pageLoadId;
|
|
10
|
+
function getPageLoadId() {
|
|
11
|
+
pageLoadId ??=
|
|
12
|
+
typeof crypto.randomUUID === 'function'
|
|
13
|
+
? crypto.randomUUID()
|
|
14
|
+
: `${Date.now().toString(36)}-${Math.random().toString(36).slice(2)}`;
|
|
15
|
+
return pageLoadId;
|
|
16
|
+
}
|
|
17
|
+
// Names only, and only JBrowse's own: says whether a load was a link to a
|
|
18
|
+
// location or a set of tracks without saying which. Read when this module
|
|
19
|
+
// loads, because jbrowse-web folds `loc`, `tracks` and `assembly` into a
|
|
20
|
+
// `session` parameter before the report goes out.
|
|
21
|
+
const knownUrlParams = [
|
|
22
|
+
'assembly',
|
|
23
|
+
'config',
|
|
24
|
+
'highlight',
|
|
25
|
+
'loc',
|
|
26
|
+
'nav',
|
|
27
|
+
'session',
|
|
28
|
+
'sessionName',
|
|
29
|
+
'sessionTracks',
|
|
30
|
+
'tracklist',
|
|
31
|
+
'tracks',
|
|
32
|
+
];
|
|
33
|
+
export function urlParamNames(search) {
|
|
34
|
+
const params = new URLSearchParams(search);
|
|
35
|
+
return knownUrlParams.filter(name => params.has(name)).join(',');
|
|
36
|
+
}
|
|
37
|
+
const initialUrlParams = typeof window === 'undefined' ? '' : urlParamNames(window.location.search);
|
|
38
|
+
function sessionTrackTypeCounts(session) {
|
|
39
|
+
const counts = {};
|
|
40
|
+
for (const track of session?.sessionTracks ?? []) {
|
|
41
|
+
const key = `sessionTrack-types-${track.type}`;
|
|
42
|
+
counts[key] = (counts[key] ?? 0) + 1;
|
|
43
|
+
}
|
|
44
|
+
return counts;
|
|
45
|
+
}
|
|
46
|
+
async function send(stats, init) {
|
|
47
|
+
const qs = new URLSearchParams(Object.entries(stats).map(([key, value]) => [key, String(value)])).toString();
|
|
48
|
+
await fetch(`${analyticsUrl}?${qs}`, init);
|
|
49
|
+
}
|
|
4
50
|
// Both writers are fire-and-forget from several call sites, so they swallow
|
|
5
51
|
// their own failures rather than rejecting: a floating rejected promise trips
|
|
6
52
|
// the webpack-dev-server overlay (it listens for unhandledrejection), and an
|
|
7
53
|
// analytics ping is never worth interrupting a session for.
|
|
8
54
|
export async function writeAWSAnalytics(rootModel, initialTimestamp, sessionQuery) {
|
|
9
55
|
try {
|
|
10
|
-
const
|
|
11
|
-
const multiAssemblyTracks = rootModel.jbrowse.tracks.filter(track => readConfObject(track, 'assemblyNames').length > 1).length;
|
|
56
|
+
const multiAssemblyTracks = rootModel.jbrowse.tracks.filter(track => getConfAssemblyNamesOrNone(track).length > 1).length;
|
|
12
57
|
// The rung createGpuHal built where a display has built one by idle time,
|
|
13
58
|
// else the ladder's prediction with any page-wide pin applied — so a
|
|
14
59
|
// session that fell back to Canvas2D is counted as Canvas2D rather than as
|
|
@@ -24,8 +69,11 @@ export async function writeAWSAnalytics(rootModel, initialTimestamp, sessionQuer
|
|
|
24
69
|
const softwareRendering = capabilities.softwareWebgl ?? 'unknown';
|
|
25
70
|
const { jbrowse: config, session, version: ver } = rootModel;
|
|
26
71
|
const { tracks, assemblies, plugins } = config;
|
|
72
|
+
const shape = describeSession(session);
|
|
27
73
|
// stats to be recorded in db
|
|
28
74
|
const stats = {
|
|
75
|
+
event: 'start',
|
|
76
|
+
sid: getPageLoadId(),
|
|
29
77
|
ver,
|
|
30
78
|
'plugins-count': plugins?.length ?? 0,
|
|
31
79
|
'plugin-names': plugins?.map(p => p.name).join(','),
|
|
@@ -33,6 +81,9 @@ export async function writeAWSAnalytics(rootModel, initialTimestamp, sessionQuer
|
|
|
33
81
|
'tracks-count': tracks.length,
|
|
34
82
|
'session-tracks-count': session?.sessionTracks.length ?? 0,
|
|
35
83
|
'open-views': session?.views.length ?? 0,
|
|
84
|
+
'view-types': tallyTypes(shape.viewTypes),
|
|
85
|
+
'open-track-types': tallyTypes(shape.trackTypes),
|
|
86
|
+
'url-params': initialUrlParams,
|
|
36
87
|
'synteny-tracks-count': multiAssemblyTracks,
|
|
37
88
|
// No `saved-sessions-count`: it counted localStorage keys matching
|
|
38
89
|
// `localSaved-`, a format nothing has written since autosaved sessions
|
|
@@ -61,14 +112,8 @@ export async function writeAWSAnalytics(rootModel, initialTimestamp, sessionQuer
|
|
|
61
112
|
const key = `track-types-${track.type}`;
|
|
62
113
|
trackTypeCounts[key] = (trackTypeCounts[key] ?? 0) + 1;
|
|
63
114
|
}
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
const key = `sessionTrack-types-${track.type}`;
|
|
67
|
-
sessionTrackTypeCounts[key] = (sessionTrackTypeCounts[key] ?? 0) + 1;
|
|
68
|
-
}
|
|
69
|
-
Object.assign(stats, trackTypeCounts, sessionTrackTypeCounts);
|
|
70
|
-
const qs = new URLSearchParams(Object.entries(stats).map(([key, value]) => [key, String(value)])).toString();
|
|
71
|
-
await fetch(`${url}?${qs}`);
|
|
115
|
+
Object.assign(stats, trackTypeCounts, sessionTrackTypeCounts(session));
|
|
116
|
+
await send(stats);
|
|
72
117
|
}
|
|
73
118
|
catch (e) {
|
|
74
119
|
console.warn('Failed to write analytics to AWS.', e);
|
|
@@ -108,6 +153,83 @@ export async function writeGAAnalytics(rootModel, initialTimestamp) {
|
|
|
108
153
|
console.warn('Failed to write analytics to GA.', e);
|
|
109
154
|
}
|
|
110
155
|
}
|
|
156
|
+
// What the page load's sessions held while in use, for the end report.
|
|
157
|
+
const activity = createSessionActivity();
|
|
158
|
+
let latestRootModel;
|
|
159
|
+
let endReportsInstalled = false;
|
|
160
|
+
let endReportsSent = 0;
|
|
161
|
+
let lastEndSignature;
|
|
162
|
+
let visibleMs = 0;
|
|
163
|
+
let visibleSince;
|
|
164
|
+
let visibleMsAtLastEnd = 0;
|
|
165
|
+
const maxEndReports = 10;
|
|
166
|
+
const resendAfterVisibleMs = 60_000;
|
|
167
|
+
// The end report says what a session came to hold: the view, track and widget
|
|
168
|
+
// types open when the tab was hidden and those opened at any point before.
|
|
169
|
+
// A tab is hidden many times before it closes and the close itself is not
|
|
170
|
+
// reliably observable, so each hide sends one, numbered by `seq`, when the
|
|
171
|
+
// session changed or another minute was spent on the page. The last one for a
|
|
172
|
+
// `sid` is the session's end.
|
|
173
|
+
export async function writeAWSSessionEnd() {
|
|
174
|
+
try {
|
|
175
|
+
if (!activity.watching || endReportsSent >= maxEndReports) {
|
|
176
|
+
return;
|
|
177
|
+
}
|
|
178
|
+
const seen = activity.stats();
|
|
179
|
+
const signature = JSON.stringify(seen);
|
|
180
|
+
if (signature === lastEndSignature &&
|
|
181
|
+
visibleMs - visibleMsAtLastEnd < resendAfterVisibleMs) {
|
|
182
|
+
return;
|
|
183
|
+
}
|
|
184
|
+
lastEndSignature = signature;
|
|
185
|
+
visibleMsAtLastEnd = visibleMs;
|
|
186
|
+
endReportsSent += 1;
|
|
187
|
+
const stats = {
|
|
188
|
+
event: 'end',
|
|
189
|
+
sid: getPageLoadId(),
|
|
190
|
+
seq: endReportsSent,
|
|
191
|
+
duration: Math.round(performance.now() / 1000),
|
|
192
|
+
'visible-time': Math.round(visibleMs / 1000),
|
|
193
|
+
...seen,
|
|
194
|
+
electron: isElectron,
|
|
195
|
+
jb2: true,
|
|
196
|
+
};
|
|
197
|
+
try {
|
|
198
|
+
const { session, version } = latestRootModel ?? {};
|
|
199
|
+
stats.ver = version;
|
|
200
|
+
stats['session-tracks-count'] = session?.sessionTracks.length ?? 0;
|
|
201
|
+
Object.assign(stats, sessionTrackTypeCounts(session));
|
|
202
|
+
}
|
|
203
|
+
catch {
|
|
204
|
+
// root model left its state tree; the accumulated types still go out
|
|
205
|
+
}
|
|
206
|
+
// keepalive lets the request outlive the page it was sent from
|
|
207
|
+
await send(stats, { keepalive: true });
|
|
208
|
+
}
|
|
209
|
+
catch (e) {
|
|
210
|
+
console.warn('Failed to write analytics to AWS.', e);
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
function installEndReports() {
|
|
214
|
+
if (!endReportsInstalled) {
|
|
215
|
+
endReportsInstalled = true;
|
|
216
|
+
if (document.visibilityState === 'visible') {
|
|
217
|
+
visibleSince = performance.now();
|
|
218
|
+
}
|
|
219
|
+
document.addEventListener('visibilitychange', () => {
|
|
220
|
+
if (document.visibilityState === 'hidden') {
|
|
221
|
+
if (visibleSince !== undefined) {
|
|
222
|
+
visibleMs += performance.now() - visibleSince;
|
|
223
|
+
visibleSince = undefined;
|
|
224
|
+
}
|
|
225
|
+
void writeAWSSessionEnd();
|
|
226
|
+
}
|
|
227
|
+
else {
|
|
228
|
+
visibleSince = performance.now();
|
|
229
|
+
}
|
|
230
|
+
});
|
|
231
|
+
}
|
|
232
|
+
}
|
|
111
233
|
// One pageview per page load, not per pluginManager. jbrowse-web rebuilds the
|
|
112
234
|
// whole pluginManager (and rootModel) whenever plugins change, and StrictMode
|
|
113
235
|
// builds it twice on mount — without this guard each rebuild re-pings AWS and
|
|
@@ -115,9 +237,19 @@ export async function writeGAAnalytics(rootModel, initialTimestamp) {
|
|
|
115
237
|
// growing the document on every plugin install.
|
|
116
238
|
let analyticsSent = false;
|
|
117
239
|
export function doAnalytics(rootModel, initialTimestamp, initialSessionQuery) {
|
|
118
|
-
if (rootModel
|
|
119
|
-
|
|
120
|
-
|
|
240
|
+
if (!rootModel) {
|
|
241
|
+
return;
|
|
242
|
+
}
|
|
243
|
+
// a config that opts out stops the end reports too, whichever config or
|
|
244
|
+
// session started them
|
|
245
|
+
if (readConfObject(rootModel.jbrowse.configuration, 'disableAnalytics')) {
|
|
246
|
+
activity.stop();
|
|
247
|
+
return;
|
|
248
|
+
}
|
|
249
|
+
latestRootModel = rootModel;
|
|
250
|
+
activity.watch(() => rootModel.session);
|
|
251
|
+
installEndReports();
|
|
252
|
+
if (!analyticsSent) {
|
|
121
253
|
analyticsSent = true;
|
|
122
254
|
// writeGAAnalytics injects Google's scripts and writeAWSAnalytics probes
|
|
123
255
|
// graphics capabilities, hundreds of ms of main-thread work together. Idle
|
|
@@ -138,7 +270,8 @@ export function doAnalytics(rootModel, initialTimestamp, initialSessionQuery) {
|
|
|
138
270
|
// `[data-app-phase="ready"]`, or a timeout for a page that never shows one
|
|
139
271
|
// (Desktop's start screen)
|
|
140
272
|
function afterAppReady(callback, maxWaitMs = 10_000) {
|
|
141
|
-
const
|
|
273
|
+
const doc = document;
|
|
274
|
+
const isReady = () => doc.querySelector('[data-app-phase="ready"]') !== null;
|
|
142
275
|
if (isReady()) {
|
|
143
276
|
callback();
|
|
144
277
|
return;
|
|
@@ -158,7 +291,7 @@ function afterAppReady(callback, maxWaitMs = 10_000) {
|
|
|
158
291
|
}
|
|
159
292
|
});
|
|
160
293
|
const timer = setTimeout(finish, maxWaitMs);
|
|
161
|
-
observer.observe(
|
|
294
|
+
observer.observe(doc.body, {
|
|
162
295
|
subtree: true,
|
|
163
296
|
childList: true,
|
|
164
297
|
attributeFilter: ['data-app-phase'],
|
|
@@ -1,5 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A symmetric cubic's extreme sits 3/4 of the way from its baseline to its
|
|
3
|
+
* controls; the sashimi labels solve the same equation in the other direction.
|
|
4
|
+
*/
|
|
1
5
|
export declare const CUBIC_APEX_RATIO = 0.75;
|
|
6
|
+
/**
|
|
7
|
+
* How far a curve can stray outside the band between its two endpoints, which
|
|
8
|
+
* a culler pads its viewport test by.
|
|
9
|
+
*/
|
|
2
10
|
export declare const BEZIER_CONNECTOR_MAX_REACH_PX = 110;
|
|
11
|
+
/**
|
|
12
|
+
* One horizontal-tangent connector curve as an SVG path: the read and
|
|
13
|
+
* breakpoint connector BreakpointSplitView's AlignmentConnections draws, and
|
|
14
|
+
* the alignments display draws as render-core's `connector` mark. The
|
|
15
|
+
* geometry is that shader's own, through its JS twin, so the two views cannot
|
|
16
|
+
* drift in which way a connection leaves its read.
|
|
17
|
+
*
|
|
18
|
+
* A discordant connection dips below its ends instead of bowing up over them,
|
|
19
|
+
* so the two classes read apart at a glance. How deep is the caller's call:
|
|
20
|
+
* only it knows the band the ink has to survive in, and `discordantDipPx`
|
|
21
|
+
* (@jbrowse/sv-core) is the law the two views share.
|
|
22
|
+
*/
|
|
3
23
|
export declare function bezierConnectorPath({ x1, y1, x2, y2, s1, s2, leadingEnd2, reversed1, reversed2, maxHandlePx, dipPx, }: {
|
|
4
24
|
x1: number;
|
|
5
25
|
y1: number;
|
|
@@ -1,101 +1,39 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
// other direction, and the two spellings drifting apart would put the insert-
|
|
26
|
-
// size ruler's labels at heights nothing plots at.
|
|
27
|
-
export const CUBIC_APEX_RATIO = 0.75;
|
|
28
|
-
// Vertical bow applied to a connection whose two endpoints share (or nearly
|
|
29
|
-
// share) a row — e.g. a chain whose split segments are all laid out on one
|
|
30
|
-
// pileup row. Without it the horizontal-only handles collapse the cubic to a
|
|
31
|
-
// flat, invisible line lying on the row; the bow lifts the control points so
|
|
32
|
-
// the curve arcs into a visible hump. This is the control-point lift, not the
|
|
33
|
-
// height the curve reaches.
|
|
34
|
-
const MAX_BOW_PX = 30;
|
|
35
|
-
// A discordant connection bows *down* instead of up, so the two classes read
|
|
36
|
-
// apart at a glance. Both renderers follow this: BreakpointSplitView dips its
|
|
37
|
-
// same-level discordant links, and the pileup overlay dips every discordant
|
|
38
|
-
// curve it draws (a normal-orientation pair is a plain line, or bows up over its
|
|
39
|
-
// row where a hidden-segment one would lie on a chain's connecting line). Keep
|
|
40
|
-
// it that way — a renderer that opts out makes "below the reads" mean two
|
|
41
|
-
// different things in two views of the same data.
|
|
42
|
-
//
|
|
43
|
-
// HOW DEEP is the renderer's call, not this file's. Depth is the mark's one free
|
|
44
|
-
// channel, and only the renderer knows the band the ink has to survive in — the
|
|
45
|
-
// pileup clips each section at its band bottom, and the split view bleeds a
|
|
46
|
-
// too-deep dip into the panel below. So callers pass the depth they want and
|
|
47
|
-
// `discordantDipPx` (@jbrowse/sv-core) is the law the two of them share.
|
|
48
|
-
// How far a curve can stray outside the band between its two endpoints. The dip
|
|
49
|
-
// is the deeper of the two shaping terms, so this is a ceiling on it, applied
|
|
50
|
-
// here rather than trusted to a caller: a culler pads its viewport test by this,
|
|
51
|
-
// and the shaping is applied to the *control points*, so a curve whose two
|
|
52
|
-
// endpoints both sit just outside the viewport can still have a visible body.
|
|
53
|
-
export const BEZIER_CONNECTOR_MAX_REACH_PX = 110;
|
|
54
|
-
// Sign (+1/-1) of an endpoint's horizontal control handle. The handle leaves a
|
|
55
|
-
// trailing (3') endpoint along the read's reading direction (`strand`); at a
|
|
56
|
-
// split junction's leading (5') endpoint it flips, so the curve arrives flowing
|
|
57
|
-
// *into* the next segment (a fwd→rev inversion folds back instead of cutting
|
|
58
|
-
// straight across). `reversed` flips screen-x for a reverse-complemented region.
|
|
59
|
-
function tangentSign(strand, leading, reversed) {
|
|
60
|
-
return strand * (leading ? -1 : 1) * (reversed ? -1 : 1);
|
|
61
|
-
}
|
|
62
|
-
// How much shaping (handle length, bow height) this curve may spend: a fraction
|
|
63
|
-
// of the distance it has to cover.
|
|
64
|
-
function shapingBudget(p1, p2) {
|
|
65
|
-
return Math.hypot(p2.x - p1.x, p2.y - p1.y) * SPAN_FACTOR;
|
|
66
|
-
}
|
|
67
|
-
// Fades to zero as the endpoints' rows separate, since a cross-row curve
|
|
68
|
-
// already has vertical extent — and via the budget as they close in
|
|
69
|
-
// horizontally, since a short connector is legible without a hump.
|
|
70
|
-
function bowHeight(p1, p2, budget) {
|
|
71
|
-
return Math.min(budget, Math.max(0, MAX_BOW_PX - Math.abs(p2.y - p1.y)));
|
|
72
|
-
}
|
|
73
|
-
function cubicPath(from, ctrl1, ctrl2, to) {
|
|
74
|
-
return `M ${from.x} ${from.y} C ${ctrl1.x} ${ctrl1.y} ${ctrl2.x} ${ctrl2.y} ${to.x} ${to.y}`;
|
|
75
|
-
}
|
|
1
|
+
import { connectorBudgetPx, connectorHandlePx, connectorLiftPx, connectorTangent, } from '@jbrowse/render-core/shaders/connectorMark';
|
|
2
|
+
import { CONNECTOR_APEX_RATIO, CONNECTOR_BOW, CONNECTOR_MAX_HANDLE_PX, CONNECTOR_MAX_REACH_PX, } from '@jbrowse/render-core/shaders/connectorMarkConsts';
|
|
3
|
+
/**
|
|
4
|
+
* A symmetric cubic's extreme sits 3/4 of the way from its baseline to its
|
|
5
|
+
* controls; the sashimi labels solve the same equation in the other direction.
|
|
6
|
+
*/
|
|
7
|
+
export const CUBIC_APEX_RATIO = CONNECTOR_APEX_RATIO;
|
|
8
|
+
/**
|
|
9
|
+
* How far a curve can stray outside the band between its two endpoints, which
|
|
10
|
+
* a culler pads its viewport test by.
|
|
11
|
+
*/
|
|
12
|
+
export const BEZIER_CONNECTOR_MAX_REACH_PX = CONNECTOR_MAX_REACH_PX;
|
|
13
|
+
/**
|
|
14
|
+
* One horizontal-tangent connector curve as an SVG path: the read and
|
|
15
|
+
* breakpoint connector BreakpointSplitView's AlignmentConnections draws, and
|
|
16
|
+
* the alignments display draws as render-core's `connector` mark. The
|
|
17
|
+
* geometry is that shader's own, through its JS twin, so the two views cannot
|
|
18
|
+
* drift in which way a connection leaves its read.
|
|
19
|
+
*
|
|
20
|
+
* A discordant connection dips below its ends instead of bowing up over them,
|
|
21
|
+
* so the two classes read apart at a glance. How deep is the caller's call:
|
|
22
|
+
* only it knows the band the ink has to survive in, and `discordantDipPx`
|
|
23
|
+
* (@jbrowse/sv-core) is the law the two views share.
|
|
24
|
+
*/
|
|
76
25
|
export function bezierConnectorPath({ x1, y1, x2, y2, s1, s2,
|
|
77
26
|
// The second endpoint is a split junction's 5' leading edge (its handle flips
|
|
78
27
|
// to fold the curve into the next segment); false for a paired mate's 3' edge.
|
|
79
|
-
leadingEnd2 = false, reversed1 = false, reversed2 = false, maxHandlePx =
|
|
80
|
-
// Depth, in px, of the dip a discordant connection draws instead
|
|
81
|
-
// concordant one gets
|
|
82
|
-
// strand flip, so the two classes are tellable apart by shape alone. It is
|
|
83
|
-
// the depth of the curve's APEX — what a caller can bound by the room it has —
|
|
84
|
-
// and CUBIC_APEX_RATIO converts it to the control-point drop that puts the ink
|
|
85
|
-
// there. Leave it out to bow up.
|
|
28
|
+
leadingEnd2 = false, reversed1 = false, reversed2 = false, maxHandlePx = CONNECTOR_MAX_HANDLE_PX,
|
|
29
|
+
// Depth, in px, of the APEX of the dip a discordant connection draws instead
|
|
30
|
+
// of the bow a concordant one gets. Leave it out to bow up.
|
|
86
31
|
dipPx, }) {
|
|
87
|
-
const
|
|
88
|
-
const
|
|
89
|
-
const
|
|
90
|
-
const
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
// it goes, so a big event squeezed into a few px draws a narrow trough rather
|
|
95
|
-
// than a squiggle. Pinned by 'a dipped connection never overshoots its
|
|
96
|
-
// endpoints in x'.
|
|
97
|
-
const bow = dipPx === undefined
|
|
98
|
-
? bowHeight(from, to, budget)
|
|
99
|
-
: -Math.min(dipPx, BEZIER_CONNECTOR_MAX_REACH_PX) / CUBIC_APEX_RATIO;
|
|
100
|
-
return cubicPath(from, { x: x1 + handle * tangentSign(s1, false, reversed1), y: y1 - bow }, { x: x2 + handle * tangentSign(s2, leadingEnd2, reversed2), y: y2 - bow }, to);
|
|
32
|
+
const dy = y2 - y1;
|
|
33
|
+
const budget = connectorBudgetPx(x2 - x1, dy);
|
|
34
|
+
const handle = connectorHandlePx(budget, maxHandlePx);
|
|
35
|
+
const lift = connectorLiftPx(budget, dy, dipPx ?? CONNECTOR_BOW);
|
|
36
|
+
const c1x = x1 + handle * connectorTangent(s1, 0, reversed1 ? 1 : 0);
|
|
37
|
+
const c2x = x2 + handle * connectorTangent(s2, leadingEnd2 ? 1 : 0, reversed2 ? 1 : 0);
|
|
38
|
+
return `M ${x1} ${y1} C ${c1x} ${y1 - lift} ${c2x} ${y2 - lift} ${x2} ${y2}`;
|
|
101
39
|
}
|
|
@@ -51,5 +51,8 @@ import { SharedBudget } from '@gmod/shared-read-cache';
|
|
|
51
51
|
* why this used to be two budgets named for their units: a million records
|
|
52
52
|
* could not be added to bytes, and never bound long-read data either, where a
|
|
53
53
|
* 6 MB slice counted as 37.
|
|
54
|
+
*
|
|
55
|
+
* `@jbrowse/tables` lowers the limit for a host such as R, which keeps no
|
|
56
|
+
* track open to pan (`packages/tables/src/cache.ts`).
|
|
54
57
|
*/
|
|
55
58
|
export declare const decompressedBytesBudget: SharedBudget;
|
package/esm/util/cacheBudgets.js
CHANGED
|
@@ -51,5 +51,8 @@ import { SharedBudget } from '@gmod/shared-read-cache';
|
|
|
51
51
|
* why this used to be two budgets named for their units: a million records
|
|
52
52
|
* could not be added to bytes, and never bound long-read data either, where a
|
|
53
53
|
* 6 MB slice counted as 37.
|
|
54
|
+
*
|
|
55
|
+
* `@jbrowse/tables` lowers the limit for a host such as R, which keeps no
|
|
56
|
+
* track open to pan (`packages/tables/src/cache.ts`).
|
|
54
57
|
*/
|
|
55
58
|
export const decompressedBytesBudget = new SharedBudget(1024 * 2 ** 20);
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { HeldSlots } from '../ui/colors.ts';
|
|
1
2
|
/** #api */
|
|
2
3
|
export declare const STRAND_FIELD = "strand";
|
|
3
4
|
/**
|
|
@@ -19,7 +20,9 @@ export declare const NO_VALUE_LABEL = "(no value)";
|
|
|
19
20
|
* orders keys (the `domain` first, the rest by `compareGroupKeys`, `''`
|
|
20
21
|
* after them), `label` names a key in a legend, `sectionLabel` on a chip, and
|
|
21
22
|
* `color` paints it. A key's color depends only on the key and the
|
|
22
|
-
* declaration, so every region agrees on it
|
|
23
|
+
* declaration, so every region agrees on it, except that a field dealing its
|
|
24
|
+
* colors (`categoricalField`'s `held`) also steps a key off the colors of the
|
|
25
|
+
* keys met before it.
|
|
23
26
|
*/
|
|
24
27
|
export interface CategoricalField {
|
|
25
28
|
field: string;
|
|
@@ -38,7 +41,7 @@ export interface CategoricalField {
|
|
|
38
41
|
}
|
|
39
42
|
/**
|
|
40
43
|
* #api
|
|
41
|
-
* What a key names each of `keys`, from a
|
|
44
|
+
* What a key names each of `keys`, from a color object's `labels`: one each in
|
|
42
45
|
* order, an empty or missing entry leaving that key its own name. Every key
|
|
43
46
|
* that takes `labels` reads them through this, so a config means one thing by
|
|
44
47
|
* them everywhere.
|
|
@@ -47,10 +50,27 @@ export declare function keyNames(keys: readonly unknown[], labels?: readonly str
|
|
|
47
50
|
/**
|
|
48
51
|
* #api
|
|
49
52
|
* `labels` names the `domain`'s values in a key, one each in order, where a
|
|
50
|
-
* config spells them for a reader rather than as the data does.
|
|
53
|
+
* config spells them for a reader rather than as the data does. `held` deals
|
|
54
|
+
* each key the domain does not list a color of its own on first sight
|
|
55
|
+
* (`categoricalScale`); the caller keeps it for as long as the colors should
|
|
56
|
+
* hold.
|
|
51
57
|
*/
|
|
52
|
-
export declare function categoricalField(field: string, { domain, range, labels, }?: {
|
|
58
|
+
export declare function categoricalField(field: string, { domain, range, labels, held, }?: {
|
|
53
59
|
domain?: readonly string[];
|
|
54
60
|
range?: readonly string[];
|
|
55
61
|
labels?: readonly string[];
|
|
62
|
+
held?: HeldSlots;
|
|
56
63
|
}): CategoricalField;
|
|
64
|
+
/**
|
|
65
|
+
* #api
|
|
66
|
+
* Deals `keys` their colors in `field.compare` order, so the colors a set
|
|
67
|
+
* of keys first seen together takes do not depend on the order they arrive
|
|
68
|
+
* in. A no-op for a field that deals nothing.
|
|
69
|
+
*/
|
|
70
|
+
export declare function dealKeyColors(field: CategoricalField, keys: Iterable<string>): void;
|
|
71
|
+
/**
|
|
72
|
+
* #api
|
|
73
|
+
* The `HeldSlots` `owner` keeps under `key`, made empty on first ask. Lives as
|
|
74
|
+
* long as `owner` and is never persisted, so a reload deals afresh.
|
|
75
|
+
*/
|
|
76
|
+
export declare function heldSlotsOf(owner: object, key: string): HeldSlots;
|
|
@@ -18,7 +18,7 @@ export const SV_TYPE_FIELD = 'svType';
|
|
|
18
18
|
export const NO_VALUE_LABEL = '(no value)';
|
|
19
19
|
/**
|
|
20
20
|
* #api
|
|
21
|
-
* What a key names each of `keys`, from a
|
|
21
|
+
* What a key names each of `keys`, from a color object's `labels`: one each in
|
|
22
22
|
* order, an empty or missing entry leaving that key its own name. Every key
|
|
23
23
|
* that takes `labels` reads them through this, so a config means one thing by
|
|
24
24
|
* them everywhere.
|
|
@@ -37,11 +37,14 @@ export function keyNames(keys, labels = []) {
|
|
|
37
37
|
/**
|
|
38
38
|
* #api
|
|
39
39
|
* `labels` names the `domain`'s values in a key, one each in order, where a
|
|
40
|
-
* config spells them for a reader rather than as the data does.
|
|
40
|
+
* config spells them for a reader rather than as the data does. `held` deals
|
|
41
|
+
* each key the domain does not list a color of its own on first sight
|
|
42
|
+
* (`categoricalScale`); the caller keeps it for as long as the colors should
|
|
43
|
+
* hold.
|
|
41
44
|
*/
|
|
42
|
-
export function categoricalField(field, { domain = [], range = [], labels = [], } = {}) {
|
|
45
|
+
export function categoricalField(field, { domain = [], range = [], labels = [], held, } = {}) {
|
|
43
46
|
// a field with a vocabulary of its own reads it on every channel, a facet's
|
|
44
|
-
// sections as well as a
|
|
47
|
+
// sections as well as a color's key
|
|
45
48
|
const vocabulary = universalPresetOf(field);
|
|
46
49
|
const ownOrder = vocabulary?.domain ?? [];
|
|
47
50
|
const order = domain.length > 0 ? domain : ownOrder;
|
|
@@ -66,8 +69,38 @@ export function categoricalField(field, { domain = [], range = [], labels = [],
|
|
|
66
69
|
if (key === '') {
|
|
67
70
|
return NO_CATEGORY_COLOR;
|
|
68
71
|
}
|
|
69
|
-
colorOf ??= categoricalColorScale(paired, colors);
|
|
72
|
+
colorOf ??= categoricalColorScale(paired, colors, held);
|
|
70
73
|
return colorOf(key);
|
|
71
74
|
},
|
|
72
75
|
};
|
|
73
76
|
}
|
|
77
|
+
/**
|
|
78
|
+
* #api
|
|
79
|
+
* Deals `keys` their colors in `field.compare` order, so the colors a set
|
|
80
|
+
* of keys first seen together takes do not depend on the order they arrive
|
|
81
|
+
* in. A no-op for a field that deals nothing.
|
|
82
|
+
*/
|
|
83
|
+
export function dealKeyColors(field, keys) {
|
|
84
|
+
for (const key of [...new Set(keys)].sort(field.compare)) {
|
|
85
|
+
field.color(key);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
const heldByOwner = new WeakMap();
|
|
89
|
+
/**
|
|
90
|
+
* #api
|
|
91
|
+
* The `HeldSlots` `owner` keeps under `key`, made empty on first ask. Lives as
|
|
92
|
+
* long as `owner` and is never persisted, so a reload deals afresh.
|
|
93
|
+
*/
|
|
94
|
+
export function heldSlotsOf(owner, key) {
|
|
95
|
+
let byKey = heldByOwner.get(owner);
|
|
96
|
+
if (byKey === undefined) {
|
|
97
|
+
byKey = new Map();
|
|
98
|
+
heldByOwner.set(owner, byKey);
|
|
99
|
+
}
|
|
100
|
+
let held = byKey.get(key);
|
|
101
|
+
if (held === undefined) {
|
|
102
|
+
held = new Map();
|
|
103
|
+
byKey.set(key, held);
|
|
104
|
+
}
|
|
105
|
+
return held;
|
|
106
|
+
}
|
package/esm/util/cellMatches.js
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
// A `cells` step, the interval `bin` behind it and the `aggregate` of its
|
|
2
2
|
// matches as one walk over the rows' bytes, which `runSteps` in
|
|
3
3
|
// featureTransforms.ts reaches by relative path only.
|
|
4
|
+
import { DASH, SPACE, firstDrawn, isGapByte, lastDrawn, } from './alignedBytes.js';
|
|
4
5
|
import { fusesBinAggregate } from './binnedAggregate.js';
|
|
5
|
-
import {
|
|
6
|
+
import { DEFAULT_CELLS_FIELD, MATCH, NO_STATE, cellState, comparesBase, opensRun, runKey, walkedTexts, } from './cellsStep.js';
|
|
6
7
|
import { numberReaderOf, readerOf } from './featureTable.js';
|
|
7
8
|
import { BIN_OVERLAP_FIELD, DEFAULT_BIN_AS, OpSums, groupKey, madeGroups, } from './stepTables.js';
|
|
8
9
|
const isEdges = (pair) => pair?.length === 2 && pair[0] === 'start' && pair[1] === 'end';
|
|
@@ -97,10 +98,10 @@ class SectionBins {
|
|
|
97
98
|
}
|
|
98
99
|
/**
|
|
99
100
|
* One row's runs as `cells` writes them, each met by its bins as the bin
|
|
100
|
-
* step cuts it and in the order the lanes hold them: a run
|
|
101
|
-
* column
|
|
102
|
-
* ahead of the run still open. The bases a run
|
|
103
|
-
*
|
|
101
|
+
* step cuts it and in the order the lanes hold them: a run where the next
|
|
102
|
+
* column `opensRun`, an insertion at the reference base after it,
|
|
103
|
+
* ahead of the run still open. The compared bases a run holds are counted
|
|
104
|
+
* in their bins as the walk passes them.
|
|
104
105
|
*/
|
|
105
106
|
walk(r, startPos, size, rowBytes, rowAt, rowLen, refBytes, refAt, refLen) {
|
|
106
107
|
const { matched, compared, low } = this;
|
|
@@ -114,7 +115,7 @@ class SectionBins {
|
|
|
114
115
|
let runOpen = false;
|
|
115
116
|
let runBin = 0;
|
|
116
117
|
let runState = NO_STATE;
|
|
117
|
-
let
|
|
118
|
+
let openKey = -1;
|
|
118
119
|
let inserting = false;
|
|
119
120
|
for (let col = 0; col < refLen; col++) {
|
|
120
121
|
const refByte = refBytes[refAt + col];
|
|
@@ -130,22 +131,21 @@ class SectionBins {
|
|
|
130
131
|
inserting = false;
|
|
131
132
|
}
|
|
132
133
|
const st = cellState(refByte, rowByte, col >= first && col <= last && col < rowLen);
|
|
133
|
-
const
|
|
134
|
-
if (st
|
|
134
|
+
const key = runKey(st, refByte);
|
|
135
|
+
if (opensRun(st, key, runState, openKey)) {
|
|
135
136
|
if (runOpen) {
|
|
136
137
|
this.touch(runBin, pos > edge - size ? bin : bin - 1, r);
|
|
137
138
|
}
|
|
138
139
|
runOpen = st !== NO_STATE;
|
|
139
140
|
runBin = bin;
|
|
140
141
|
runState = st;
|
|
141
|
-
|
|
142
|
+
openKey = key;
|
|
142
143
|
}
|
|
143
|
-
if (st
|
|
144
|
-
m++;
|
|
145
|
-
c++;
|
|
146
|
-
}
|
|
147
|
-
else if (st === MISMATCH) {
|
|
144
|
+
if (comparesBase(st, refByte)) {
|
|
148
145
|
c++;
|
|
146
|
+
if (st === MATCH) {
|
|
147
|
+
m++;
|
|
148
|
+
}
|
|
149
149
|
}
|
|
150
150
|
pos++;
|
|
151
151
|
if (pos === edge) {
|
package/esm/util/cellsStep.d.ts
CHANGED
|
@@ -2,15 +2,13 @@ import type { FeatureTable, TextColumn } from './featureTable.ts';
|
|
|
2
2
|
import type { CellsStep } from './markEncodingTypes.ts';
|
|
3
3
|
import type { Staged } from './stepTables.ts';
|
|
4
4
|
export declare const DEFAULT_CELLS_FIELD = "seq";
|
|
5
|
-
export declare const DASH = 45;
|
|
6
|
-
export declare const SPACE = 32;
|
|
7
5
|
export declare const MATCH = 0;
|
|
8
6
|
export declare const MISMATCH = 1;
|
|
9
7
|
export declare const NO_STATE = 255;
|
|
10
|
-
export declare function isGapByte(b: number): b is 32 | 45;
|
|
11
|
-
export declare function firstDrawn(bytes: Uint8Array, at: number, len: number): number;
|
|
12
|
-
export declare function lastDrawn(bytes: Uint8Array, at: number, len: number, first: number): number;
|
|
13
8
|
export declare function cellState(refByte: number, rowByte: number, drawn: boolean): 0 | 1 | 2 | 255;
|
|
9
|
+
export declare function comparesBase(state: number, refByte: number): boolean;
|
|
10
|
+
export declare function runKey(state: number, refByte: number): 0 | 1;
|
|
11
|
+
export declare function opensRun(state: number, key: number, runState: number, openKey: number): boolean;
|
|
14
12
|
/**
|
|
15
13
|
* The texts a `cells` walk reads, by the row of the table it walked: each
|
|
16
14
|
* row's own, and the reference it is read against, which a row fanned out of
|