@jbrowse/core 5.0.0-beta.8 → 5.0.0-beta.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +427 -130
- 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 +8 -9
- package/esm/BaseFeatureWidget/BaseFeatureDetail/CoreDetails.js +8 -13
- package/esm/BaseFeatureWidget/BaseFeatureDetail/FeatureDetails.d.ts +2 -1
- package/esm/BaseFeatureWidget/BaseFeatureDetail/FeatureDetails.js +3 -3
- package/esm/BaseFeatureWidget/BaseFeatureDetail/FieldActionsButton.d.ts +8 -0
- package/esm/BaseFeatureWidget/BaseFeatureDetail/FieldActionsButton.js +24 -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 +1 -0
- package/esm/BaseFeatureWidget/BaseFeatureDetail/index.js +1 -4
- package/esm/BaseFeatureWidget/BaseFeatureDetail/jexlFilterActions.d.ts +16 -0
- package/esm/BaseFeatureWidget/BaseFeatureDetail/jexlFilterActions.js +53 -0
- package/esm/BaseFeatureWidget/BaseFeatureDetail/util.d.ts +0 -8
- package/esm/BaseFeatureWidget/BaseFeatureDetail/util.js +0 -16
- package/esm/BaseFeatureWidget/SequenceFeatureDetails/SequenceContents.js +7 -34
- package/esm/BaseFeatureWidget/configSchema.d.ts +1 -1
- package/esm/BaseFeatureWidget/formatDetails.d.ts +13 -29
- package/esm/BaseFeatureWidget/formatDetails.js +46 -79
- package/esm/BaseFeatureWidget/index.d.ts +1 -0
- package/esm/BaseFeatureWidget/stateModelFactory.d.ts +35 -28
- package/esm/BaseFeatureWidget/stateModelFactory.js +94 -102
- package/esm/BaseFeatureWidget/types.d.ts +3 -0
- package/esm/BaseFeatureWidget/util.d.ts +0 -3
- package/esm/BaseFeatureWidget/util.js +0 -17
- package/esm/PluginLoader.d.ts +14 -9
- package/esm/PluginLoader.js +34 -26
- package/esm/PluginManager.d.ts +4 -4
- package/esm/PluginManager.js +1 -1
- package/esm/ReExports/coreModules.generated.d.ts +2 -0
- package/esm/ReExports/coreModules.generated.js +492 -0
- package/esm/ReExports/coreWorkerModules.generated.d.ts +2 -0
- package/esm/ReExports/coreWorkerModules.generated.js +453 -0
- package/esm/ReExports/frameworkModules.d.ts +2 -0
- package/esm/ReExports/frameworkModules.js +67 -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 +493 -79
- package/esm/ReExports/modules.d.ts +1 -1
- package/esm/ReExports/modules.js +10 -87
- package/esm/ReExports/registry.d.ts +1 -0
- package/esm/ReExports/registry.js +23 -5
- package/esm/ReExports/uiStub.d.ts +2 -1
- package/esm/ReExports/uiStub.js +24 -2
- package/esm/ReExports/workerModules.js +8 -12
- package/esm/TextSearch/TextSearchManager.d.ts +3 -12
- package/esm/TextSearch/TextSearchManager.js +22 -10
- package/esm/assemblyManager/assembly.d.ts +10 -14
- package/esm/assemblyManager/assembly.js +10 -14
- package/esm/assemblyManager/assemblyConfigSchema.d.ts +23 -81
- package/esm/assemblyManager/assemblyManager.d.ts +10 -16
- package/esm/assemblyManager/assemblyManager.js +7 -10
- package/esm/assemblyManager/loadRefNameMap.js +3 -3
- package/esm/configuration/configurationSchema.d.ts +75 -31
- package/esm/configuration/configurationSchema.js +74 -40
- package/esm/configuration/configurationSchemaUnion.d.ts +39 -0
- package/esm/configuration/configurationSchemaUnion.js +59 -0
- package/esm/configuration/configurationSlot.d.ts +37 -12
- package/esm/configuration/configurationSlot.js +83 -22
- 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/getConf.d.ts +17 -9
- package/esm/configuration/getConf.js +52 -7
- package/esm/configuration/index.d.ts +11 -4
- package/esm/configuration/index.js +7 -4
- package/esm/configuration/mergeFormatCallbacks.d.ts +6 -7
- package/esm/configuration/mergeFormatCallbacks.js +13 -10
- package/esm/configuration/readConfObject.d.ts +2 -22
- package/esm/configuration/readConfObject.js +15 -49
- package/esm/configuration/requirements.d.ts +37 -0
- package/esm/configuration/requirements.js +88 -0
- package/esm/configuration/schemaRegistry.d.ts +21 -1
- package/esm/configuration/schemaRegistry.js +11 -0
- package/esm/configuration/schemaTypes.d.ts +3 -0
- package/esm/configuration/schemaTypes.js +10 -0
- package/esm/configuration/slotFacade.d.ts +35 -4
- package/esm/configuration/slotFacade.js +96 -9
- package/esm/configuration/snapshotPreprocess.d.ts +27 -0
- package/esm/configuration/snapshotPreprocess.js +102 -0
- package/esm/configuration/types.d.ts +161 -22
- package/esm/data_adapters/BaseAdapter/BaseAdapter.d.ts +2 -2
- package/esm/data_adapters/BaseAdapter/BaseFeatureDataAdapter.d.ts +11 -2
- package/esm/data_adapters/BaseAdapter/BaseFeatureDataAdapter.js +12 -1
- package/esm/data_adapters/BaseAdapter/featureDensity.d.ts +2 -3
- package/esm/data_adapters/BaseAdapter/featureDensity.js +2 -3
- package/esm/data_adapters/BaseAdapter/index.d.ts +22 -3
- package/esm/data_adapters/BaseAdapter/types.d.ts +3 -4
- package/esm/data_adapters/BaseAdapter/zoomRange.d.ts +10 -0
- package/esm/data_adapters/BaseAdapter/zoomRange.js +1 -0
- package/esm/data_adapters/CytobandAdapter/configSchema.d.ts +9 -11
- package/esm/data_adapters/getSequenceSubAdapter.d.ts +1 -3
- package/esm/data_adapters/getSequenceSubAdapter.js +1 -3
- package/esm/pluggableElementTypes/AdapterType.d.ts +7 -7
- package/esm/pluggableElementTypes/RpcMethodType.d.ts +1 -1
- package/esm/pluggableElementTypes/RpcMethodType.js +3 -8
- package/esm/pluggableElementTypes/RpcMethodTypeWithFiltersAndRenameRegions.d.ts +1 -2
- package/esm/pluggableElementTypes/TextSearchAdapterType.d.ts +7 -7
- package/esm/pluggableElementTypes/index.d.ts +1 -1
- package/esm/pluggableElementTypes/index.js +1 -1
- package/esm/pluggableElementTypes/models/BaseConnectionModelFactory.d.ts +17 -7
- package/esm/pluggableElementTypes/models/BaseDisplayModel.d.ts +45 -48
- package/esm/pluggableElementTypes/models/BaseDisplayModel.js +40 -36
- package/esm/pluggableElementTypes/models/BaseTrackModel.d.ts +10 -13
- package/esm/pluggableElementTypes/models/BaseTrackModel.js +6 -6
- package/esm/pluggableElementTypes/models/BaseViewModel.d.ts +37 -17
- package/esm/pluggableElementTypes/models/BaseViewModel.js +25 -10
- package/esm/pluggableElementTypes/models/InternetAccountModel.d.ts +26 -16
- package/esm/pluggableElementTypes/models/assertDisplayContract.d.ts +1 -1
- 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 +57 -141
- package/esm/pluggableElementTypes/models/baseTrackConfig.js +22 -26
- package/esm/pluggableElementTypes/models/components/SaveTrackData.js +2 -2
- 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 +15 -7
- package/esm/pluggableElementTypes/models/expandTrackConfigShorthand.js +38 -29
- package/esm/pluggableElementTypes/models/index.d.ts +1 -2
- package/esm/pluggableElementTypes/models/index.js +1 -2
- package/esm/pluggableElementTypes/models/saveTrackFileTypes/genbank.d.ts +3 -3
- package/esm/pluggableElementTypes/models/saveTrackFileTypes/genbank.js +4 -4
- package/esm/pluggableElementTypes/models/saveTrackFileTypes/types.d.ts +3 -3
- package/esm/rpc/BaseRpcDriver.d.ts +1 -2
- package/esm/rpc/BaseRpcDriver.js +23 -30
- package/esm/rpc/MainThreadRpcDriver.d.ts +2 -2
- package/esm/rpc/MainThreadRpcDriver.js +13 -8
- package/esm/rpc/RpcClient.d.ts +17 -6
- package/esm/rpc/RpcClient.js +42 -12
- package/esm/rpc/RpcManager.d.ts +8 -10
- package/esm/rpc/RpcManager.js +1 -1
- package/esm/rpc/RpcRegistry.d.ts +8 -2
- package/esm/rpc/RpcServer.d.ts +3 -1
- package/esm/rpc/RpcServer.js +19 -12
- package/esm/rpc/WebWorkerRpcDriver.d.ts +3 -3
- package/esm/rpc/WebWorkerRpcDriver.js +9 -47
- package/esm/rpc/byteBudget.d.ts +3 -5
- package/esm/rpc/byteBudget.js +4 -4
- package/esm/rpc/configSchema.d.ts +7 -21
- package/esm/rpc/coreRpcMethods.d.ts +1 -0
- package/esm/rpc/coreRpcMethods.js +1 -0
- package/esm/rpc/methods/CoreEncodeFeatures.d.ts +6 -5
- package/esm/rpc/methods/CoreEncodeFeatures.js +26 -31
- package/esm/rpc/methods/CoreGetEncodedFeature.d.ts +13 -0
- package/esm/rpc/methods/CoreGetEncodedFeature.js +31 -0
- package/esm/rpc/methods/CoreGetExportData.js +2 -2
- package/esm/rpc/methods/CoreGetFeatureDensity.js +2 -2
- package/esm/rpc/methods/CoreGetFeatures.js +2 -2
- package/esm/rpc/methods/CoreGetSequence.js +2 -2
- package/esm/rpc/methods/layerFeatures.d.ts +26 -0
- package/esm/rpc/methods/layerFeatures.js +40 -0
- package/esm/svg/SvgExport.js +3 -4
- package/esm/svg/SvgThemeProviders.d.ts +12 -0
- package/esm/svg/SvgThemeProviders.js +15 -0
- package/esm/svg/exportViewSvg.d.ts +32 -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/svgReady.d.ts +8 -7
- package/esm/svg/svgReady.js +8 -7
- package/esm/svg/trackNames.d.ts +5 -5
- package/esm/svg/trackNames.js +6 -6
- package/esm/svg/wrapSvgExport.js +6 -74
- package/esm/ui/CascadingMenu.js +83 -86
- package/esm/ui/ErrorMessageStackTraceDialog.js +0 -5
- 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/LoadingOverlay.js +3 -1
- package/esm/ui/MonospaceTextField.d.ts +2 -1
- package/esm/ui/MonospaceTextField.js +21 -19
- package/esm/ui/PaletteContext.d.ts +7 -9
- package/esm/ui/PaletteContext.js +24 -10
- package/esm/ui/RefNameAutocomplete/index.d.ts +1 -2
- package/esm/ui/RefNameAutocomplete/index.js +1 -1
- package/esm/ui/ScrollChrome.d.ts +6 -9
- package/esm/ui/ScrollChrome.js +5 -6
- package/esm/ui/ScrollEdgeShadow.d.ts +6 -9
- package/esm/ui/ScrollEdgeShadow.js +9 -24
- package/esm/ui/SettingsChangesTable.js +3 -3
- package/esm/ui/VerticalScrollbar.d.ts +13 -34
- package/esm/ui/VerticalScrollbar.js +29 -83
- package/esm/ui/ViewLoadingScreen.d.ts +2 -2
- package/esm/ui/ViewLoadingScreen.js +3 -3
- package/esm/ui/colorScale.d.ts +26 -1
- package/esm/ui/colorScale.js +28 -5
- package/esm/ui/colors.d.ts +49 -1
- package/esm/ui/colors.js +139 -4
- package/esm/ui/hoverBoxStyle.d.ts +14 -2
- package/esm/ui/hoverBoxStyle.js +17 -2
- package/esm/ui/index.d.ts +5 -3
- package/esm/ui/index.js +9 -7
- package/esm/ui/launchViewMenu.js +3 -3
- package/esm/ui/legendSpec.d.ts +2 -0
- package/esm/ui/legendSpec.js +3 -0
- package/esm/ui/palette.d.ts +0 -1
- package/esm/ui/palette.js +3 -27
- package/esm/ui/replaceViewAction.d.ts +1 -1
- package/esm/ui/replaceViewAction.js +1 -1
- package/esm/ui/theme.d.ts +1 -1
- package/esm/ui/theme.js +6 -40
- package/esm/ui/viewHeaderHeight.d.ts +1 -0
- package/esm/ui/viewHeaderHeight.js +1 -0
- package/esm/util/Base1DUtils.d.ts +1 -1
- package/esm/util/Base1DUtils.js +2 -2
- package/esm/util/SvgCanvas.d.ts +15 -13
- package/esm/util/SvgCanvas.js +72 -53
- package/esm/util/aborting.d.ts +39 -0
- package/esm/util/aborting.js +84 -0
- package/esm/util/adapterMetadata.d.ts +1 -1
- package/esm/util/adapterMetadata.js +6 -6
- package/esm/util/addAndShowTrack.d.ts +1 -4
- package/esm/util/addRelativeUris.d.ts +10 -2
- package/esm/util/addRelativeUris.js +22 -7
- package/esm/util/addTrackFromWidget.d.ts +2 -5
- 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/bandLayout.d.ts +4 -4
- package/esm/util/bandLayout.js +4 -4
- package/esm/util/bezierConnector.js +5 -4
- package/esm/util/bgzfWorkerPool.d.ts +20 -74
- package/esm/util/bgzfWorkerPool.js +20 -74
- package/esm/util/cachedSetup.d.ts +1 -1
- package/esm/util/cachedSetup.js +2 -2
- package/esm/util/categoricalField.d.ts +37 -0
- package/esm/util/categoricalField.js +52 -0
- 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 +1 -2
- package/esm/util/colorBits.js +17 -39
- package/esm/util/colorRamp.d.ts +27 -1
- package/esm/util/colorRamp.js +56 -2
- package/esm/util/colorSchemes.d.ts +9 -0
- package/esm/util/colorSchemes.js +7 -0
- package/esm/util/{createStopTokenRotation.d.ts → createAbortRotation.d.ts} +11 -14
- package/esm/util/{createStopTokenRotation.js → createAbortRotation.js} +14 -26
- 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 +7 -12
- package/esm/util/expandLooseSearchIndex.d.ts +7 -0
- package/esm/util/expandLooseSearchIndex.js +25 -0
- package/esm/util/featureTransforms.d.ts +30 -3
- package/esm/util/featureTransforms.js +233 -36
- package/esm/util/fetchAndMaybeUnzip.js +5 -6
- package/esm/util/fetchContext.d.ts +5 -6
- package/esm/util/fetchContext.js +1 -1
- package/esm/util/fetchHub.d.ts +3 -1
- package/esm/util/fetchHub.js +2 -2
- 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/groupKeys.d.ts +75 -0
- package/esm/util/groupKeys.js +152 -0
- package/esm/util/highlights.d.ts +6 -4
- package/esm/util/highlights.js +12 -25
- package/esm/util/hooks.d.ts +1 -2
- package/esm/util/hooks.js +1 -2
- package/esm/util/index.d.ts +3 -3
- package/esm/util/index.js +4 -3
- package/esm/util/indexCandidates.js +1 -1
- package/esm/util/installFetch.d.ts +13 -10
- package/esm/util/installFetch.js +11 -10
- package/esm/util/installPrerequisiteFetch.d.ts +5 -3
- package/esm/util/installPrerequisiteFetch.js +3 -4
- package/esm/util/io/index.js +12 -12
- package/esm/util/isDataCurrent.d.ts +7 -5
- package/esm/util/isDataCurrent.js +9 -6
- 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 +7 -5
- package/esm/util/jexlStrings.d.ts +3 -4
- package/esm/util/jexlStrings.js +2 -3
- package/esm/util/legendCandidates.d.ts +31 -27
- package/esm/util/legendCandidates.js +79 -53
- package/esm/util/localStorage.js +4 -4
- package/esm/util/markEncoding.d.ts +32 -16
- package/esm/util/markEncoding.js +177 -150
- package/esm/util/markEncodingTypes.d.ts +137 -66
- package/esm/util/mstUtils.d.ts +19 -22
- package/esm/util/mstUtils.js +19 -22
- 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.js +1 -2
- package/esm/util/openViews.d.ts +1 -0
- package/esm/util/openViews.js +3 -3
- package/esm/util/parseLineByLine.d.ts +3 -4
- package/esm/util/parseLineByLine.js +7 -13
- package/esm/util/progress.d.ts +21 -21
- package/esm/util/progress.js +27 -26
- package/esm/util/renameRegions.d.ts +1 -2
- package/esm/util/renderToStaticMarkup.js +16 -16
- package/esm/util/rxjs.d.ts +7 -8
- package/esm/util/rxjs.js +12 -15
- package/esm/util/simpleFeature.d.ts +0 -1
- package/esm/util/svgColorProps.d.ts +11 -0
- package/esm/util/svgColorProps.js +28 -1
- package/esm/util/tabix.d.ts +3 -4
- package/esm/util/tabix.js +6 -7
- package/esm/util/thresholdScale.d.ts +54 -0
- package/esm/util/thresholdScale.js +112 -0
- package/esm/util/timeGate.d.ts +4 -5
- package/esm/util/timeGate.js +4 -5
- package/esm/util/trackConfigDelta.d.ts +22 -18
- package/esm/util/trackConfigDelta.js +40 -38
- package/esm/util/tracks.d.ts +27 -4
- package/esm/util/tracks.js +116 -43
- package/esm/util/translateTranscript.d.ts +44 -0
- package/esm/util/translateTranscript.js +102 -0
- package/esm/util/types/index.d.ts +19 -7
- package/esm/util/types/services.d.ts +1 -1
- package/esm/util/unknownSnapshotKeys.d.ts +15 -0
- package/esm/util/unknownSnapshotKeys.js +13 -0
- package/esm/util/useFeatureSequence.js +4 -4
- package/esm/util/useFetch.d.ts +3 -4
- package/esm/util/useFetch.js +5 -6
- package/esm/util/usePanelVirtualScroll.d.ts +7 -39
- package/esm/util/usePanelVirtualScroll.js +9 -40
- 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 -84
- package/esm/util/viewHighlights.d.ts +3 -0
- package/esm/util/viewHighlights.js +5 -0
- package/esm/util/viewStatus.d.ts +24 -15
- package/esm/util/viewStatus.js +17 -0
- package/esm/util/withLaunchInput.d.ts +1 -1
- package/esm/util/withLaunchInput.js +0 -4
- package/package.json +26 -12
- 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/barrelOnlyNames.d.ts +0 -5
- package/esm/ReExports/barrelOnlyNames.js +0 -63
- package/esm/ReExports/index.d.ts +0 -1
- package/esm/ReExports/index.js +0 -1
- package/esm/ReExports/publicTracks.d.ts +0 -1
- package/esm/ReExports/publicTracks.js +0 -14
- package/esm/ReExports/publicUi.d.ts +0 -4
- package/esm/ReExports/publicUi.js +0 -33
- package/esm/ReExports/publicUtil.d.ts +0 -1
- package/esm/ReExports/publicUtil.js +0 -32
- package/esm/ReExports/sharedModules.d.ts +0 -96
- package/esm/ReExports/sharedModules.js +0 -66
- package/esm/ReExports/workerNamespaceNames.d.ts +0 -11
- package/esm/ReExports/workerNamespaceNames.js +0 -275
- package/esm/pluggableElementTypes/models/HighlightsMixin.d.ts +0 -51
- package/esm/pluggableElementTypes/models/HighlightsMixin.js +0 -78
- package/esm/ui/highlightChipReveal.d.ts +0 -32
- package/esm/ui/highlightChipReveal.js +0 -39
- package/esm/util/adapterConfigKey.d.ts +0 -12
- package/esm/util/adapterConfigKey.js +0 -14
- package/esm/util/stopToken.d.ts +0 -212
- package/esm/util/stopToken.js +0 -438
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import type { StatusCallback } from './progress.ts';
|
|
2
|
-
import type { StopToken } from './stopToken.ts';
|
|
3
2
|
import type { Region } from './types/data.ts';
|
|
4
3
|
export interface AlignmentData {
|
|
5
4
|
refRefName: string;
|
|
@@ -17,7 +16,7 @@ export interface DiagonalizationResult {
|
|
|
17
16
|
regionsReversed: number;
|
|
18
17
|
};
|
|
19
18
|
}
|
|
20
|
-
export declare function diagonalizeRegions(alignments: AlignmentData[], referenceRegions: Region[], currentRegions: Region[], {
|
|
21
|
-
|
|
19
|
+
export declare function diagonalizeRegions(alignments: AlignmentData[], referenceRegions: Region[], currentRegions: Region[], { signal, statusCallback, }?: {
|
|
20
|
+
signal?: AbortSignal;
|
|
22
21
|
statusCallback?: StatusCallback;
|
|
23
22
|
}): Promise<DiagonalizationResult>;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
+
import { checkAbortSignal } from './aborting.js';
|
|
1
2
|
import { cmpStr } from './cmpStr.js';
|
|
2
3
|
import { createProgressReporter } from './progress.js';
|
|
3
|
-
import { checkStopToken } from './stopToken.js';
|
|
4
4
|
// A strand vote at least this lopsided (80% of aligned bases agreeing) decides
|
|
5
5
|
// the reversal by itself. Below that the vote is unreliable: a chromosome
|
|
6
6
|
// carrying many inversions splits it near 50/50, and MCScan `strand` is the
|
|
@@ -61,19 +61,14 @@ function anchorStats({ alignments, bases, strandWeightedSum }) {
|
|
|
61
61
|
//
|
|
62
62
|
// - refRefName: horizontal-axis (reference) chromosome
|
|
63
63
|
// - queryRefName: vertical-axis (query) chromosome
|
|
64
|
-
export async function diagonalizeRegions(alignments, referenceRegions, currentRegions, {
|
|
65
|
-
//
|
|
66
|
-
//
|
|
67
|
-
// chromosome's group. They used to share a single cancel check between them,
|
|
68
|
-
// so the whole grouping pass ran after a cancel and the bar sat on the
|
|
69
|
-
// fetch's last message throughout. Two reporters because the phases count
|
|
70
|
-
// different things (alignments, then chromosomes), so one auto-incrementing
|
|
71
|
-
// counter across both would report a meaningless fraction.
|
|
64
|
+
export async function diagonalizeRegions(alignments, referenceRegions, currentRegions, { signal, statusCallback, } = {}) {
|
|
65
|
+
// Two reporters because the phases count different things (alignments, then
|
|
66
|
+
// chromosomes). No breakpoint: each pass measured ~50ms over 500k alignments.
|
|
72
67
|
const reportGrouping = createProgressReporter({
|
|
73
68
|
label: 'Grouping alignments',
|
|
74
69
|
total: alignments.length,
|
|
75
70
|
statusCallback,
|
|
76
|
-
|
|
71
|
+
signal,
|
|
77
72
|
});
|
|
78
73
|
// first appearance wins: a refName can appear in more than one reference
|
|
79
74
|
// region, and the ordering key is where that chromosome starts on the axis
|
|
@@ -118,7 +113,7 @@ export async function diagonalizeRegions(alignments, referenceRegions, currentRe
|
|
|
118
113
|
label: 'Ordering chromosomes',
|
|
119
114
|
total: queryGroups.size,
|
|
120
115
|
statusCallback,
|
|
121
|
-
|
|
116
|
+
signal,
|
|
122
117
|
});
|
|
123
118
|
for (const [verticalChrom, group] of queryGroups) {
|
|
124
119
|
reportOrdering();
|
|
@@ -142,7 +137,7 @@ export async function diagonalizeRegions(alignments, referenceRegions, currentRe
|
|
|
142
137
|
});
|
|
143
138
|
}
|
|
144
139
|
}
|
|
145
|
-
|
|
140
|
+
checkAbortSignal(signal);
|
|
146
141
|
queryOrdering.sort((a, b) => a.bestRefIndex - b.bestRefIndex ||
|
|
147
142
|
a.bestRefPos - b.bestRefPos ||
|
|
148
143
|
cmpStr(a.refName, b.refName));
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Fill in what a search index written short leaves out: `type` from a `uri`
|
|
3
|
+
* naming a `.ix`, which is what `jbrowse text-index` writes, and
|
|
4
|
+
* `assemblyNames` from the caller — the track's own for a per-track index, or a
|
|
5
|
+
* config's only assembly. A key already written is kept.
|
|
6
|
+
*/
|
|
7
|
+
export declare function expandLooseSearchIndex<T>(snap: T, assemblyNames?: unknown): T;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Fill in what a search index written short leaves out: `type` from a `uri`
|
|
3
|
+
* naming a `.ix`, which is what `jbrowse text-index` writes, and
|
|
4
|
+
* `assemblyNames` from the caller — the track's own for a per-track index, or a
|
|
5
|
+
* config's only assembly. A key already written is kept.
|
|
6
|
+
*/
|
|
7
|
+
export function expandLooseSearchIndex(snap, assemblyNames) {
|
|
8
|
+
if (typeof snap !== 'object' || snap === null || Array.isArray(snap)) {
|
|
9
|
+
return snap;
|
|
10
|
+
}
|
|
11
|
+
const index = snap;
|
|
12
|
+
const guessType = index.type === undefined &&
|
|
13
|
+
typeof index.uri === 'string' &&
|
|
14
|
+
/\.ix$/i.test(index.uri.split(/[?#]/)[0]);
|
|
15
|
+
const fillNames = index.assemblyNames === undefined &&
|
|
16
|
+
Array.isArray(assemblyNames) &&
|
|
17
|
+
assemblyNames.length > 0;
|
|
18
|
+
return guessType || fillNames
|
|
19
|
+
? {
|
|
20
|
+
...index,
|
|
21
|
+
...(guessType ? { type: 'TrixTextSearchAdapter' } : {}),
|
|
22
|
+
...(fillNames ? { assemblyNames } : {}),
|
|
23
|
+
}
|
|
24
|
+
: snap;
|
|
25
|
+
}
|
|
@@ -1,11 +1,38 @@
|
|
|
1
1
|
import type { JexlInstance } from './jexlStrings.ts';
|
|
2
|
-
import type { AggregateOp, TransformStep } from './markEncodingTypes.ts';
|
|
2
|
+
import type { AggregateOp, FacetSection, FieldRef, TransformStep } from './markEncodingTypes.ts';
|
|
3
3
|
import type { Feature } from './simpleFeature.ts';
|
|
4
|
+
export declare const DEFAULT_BIN_FIELD = "start";
|
|
4
5
|
export declare const DEFAULT_BIN_AS: [string, string];
|
|
6
|
+
export declare const DEFAULT_FLATTEN_FIELD = "subfeatures";
|
|
5
7
|
export declare const DEFAULT_COVERAGE_AS = "coverage";
|
|
6
|
-
export declare const
|
|
7
|
-
export declare const
|
|
8
|
+
export declare const DEFAULT_PILEUP_AS = "row";
|
|
9
|
+
export declare const DEFAULT_PILEUP_FIELDS: [string, string];
|
|
8
10
|
export declare function aggregateFieldName({ op, field, as }: AggregateOp): string;
|
|
11
|
+
/**
|
|
12
|
+
* #api
|
|
13
|
+
* One layer of a faceted request: its features in section order, and the
|
|
14
|
+
* stacked row of each, index for index.
|
|
15
|
+
*/
|
|
16
|
+
export interface FacetedLayer {
|
|
17
|
+
features: readonly Feature[];
|
|
18
|
+
rows: readonly number[];
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* #api
|
|
22
|
+
* A faceted request's layers: the features split on `field`'s key, each
|
|
23
|
+
* layer's own steps run over each section alone, and the sections stacked —
|
|
24
|
+
* a section's rows start where the one above it ends, and it is as tall as
|
|
25
|
+
* the tallest layer packed it. Every layer's features come back in section
|
|
26
|
+
* order beside their stacked rows, so a faceted display is the unfaceted one
|
|
27
|
+
* drawn once per section, and a feature is handed on as its steps left it.
|
|
28
|
+
*/
|
|
29
|
+
export declare function facetLayers(features: readonly Feature[], field: FieldRef, layers: readonly {
|
|
30
|
+
transform?: readonly TransformStep[];
|
|
31
|
+
row?: FieldRef;
|
|
32
|
+
}[], jexl?: JexlInstance): {
|
|
33
|
+
layers: FacetedLayer[];
|
|
34
|
+
sections: FacetSection[];
|
|
35
|
+
};
|
|
9
36
|
/**
|
|
10
37
|
* #api
|
|
11
38
|
* Run the transform steps over a feature list, in order, in the worker. The
|
|
@@ -1,9 +1,14 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { categoricalField } from './categoricalField.js';
|
|
2
|
+
import { fieldReader, isPlainFieldRef } from './fieldReader.js';
|
|
3
|
+
import { isJexl, stringToJexlExpression } from './jexlStrings.js';
|
|
4
|
+
import { numericValue } from './numericValue.js';
|
|
2
5
|
import SimpleFeature, { buildJexlContext } from './simpleFeature.js';
|
|
6
|
+
export const DEFAULT_BIN_FIELD = 'start';
|
|
3
7
|
export const DEFAULT_BIN_AS = ['start', 'end'];
|
|
8
|
+
export const DEFAULT_FLATTEN_FIELD = 'subfeatures';
|
|
4
9
|
export const DEFAULT_COVERAGE_AS = 'coverage';
|
|
5
|
-
export const
|
|
6
|
-
export const
|
|
10
|
+
export const DEFAULT_PILEUP_AS = 'row';
|
|
11
|
+
export const DEFAULT_PILEUP_FIELDS = ['start', 'end'];
|
|
7
12
|
/**
|
|
8
13
|
* A feature with fields written over another's: what `formula` and `bin`
|
|
9
14
|
* produce, without copying the base feature's data per step.
|
|
@@ -58,6 +63,26 @@ function expression(expr, jexl) {
|
|
|
58
63
|
}
|
|
59
64
|
return stringToJexlExpression(expr, jexl);
|
|
60
65
|
}
|
|
66
|
+
// A step reads a name or a dotted path. A plain name keeps the direct
|
|
67
|
+
// `f.get` its loop has always made; this is the reader a path takes instead,
|
|
68
|
+
// chosen once per step. A computed field is a `formula` step's to make.
|
|
69
|
+
function pathReader(ref, step) {
|
|
70
|
+
if (isJexl(ref)) {
|
|
71
|
+
throw new Error(`${step} field is a name or a dotted path, and a formula step in front computes one (${ref})`);
|
|
72
|
+
}
|
|
73
|
+
return fieldReader(ref, undefined);
|
|
74
|
+
}
|
|
75
|
+
// A list holding one value is that value, as a VCF's ALT and INFO fields
|
|
76
|
+
// arrive, and a longer one is its text: a Map keys a list by identity, which
|
|
77
|
+
// made every feature a group of its own. A missing value is one group, whether
|
|
78
|
+
// the field is absent or holds a VCF's `.`.
|
|
79
|
+
function groupKey(value) {
|
|
80
|
+
return Array.isArray(value)
|
|
81
|
+
? value.length === 1
|
|
82
|
+
? (value[0] ?? undefined)
|
|
83
|
+
: value.join(',')
|
|
84
|
+
: (value ?? undefined);
|
|
85
|
+
}
|
|
61
86
|
function filter(features, expr, jexl) {
|
|
62
87
|
const compiled = expression(expr, jexl);
|
|
63
88
|
return features.filter(f => compiled.eval(buildJexlContext({ feature: f })));
|
|
@@ -97,10 +122,13 @@ class FlattenedFeature {
|
|
|
97
122
|
}
|
|
98
123
|
}
|
|
99
124
|
function flatten(features, step) {
|
|
100
|
-
const { field =
|
|
125
|
+
const { field = DEFAULT_FLATTEN_FIELD, index, keepEmpty } = step;
|
|
101
126
|
const out = [];
|
|
127
|
+
const read = isPlainFieldRef(field)
|
|
128
|
+
? undefined
|
|
129
|
+
: pathReader(field, 'a flatten');
|
|
102
130
|
for (const f of features) {
|
|
103
|
-
const items = f.get(field);
|
|
131
|
+
const items = read ? read(f) : f.get(field);
|
|
104
132
|
if (!Array.isArray(items) || items.length === 0) {
|
|
105
133
|
if (keepEmpty) {
|
|
106
134
|
out.push(f);
|
|
@@ -121,13 +149,21 @@ function flatten(features, step) {
|
|
|
121
149
|
return out;
|
|
122
150
|
}
|
|
123
151
|
function bin(features, step) {
|
|
124
|
-
const { field =
|
|
152
|
+
const { field = DEFAULT_BIN_FIELD, step: size } = step;
|
|
125
153
|
if (!(size > 0)) {
|
|
126
154
|
throw new Error(`a bin step needs a positive size (${size})`);
|
|
127
155
|
}
|
|
128
156
|
const [asStart, asEnd] = step.as ?? DEFAULT_BIN_AS;
|
|
157
|
+
if (isPlainFieldRef(field)) {
|
|
158
|
+
return features.map(f => {
|
|
159
|
+
const v = numericValue(f.get(field));
|
|
160
|
+
const start = Math.floor(v / size) * size;
|
|
161
|
+
return new DerivedFeature(f, { [asStart]: start, [asEnd]: start + size });
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
const read = pathReader(field, 'a bin');
|
|
129
165
|
return features.map(f => {
|
|
130
|
-
const v =
|
|
166
|
+
const v = numericValue(read(f));
|
|
131
167
|
const start = Math.floor(v / size) * size;
|
|
132
168
|
return new DerivedFeature(f, { [asStart]: start, [asEnd]: start + size });
|
|
133
169
|
});
|
|
@@ -145,7 +181,8 @@ function groupMembers(features, groupby) {
|
|
|
145
181
|
for (const f of features) {
|
|
146
182
|
let node = root;
|
|
147
183
|
for (let i = 0; i < last; i++) {
|
|
148
|
-
const
|
|
184
|
+
const raw = f.get(groupby[i]);
|
|
185
|
+
const v = typeof raw === 'object' ? groupKey(raw) : raw;
|
|
149
186
|
let next = node.get(v);
|
|
150
187
|
if (!next) {
|
|
151
188
|
next = new Map();
|
|
@@ -153,7 +190,8 @@ function groupMembers(features, groupby) {
|
|
|
153
190
|
}
|
|
154
191
|
node = next;
|
|
155
192
|
}
|
|
156
|
-
const
|
|
193
|
+
const raw = f.get(groupby[last]);
|
|
194
|
+
const v = typeof raw === 'object' ? groupKey(raw) : raw;
|
|
157
195
|
let members = node.get(v);
|
|
158
196
|
if (!members) {
|
|
159
197
|
members = [];
|
|
@@ -164,11 +202,49 @@ function groupMembers(features, groupby) {
|
|
|
164
202
|
}
|
|
165
203
|
return groups;
|
|
166
204
|
}
|
|
205
|
+
// `groupMembers` over readers, for a groupby naming a dotted path.
|
|
206
|
+
function groupMembersBy(features, reads) {
|
|
207
|
+
const last = reads.length - 1;
|
|
208
|
+
const root = new Map();
|
|
209
|
+
const groups = [];
|
|
210
|
+
for (const f of features) {
|
|
211
|
+
let node = root;
|
|
212
|
+
for (let i = 0; i < last; i++) {
|
|
213
|
+
const v = groupKey(reads[i](f));
|
|
214
|
+
let next = node.get(v);
|
|
215
|
+
if (!next) {
|
|
216
|
+
next = new Map();
|
|
217
|
+
node.set(v, next);
|
|
218
|
+
}
|
|
219
|
+
node = next;
|
|
220
|
+
}
|
|
221
|
+
const v = groupKey(reads[last](f));
|
|
222
|
+
let members = node.get(v);
|
|
223
|
+
if (!members) {
|
|
224
|
+
members = [];
|
|
225
|
+
node.set(v, members);
|
|
226
|
+
groups.push(members);
|
|
227
|
+
}
|
|
228
|
+
members.push(f);
|
|
229
|
+
}
|
|
230
|
+
return groups;
|
|
231
|
+
}
|
|
232
|
+
function keyedGroupby(groupby) {
|
|
233
|
+
return groupby.some(field => !isPlainFieldRef(field));
|
|
234
|
+
}
|
|
167
235
|
function aggregate(features, step) {
|
|
168
236
|
const { groupby = [], ops } = step;
|
|
169
237
|
const out = [];
|
|
170
238
|
let serial = 0;
|
|
171
|
-
|
|
239
|
+
const reads = keyedGroupby(groupby)
|
|
240
|
+
? groupby.map(field => pathReader(field, 'an aggregate'))
|
|
241
|
+
: undefined;
|
|
242
|
+
const opReads = ops.map(({ op, field }) => op === 'count' || field === undefined || isPlainFieldRef(field)
|
|
243
|
+
? undefined
|
|
244
|
+
: pathReader(field, 'an aggregate'));
|
|
245
|
+
for (const members of reads
|
|
246
|
+
? groupMembersBy(features, reads)
|
|
247
|
+
: groupMembers(features, groupby)) {
|
|
172
248
|
const first = members[0];
|
|
173
249
|
const refName = first.get('refName');
|
|
174
250
|
let start = Infinity;
|
|
@@ -178,11 +254,14 @@ function aggregate(features, step) {
|
|
|
178
254
|
end = Math.max(end, m.get('end'));
|
|
179
255
|
}
|
|
180
256
|
const data = {};
|
|
181
|
-
for (const field of groupby) {
|
|
182
|
-
data[field] = first.get(field);
|
|
257
|
+
for (const [i, field] of groupby.entries()) {
|
|
258
|
+
data[field] = groupKey(reads ? reads[i](first) : first.get(field));
|
|
183
259
|
}
|
|
184
|
-
for (const agg of ops) {
|
|
185
|
-
|
|
260
|
+
for (const [k, agg] of ops.entries()) {
|
|
261
|
+
const read = opReads[k];
|
|
262
|
+
data[aggregateFieldName(agg)] = read
|
|
263
|
+
? aggregateValueBy(members, agg.op, read)
|
|
264
|
+
: aggregateValue(members, agg);
|
|
186
265
|
}
|
|
187
266
|
out.push(new MadeFeature({ ...data, refName, start, end }, `#${serial++}`));
|
|
188
267
|
}
|
|
@@ -200,7 +279,7 @@ function aggregateValue(members, { op, field }) {
|
|
|
200
279
|
let min = Infinity;
|
|
201
280
|
let max = -Infinity;
|
|
202
281
|
for (const m of members) {
|
|
203
|
-
const v =
|
|
282
|
+
const v = numericValue(m.get(field));
|
|
204
283
|
if (!Number.isFinite(v)) {
|
|
205
284
|
continue;
|
|
206
285
|
}
|
|
@@ -224,31 +303,92 @@ function aggregateValue(members, { op, field }) {
|
|
|
224
303
|
}
|
|
225
304
|
}
|
|
226
305
|
}
|
|
306
|
+
// `aggregateValue` over a reader, for an op naming a dotted path. A function
|
|
307
|
+
// of its own, and the fold written out again, so the loop above stays the size
|
|
308
|
+
// it was: both variants in one body measured 1.04-1.20x on a plain field.
|
|
309
|
+
function aggregateValueBy(members, op, read) {
|
|
310
|
+
let sum = 0;
|
|
311
|
+
let n = 0;
|
|
312
|
+
let min = Infinity;
|
|
313
|
+
let max = -Infinity;
|
|
314
|
+
for (const m of members) {
|
|
315
|
+
const v = numericValue(read(m));
|
|
316
|
+
if (!Number.isFinite(v)) {
|
|
317
|
+
continue;
|
|
318
|
+
}
|
|
319
|
+
sum += v;
|
|
320
|
+
n++;
|
|
321
|
+
min = Math.min(min, v);
|
|
322
|
+
max = Math.max(max, v);
|
|
323
|
+
}
|
|
324
|
+
return op === 'sum'
|
|
325
|
+
? sum
|
|
326
|
+
: n === 0
|
|
327
|
+
? undefined
|
|
328
|
+
: op === 'mean'
|
|
329
|
+
? sum / n
|
|
330
|
+
: op === 'min'
|
|
331
|
+
? min
|
|
332
|
+
: max;
|
|
333
|
+
}
|
|
227
334
|
/**
|
|
228
|
-
* The lowest row each feature fits on, greedy first fit in start order
|
|
229
|
-
*
|
|
230
|
-
*
|
|
231
|
-
*
|
|
335
|
+
* The lowest row each feature fits on, greedy first fit in start order, as a
|
|
336
|
+
* step in front of the encoder rather than a packer behind it. `rowEnds[r]` is
|
|
337
|
+
* where row `r` is free again, so the scan is over rows rather than over
|
|
338
|
+
* features.
|
|
232
339
|
*/
|
|
233
|
-
function
|
|
234
|
-
const as = step.as ??
|
|
235
|
-
const [startField, endField] = step.fields ??
|
|
340
|
+
function pileup(features, step) {
|
|
341
|
+
const as = step.as ?? DEFAULT_PILEUP_AS;
|
|
342
|
+
const [startField, endField] = step.fields ?? DEFAULT_PILEUP_FIELDS;
|
|
236
343
|
const padding = step.padding ?? 0;
|
|
237
|
-
const
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
const
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
344
|
+
const n = features.length;
|
|
345
|
+
const starts = new Float64Array(n);
|
|
346
|
+
const ends = new Float64Array(n);
|
|
347
|
+
let inOrder = true;
|
|
348
|
+
if (isPlainFieldRef(startField) && isPlainFieldRef(endField)) {
|
|
349
|
+
for (let i = 0; i < n; i++) {
|
|
350
|
+
const f = features[i];
|
|
351
|
+
starts[i] = numericValue(f.get(startField));
|
|
352
|
+
ends[i] = numericValue(f.get(endField));
|
|
353
|
+
inOrder &&= i === 0 || starts[i] >= starts[i - 1];
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
else {
|
|
357
|
+
const readStart = pathReader(startField, 'a pileup');
|
|
358
|
+
const readEnd = pathReader(endField, 'a pileup');
|
|
359
|
+
for (let i = 0; i < n; i++) {
|
|
360
|
+
const f = features[i];
|
|
361
|
+
starts[i] = numericValue(readStart(f));
|
|
362
|
+
ends[i] = numericValue(readEnd(f));
|
|
363
|
+
inOrder &&= i === 0 || starts[i] >= starts[i - 1];
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
// Any unreadable start leaves the list out of order. Read as Infinity, it
|
|
367
|
+
// sorts last and packs where it claims no row a readable one could want,
|
|
368
|
+
// where NaN left the sort without an order and a row's end unreadable.
|
|
369
|
+
if (!inOrder) {
|
|
370
|
+
for (let i = 0; i < n; i++) {
|
|
371
|
+
if (Number.isNaN(starts[i])) {
|
|
372
|
+
starts[i] = Infinity;
|
|
247
373
|
}
|
|
248
|
-
rowEnds[row] = (end > start ? end : start) + padding;
|
|
249
|
-
out.push(new DerivedFeature(f, { [as]: row }));
|
|
250
374
|
}
|
|
251
375
|
}
|
|
376
|
+
const order = inOrder
|
|
377
|
+
? undefined
|
|
378
|
+
: Uint32Array.from(starts, (_, i) => i).sort((a, b) => starts[a] - starts[b] || a - b);
|
|
379
|
+
const rowEnds = [];
|
|
380
|
+
const out = [];
|
|
381
|
+
for (let k = 0; k < n; k++) {
|
|
382
|
+
const i = order ? order[k] : k;
|
|
383
|
+
const start = starts[i];
|
|
384
|
+
const end = ends[i];
|
|
385
|
+
let row = 0;
|
|
386
|
+
while (row < rowEnds.length && rowEnds[row] > start) {
|
|
387
|
+
row++;
|
|
388
|
+
}
|
|
389
|
+
rowEnds[row] = (end > start ? end : start) + padding;
|
|
390
|
+
out.push(new DerivedFeature(features[i], { [as]: row }));
|
|
391
|
+
}
|
|
252
392
|
return out;
|
|
253
393
|
}
|
|
254
394
|
/**
|
|
@@ -298,6 +438,63 @@ function coverage(features, step) {
|
|
|
298
438
|
}
|
|
299
439
|
return out;
|
|
300
440
|
}
|
|
441
|
+
function rowOf(value) {
|
|
442
|
+
const row = Number(value);
|
|
443
|
+
return row > 0 ? Math.floor(row) : 0;
|
|
444
|
+
}
|
|
445
|
+
/**
|
|
446
|
+
* #api
|
|
447
|
+
* A faceted request's layers: the features split on `field`'s key, each
|
|
448
|
+
* layer's own steps run over each section alone, and the sections stacked —
|
|
449
|
+
* a section's rows start where the one above it ends, and it is as tall as
|
|
450
|
+
* the tallest layer packed it. Every layer's features come back in section
|
|
451
|
+
* order beside their stacked rows, so a faceted display is the unfaceted one
|
|
452
|
+
* drawn once per section, and a feature is handed on as its steps left it.
|
|
453
|
+
*/
|
|
454
|
+
export function facetLayers(features, field, layers, jexl) {
|
|
455
|
+
const categories = categoricalField(field);
|
|
456
|
+
const read = fieldReader(field, jexl);
|
|
457
|
+
const byKey = new Map();
|
|
458
|
+
for (const f of features) {
|
|
459
|
+
const key = categories.key(read(f));
|
|
460
|
+
const members = byKey.get(key);
|
|
461
|
+
if (members) {
|
|
462
|
+
members.push(f);
|
|
463
|
+
}
|
|
464
|
+
else {
|
|
465
|
+
byKey.set(key, [f]);
|
|
466
|
+
}
|
|
467
|
+
}
|
|
468
|
+
const readRows = layers.map(l => fieldReader(l.row ?? DEFAULT_PILEUP_AS, jexl));
|
|
469
|
+
const out = layers.map(() => ({
|
|
470
|
+
features: [],
|
|
471
|
+
rows: [],
|
|
472
|
+
}));
|
|
473
|
+
const sections = [];
|
|
474
|
+
let next = 0;
|
|
475
|
+
for (const key of [...byKey.keys()].sort(categories.compare)) {
|
|
476
|
+
const members = byKey.get(key);
|
|
477
|
+
let rowCount = 1;
|
|
478
|
+
for (const [l, { transform }] of layers.entries()) {
|
|
479
|
+
const placed = transform?.length
|
|
480
|
+
? runTransforms(members, transform, jexl)
|
|
481
|
+
: members;
|
|
482
|
+
const readRow = readRows[l];
|
|
483
|
+
const layer = out[l];
|
|
484
|
+
for (const f of placed) {
|
|
485
|
+
const row = rowOf(readRow(f));
|
|
486
|
+
if (row + 1 > rowCount) {
|
|
487
|
+
rowCount = row + 1;
|
|
488
|
+
}
|
|
489
|
+
layer.features.push(f);
|
|
490
|
+
layer.rows.push(next + row);
|
|
491
|
+
}
|
|
492
|
+
}
|
|
493
|
+
sections.push({ key, firstRow: next, rowCount });
|
|
494
|
+
next += rowCount;
|
|
495
|
+
}
|
|
496
|
+
return { layers: out, sections };
|
|
497
|
+
}
|
|
301
498
|
/**
|
|
302
499
|
* #api
|
|
303
500
|
* Run the transform steps over a feature list, in order, in the worker. The
|
|
@@ -332,8 +529,8 @@ export function runTransforms(features, steps, jexl) {
|
|
|
332
529
|
current = coverage(current, step);
|
|
333
530
|
break;
|
|
334
531
|
}
|
|
335
|
-
case '
|
|
336
|
-
current =
|
|
532
|
+
case 'pileup': {
|
|
533
|
+
current = pileup(current, step);
|
|
337
534
|
break;
|
|
338
535
|
}
|
|
339
536
|
}
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { redactSource } from './getLocationUri.js';
|
|
2
2
|
import { downloadStatus, phaseOf, updateStatus } from './progress.js';
|
|
3
|
-
import { withStopTokenSignal } from './stopToken.js';
|
|
4
3
|
export function isGzip(buf) {
|
|
5
4
|
return buf[0] === 31 && buf[1] === 139 && buf[2] === 8;
|
|
6
5
|
}
|
|
@@ -36,10 +35,10 @@ label = 'Downloading file') {
|
|
|
36
35
|
const phase = loc.source === undefined
|
|
37
36
|
? label
|
|
38
37
|
: { message: phaseOf(label), source: redactSource(loc.source) };
|
|
39
|
-
const { statusCallback,
|
|
40
|
-
// the
|
|
41
|
-
//
|
|
42
|
-
const buf = await
|
|
38
|
+
const { statusCallback, signal } = opts;
|
|
39
|
+
// the signal reaches the read, so a cancelled whole-file load drops at the
|
|
40
|
+
// socket rather than downloading a multi-GB body to completion
|
|
41
|
+
const buf = await downloadStatus(phase, statusCallback, onProgress => loc.readFile({ ...opts, onProgress, signal }));
|
|
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
44
|
// (~180KB) on the startup path of every page load; only an actually-gzipped
|
|
@@ -51,7 +50,7 @@ label = 'Downloading file') {
|
|
|
51
50
|
},
|
|
52
51
|
// a cancel landing here is otherwise discovered only by whatever parses
|
|
53
52
|
// the result, after a whole-file inflate has run to completion
|
|
54
|
-
|
|
53
|
+
signal)
|
|
55
54
|
: buf;
|
|
56
55
|
}
|
|
57
56
|
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,18 +23,18 @@ 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
|
|
@@ -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
|
@@ -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
|
@@ -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
|
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;
|