@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
package/esm/util/aborting.js
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { isElectron, isNode } from './environment.js';
|
|
2
|
+
import { createTimeGate } from './timeGate.js';
|
|
1
3
|
class AbortError extends Error {
|
|
2
4
|
code;
|
|
3
5
|
}
|
|
@@ -45,3 +47,85 @@ export function isAbortException(exception) {
|
|
|
45
47
|
(exception instanceof AbortError && exception.code === 'ERR_ABORTED') ||
|
|
46
48
|
/\b(aborted|aborterror)\b/i.test(exception.message)));
|
|
47
49
|
}
|
|
50
|
+
/**
|
|
51
|
+
* Throw an AbortError if `signal` has aborted. A `signal.aborted` read, so it
|
|
52
|
+
* is cheap enough for the body of a loop; place it after any await and in any
|
|
53
|
+
* per-item callback a reader hands you.
|
|
54
|
+
*/
|
|
55
|
+
export function checkAbortSignal(signal) {
|
|
56
|
+
if (signal?.aborted) {
|
|
57
|
+
throw makeAbortError();
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Run an awaited stage under `signal`: checked before it starts, and again
|
|
62
|
+
* once it settles. The check after is the one that gets left out when the two
|
|
63
|
+
* are placed by hand — a stop landing during a long await otherwise goes
|
|
64
|
+
* unseen until the next stage.
|
|
65
|
+
*/
|
|
66
|
+
export async function withAbortCheck(signal, fn) {
|
|
67
|
+
checkAbortSignal(signal);
|
|
68
|
+
const result = await fn();
|
|
69
|
+
checkAbortSignal(signal);
|
|
70
|
+
return result;
|
|
71
|
+
}
|
|
72
|
+
const YIELD_INTERVAL_MS = 50;
|
|
73
|
+
/**
|
|
74
|
+
* Give the event loop one turn. A worker learns of an abort through a posted
|
|
75
|
+
* message, and a message is a task: an `await` on an already-settled promise
|
|
76
|
+
* drains only microtasks and delivers nothing. A browser realm, Electron's
|
|
77
|
+
* included, gets a MessageChannel task, which unlike `setTimeout` is not
|
|
78
|
+
* clamped. Not `scheduler.yield`: Chromium runs its continuation ahead of a
|
|
79
|
+
* posted message, so a worker loop yielding that way never sees the abort.
|
|
80
|
+
* Plain Node and jsdom get the timer: a MessagePort turn there runs no due
|
|
81
|
+
* timer, and under jest the abort is one.
|
|
82
|
+
*/
|
|
83
|
+
const yieldToEventLoop = (() => {
|
|
84
|
+
if ((isElectron || !isNode) && typeof MessageChannel !== 'undefined') {
|
|
85
|
+
const channel = new MessageChannel();
|
|
86
|
+
let resolvers = [];
|
|
87
|
+
channel.port1.onmessage = () => {
|
|
88
|
+
const pending = resolvers;
|
|
89
|
+
resolvers = [];
|
|
90
|
+
for (const resolve of pending) {
|
|
91
|
+
resolve();
|
|
92
|
+
}
|
|
93
|
+
};
|
|
94
|
+
return () => new Promise(resolve => {
|
|
95
|
+
resolvers.push(resolve);
|
|
96
|
+
channel.port2.postMessage(0);
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
return () => new Promise(resolve => {
|
|
100
|
+
setTimeout(resolve, 0);
|
|
101
|
+
});
|
|
102
|
+
})();
|
|
103
|
+
/**
|
|
104
|
+
* Cancellation for a loop that can run for seconds without awaiting — a
|
|
105
|
+
* whole-genome projection, a matrix fill. A `signal.aborted` read inside such a
|
|
106
|
+
* loop never changes, because the abort is a posted message; the loop has to
|
|
107
|
+
* give the event loop a turn now and then. A loop bounded by the byte gate or
|
|
108
|
+
* one region's features finishes before this would matter and only checks.
|
|
109
|
+
*
|
|
110
|
+
* const breakpoint = createAbortBreakpoint(signal)
|
|
111
|
+
* for (const row of rows) {
|
|
112
|
+
* if (breakpoint.due()) {
|
|
113
|
+
* await breakpoint.yield()
|
|
114
|
+
* }
|
|
115
|
+
* …
|
|
116
|
+
* }
|
|
117
|
+
*
|
|
118
|
+
* Two calls rather than one because an `await` on a non-promise still costs a
|
|
119
|
+
* microtask, about 60 ns against 2 ns for the `due()` read, and a loop over
|
|
120
|
+
* every read in a pileup notices the difference.
|
|
121
|
+
*/
|
|
122
|
+
export function createAbortBreakpoint(signal) {
|
|
123
|
+
const gate = createTimeGate();
|
|
124
|
+
return {
|
|
125
|
+
due: () => gate(YIELD_INTERVAL_MS),
|
|
126
|
+
async yield() {
|
|
127
|
+
await yieldToEventLoop();
|
|
128
|
+
checkAbortSignal(signal);
|
|
129
|
+
},
|
|
130
|
+
};
|
|
131
|
+
}
|
|
@@ -11,7 +11,7 @@ import type { IStateTreeNode } from '@jbrowse/mobx-state-tree';
|
|
|
11
11
|
*
|
|
12
12
|
* Keyed on the adapter config rather than memoized for the display's life, so
|
|
13
13
|
* a track re-pointed in the config editor stops serving the old header's
|
|
14
|
-
* descriptions. Cleared on failure so a later click retries. No
|
|
14
|
+
* descriptions. Cleared on failure so a later click retries. No signal and
|
|
15
15
|
* no status: nothing to narrate, and nothing a cancel could save — the widget
|
|
16
16
|
* opens on the result.
|
|
17
17
|
*/
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { isDataCurrent } from './isDataCurrent.js';
|
|
2
2
|
import { getRpcSessionId } from './parentWalk.js';
|
|
3
3
|
import { getRpcHost } from './sessionServices.js';
|
|
4
4
|
/**
|
|
@@ -13,19 +13,19 @@ import { getRpcHost } from './sessionServices.js';
|
|
|
13
13
|
*
|
|
14
14
|
* Keyed on the adapter config rather than memoized for the display's life, so
|
|
15
15
|
* a track re-pointed in the config editor stops serving the old header's
|
|
16
|
-
* descriptions. Cleared on failure so a later click retries. No
|
|
16
|
+
* descriptions. Cleared on failure so a later click retries. No signal and
|
|
17
17
|
* no status: nothing to narrate, and nothing a cancel could save — the widget
|
|
18
18
|
* opens on the result.
|
|
19
19
|
*/
|
|
20
20
|
export function createAdapterMetadataFetch(self) {
|
|
21
21
|
let cached;
|
|
22
22
|
return () => {
|
|
23
|
-
const
|
|
24
|
-
if (cached
|
|
23
|
+
const { adapterConfig } = self;
|
|
24
|
+
if (!cached || !isDataCurrent(cached.adapterConfig, adapterConfig)) {
|
|
25
25
|
const promise = getRpcHost(self)
|
|
26
26
|
// eslint-disable-next-line no-restricted-syntax -- nothing to narrate, nothing a cancel could save
|
|
27
27
|
.rpcManager.call(getRpcSessionId(self), 'CoreGetMetadata', {
|
|
28
|
-
adapterConfig
|
|
28
|
+
adapterConfig,
|
|
29
29
|
})
|
|
30
30
|
.catch((e) => {
|
|
31
31
|
if (cached?.promise === promise) {
|
|
@@ -33,7 +33,7 @@ export function createAdapterMetadataFetch(self) {
|
|
|
33
33
|
}
|
|
34
34
|
throw e;
|
|
35
35
|
});
|
|
36
|
-
cached = {
|
|
36
|
+
cached = { adapterConfig, promise };
|
|
37
37
|
}
|
|
38
38
|
return cached.promise;
|
|
39
39
|
};
|
|
@@ -16,7 +16,4 @@ export declare function addAndShowTrack(session: SessionWithAddSessionTrack, con
|
|
|
16
16
|
trackId: string;
|
|
17
17
|
}, view?: {
|
|
18
18
|
launchTrack: (trackId: string) => Promise<unknown>;
|
|
19
|
-
}):
|
|
20
|
-
setSubschema(slotName: string, data: Record<string, unknown>): any;
|
|
21
|
-
setSlot(slotName: string, value: unknown): void;
|
|
22
|
-
} & import("@jbrowse/mobx-state-tree").IStateTreeNode<import("../configuration/types.ts").AnyConfigurationSchemaType>) | undefined;
|
|
19
|
+
}): import("../configuration/types.ts").AnyConfigurationModel | undefined;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Stamp `baseUri` next to every `uri` in a config
|
|
3
|
-
*
|
|
2
|
+
* Stamp `baseUri` next to every `uri` in a config, and beside a MultiWiggle
|
|
3
|
+
* `bigWigs` array of bare URI strings, so relative URIs resolve against the
|
|
4
|
+
* location the config itself was loaded from. jbrowse-web runs this
|
|
4
5
|
* when it fetches a config.json from a URL; anything that injects a fetched
|
|
5
6
|
* config as an object (a hub, a track hub connection, a headless render) has to
|
|
6
7
|
* run it too, or the config's relative data URIs resolve against the page.
|
|
@@ -9,6 +10,13 @@
|
|
|
9
10
|
* schema and expandAssemblyConfigShorthand read `baseUri` back out.
|
|
10
11
|
*/
|
|
11
12
|
export declare function addRelativeUris(config: Record<string, unknown> | null, base: URL): void;
|
|
13
|
+
/**
|
|
14
|
+
* A copy of `config` with every relative URI stamped against the page, which
|
|
15
|
+
* is what the page itself would resolve it against. An RPC worker started from
|
|
16
|
+
* a `blob:` URL has no such base, so a location it receives without one fails
|
|
17
|
+
* to parse there.
|
|
18
|
+
*/
|
|
19
|
+
export declare function withPageBaseUri<T>(config: T): T;
|
|
12
20
|
/**
|
|
13
21
|
* Inverse of {@link addRelativeUris}: recursively delete every synthetic
|
|
14
22
|
* `baseUri` key (mutates in place), e.g. before serializing a config snapshot
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Stamp `baseUri` next to every `uri` in a config
|
|
3
|
-
*
|
|
2
|
+
* Stamp `baseUri` next to every `uri` in a config, and beside a MultiWiggle
|
|
3
|
+
* `bigWigs` array of bare URI strings, so relative URIs resolve against the
|
|
4
|
+
* location the config itself was loaded from. jbrowse-web runs this
|
|
4
5
|
* when it fetches a config.json from a URL; anything that injects a fetched
|
|
5
6
|
* config as an object (a hub, a track hub connection, a headless render) has to
|
|
6
7
|
* run it too, or the config's relative data URIs resolve against the page.
|
|
@@ -11,16 +12,30 @@
|
|
|
11
12
|
export function addRelativeUris(config, base) {
|
|
12
13
|
if (typeof config === 'object' && config !== null) {
|
|
13
14
|
for (const key of Object.keys(config)) {
|
|
14
|
-
|
|
15
|
-
|
|
15
|
+
const value = config[key];
|
|
16
|
+
if (typeof value === 'object' && value !== null) {
|
|
17
|
+
addRelativeUris(value, base);
|
|
16
18
|
}
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
config.baseUri = config.baseUri ?? base.href;
|
|
19
|
+
if (key === 'uri' || (key === 'bigWigs' && Array.isArray(value))) {
|
|
20
|
+
config.baseUri ??= base.href;
|
|
20
21
|
}
|
|
21
22
|
}
|
|
22
23
|
}
|
|
23
24
|
}
|
|
25
|
+
/**
|
|
26
|
+
* A copy of `config` with every relative URI stamped against the page, which
|
|
27
|
+
* is what the page itself would resolve it against. An RPC worker started from
|
|
28
|
+
* a `blob:` URL has no such base, so a location it receives without one fails
|
|
29
|
+
* to parse there.
|
|
30
|
+
*/
|
|
31
|
+
export function withPageBaseUri(config) {
|
|
32
|
+
if (typeof document === 'undefined' || config === undefined) {
|
|
33
|
+
return config;
|
|
34
|
+
}
|
|
35
|
+
const copy = structuredClone(config);
|
|
36
|
+
addRelativeUris(copy, new URL(document.baseURI));
|
|
37
|
+
return copy;
|
|
38
|
+
}
|
|
24
39
|
/**
|
|
25
40
|
* Inverse of {@link addRelativeUris}: recursively delete every synthetic
|
|
26
41
|
* `baseUri` key (mutates in place), e.g. before serializing a config snapshot
|
|
@@ -82,13 +82,10 @@ export declare function addTrackFromWidget({ model, session, conf, }: {
|
|
|
82
82
|
name?: string;
|
|
83
83
|
assemblyNames?: (string | undefined)[];
|
|
84
84
|
};
|
|
85
|
-
}): (import("@jbrowse/mobx-state-tree").$EmptyObjectBrand & Partial<{
|
|
85
|
+
}): import("../configuration/types.ts").AnyConfigurationModel | (import("@jbrowse/mobx-state-tree").$EmptyObjectBrand & Partial<{
|
|
86
86
|
[x: string]: any;
|
|
87
87
|
}> & {
|
|
88
88
|
trackId: string;
|
|
89
89
|
name?: string;
|
|
90
90
|
assemblyNames?: (string | undefined)[];
|
|
91
|
-
}) |
|
|
92
|
-
setSubschema(slotName: string, data: Record<string, unknown>): any;
|
|
93
|
-
setSlot(slotName: string, value: unknown): void;
|
|
94
|
-
} & IStateTreeNode<import("../configuration/types.ts").AnyConfigurationSchemaType>) | undefined;
|
|
91
|
+
}) | undefined;
|
|
@@ -15,3 +15,12 @@ import type { AnimationMode } from './types/index.ts';
|
|
|
15
15
|
* honors it.
|
|
16
16
|
*/
|
|
17
17
|
export declare function animationAllowed(mode: AnimationMode): boolean;
|
|
18
|
+
/** how long a layout morph takes from where it drew to where it now draws */
|
|
19
|
+
export declare const MORPH_DURATION_MS = 300;
|
|
20
|
+
export declare function easeInOutCubic(t: number): number;
|
|
21
|
+
/**
|
|
22
|
+
* The wall clock a morph is timed on. Falls back to the epoch clock rather than
|
|
23
|
+
* a constant where `performance` is missing: a clock that never advances
|
|
24
|
+
* leaves a frame loop at progress 0 forever.
|
|
25
|
+
*/
|
|
26
|
+
export declare function morphClockMs(): number;
|
|
@@ -20,3 +20,16 @@ export function animationAllowed(mode) {
|
|
|
20
20
|
return (hasFrameClock &&
|
|
21
21
|
(mode === 'enabled' || (mode === 'system' && !prefersReduced)));
|
|
22
22
|
}
|
|
23
|
+
/** how long a layout morph takes from where it drew to where it now draws */
|
|
24
|
+
export const MORPH_DURATION_MS = 300;
|
|
25
|
+
export function easeInOutCubic(t) {
|
|
26
|
+
return t < 0.5 ? 4 * t * t * t : 1 - (-2 * t + 2) ** 3 / 2;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* The wall clock a morph is timed on. Falls back to the epoch clock rather than
|
|
30
|
+
* a constant where `performance` is missing: a clock that never advances
|
|
31
|
+
* leaves a frame loop at progress 0 forever.
|
|
32
|
+
*/
|
|
33
|
+
export function morphClockMs() {
|
|
34
|
+
return typeof performance === 'undefined' ? Date.now() : performance.now();
|
|
35
|
+
}
|
|
@@ -1,10 +1,15 @@
|
|
|
1
|
-
|
|
1
|
+
import type { VirtualScrollModel } from './useVirtualScrollWheel.ts';
|
|
2
|
+
export interface RowResizeTarget extends VirtualScrollModel {
|
|
3
|
+
/** resolved, never the 0/fit sentinel — this is divided by */
|
|
2
4
|
effectiveRowHeight: number;
|
|
3
|
-
scrollTop: number;
|
|
4
5
|
nrow: number;
|
|
5
|
-
viewportHeight: number;
|
|
6
6
|
setRowHeight: (n: number) => void;
|
|
7
|
-
setScrollTop: (n: number) => void;
|
|
8
7
|
}
|
|
8
|
+
/**
|
|
9
|
+
* shift+wheel over a row stack: resize the rows, pinning the row under the
|
|
10
|
+
* cursor. The floor is the fit height, so rows never shrink past filling the
|
|
11
|
+
* viewport. The cap stops a gesture but never moves rows on its own, so it
|
|
12
|
+
* rises to a current height already above it (a pinned `rowHeight` is
|
|
13
|
+
* unbounded).
|
|
14
|
+
*/
|
|
9
15
|
export declare function applyRowResizeWheel(e: WheelEvent, el: HTMLElement, model: RowResizeTarget): void;
|
|
10
|
-
export {};
|
|
@@ -1,30 +1,19 @@
|
|
|
1
|
-
// shift+wheel resizes the sample rows (a vertical-zoom gesture) rather than
|
|
2
|
-
// scrolling, keeping the row under the cursor pinned in place as the height
|
|
3
|
-
// changes. Shared by every row-stack display — both variant displays and MAF —
|
|
4
|
-
// so the gesture stays identical wherever rows have a resolved height and a
|
|
5
|
-
// scroll offset. setScrollTop clamps to the new scrollableHeight, so the raw
|
|
6
|
-
// target is passed through unclamped.
|
|
7
1
|
import { normalizeWheelDelta } from './wheelZoom.js';
|
|
8
2
|
const MAX_ROW_HEIGHT = 20;
|
|
9
|
-
//
|
|
10
|
-
//
|
|
11
|
-
// accumulate smoothly instead of the old sign-based ±1-per-event, which flew
|
|
12
|
-
// through the whole range on a trackpad's event flood.
|
|
3
|
+
// A mouse notch (~100px) nudges the height ~0.4px, and a trackpad's small
|
|
4
|
+
// deltas accumulate smoothly rather than flying through the range.
|
|
13
5
|
const RESIZE_PX_PER_WHEEL_PX = 1 / 240;
|
|
6
|
+
/**
|
|
7
|
+
* shift+wheel over a row stack: resize the rows, pinning the row under the
|
|
8
|
+
* cursor. The floor is the fit height, so rows never shrink past filling the
|
|
9
|
+
* viewport. The cap stops a gesture but never moves rows on its own, so it
|
|
10
|
+
* rises to a current height already above it (a pinned `rowHeight` is
|
|
11
|
+
* unbounded).
|
|
12
|
+
*/
|
|
14
13
|
export function applyRowResizeWheel(e, el, model) {
|
|
15
14
|
e.preventDefault();
|
|
16
|
-
// scroll up (deltaY < 0) grows rows; proportional to the normalized delta so
|
|
17
|
-
// the speed is consistent across mice/trackpads and finer than ±1/event.
|
|
18
15
|
const delta = -normalizeWheelDelta(e.deltaY, e.deltaMode) * RESIZE_PX_PER_WHEEL_PX;
|
|
19
|
-
|
|
20
|
-
const minRowHeight = model.viewportHeight / Math.max(1, model.nrow);
|
|
21
|
-
// The cap may stop the gesture going further; it may never move the rows on
|
|
22
|
-
// its own. So both heights that can already sit above MAX_ROW_HEIGHT raise
|
|
23
|
-
// it: the auto-fit floor (few samples), and the current height (a pinned
|
|
24
|
-
// `rowHeight` — the config slot and the "Custom..." dialog are both
|
|
25
|
-
// unbounded, and MAF's own docs example is 12 while a bases-mode row wants
|
|
26
|
-
// more). Without the second, a 40px pinned row met `min(20, 40.4)` on the
|
|
27
|
-
// first notch of a *grow* gesture and halved.
|
|
16
|
+
const minRowHeight = model.scrollViewportHeight / Math.max(1, model.nrow);
|
|
28
17
|
const maxRowHeight = Math.max(MAX_ROW_HEIGHT, minRowHeight, model.effectiveRowHeight);
|
|
29
18
|
const newRowHeight = Math.max(minRowHeight, Math.min(maxRowHeight, model.effectiveRowHeight + delta));
|
|
30
19
|
const mouseY = e.clientY - el.getBoundingClientRect().top;
|
package/esm/util/bandLayout.d.ts
CHANGED
|
@@ -39,11 +39,11 @@ export interface BandStack<K extends string> {
|
|
|
39
39
|
/**
|
|
40
40
|
* #api core/util
|
|
41
41
|
* Fold an ordered set of bands into tops and a bottom. The order is the
|
|
42
|
-
* argument, so a display states its band order exactly once
|
|
43
|
-
* and pick all
|
|
44
|
-
*
|
|
42
|
+
* argument, so a display states its band order exactly once. Reserve, paint
|
|
43
|
+
* and pick all call this function, so the reserved and painted positions
|
|
44
|
+
* cannot disagree.
|
|
45
45
|
*
|
|
46
|
-
* Only the fold is shared
|
|
46
|
+
* Only the fold is shared; the rest stays in each display. Per-lane
|
|
47
47
|
* iteration runs this once per lane, sticky-vs-scrolling is a property of how
|
|
48
48
|
* the result is projected to the screen, and a band drawn outside its
|
|
49
49
|
* reservation (an overlay) carries its own draw rect beside the stack.
|
package/esm/util/bandLayout.js
CHANGED
|
@@ -14,11 +14,11 @@ export function reservedPx(band) {
|
|
|
14
14
|
/**
|
|
15
15
|
* #api core/util
|
|
16
16
|
* Fold an ordered set of bands into tops and a bottom. The order is the
|
|
17
|
-
* argument, so a display states its band order exactly once
|
|
18
|
-
* and pick all
|
|
19
|
-
*
|
|
17
|
+
* argument, so a display states its band order exactly once. Reserve, paint
|
|
18
|
+
* and pick all call this function, so the reserved and painted positions
|
|
19
|
+
* cannot disagree.
|
|
20
20
|
*
|
|
21
|
-
* Only the fold is shared
|
|
21
|
+
* Only the fold is shared; the rest stays in each display. Per-lane
|
|
22
22
|
* iteration runs this once per lane, sticky-vs-scrolling is a property of how
|
|
23
23
|
* the result is projected to the screen, and a band drawn outside its
|
|
24
24
|
* reservation (an overlay) carries its own draw rect beside the stack.
|
|
@@ -29,10 +29,11 @@ const MAX_HANDLE_PX = 200;
|
|
|
29
29
|
const MAX_BOW_PX = 30;
|
|
30
30
|
// A discordant connection bows *down* instead of up, so the two classes read
|
|
31
31
|
// apart at a glance. Both renderers follow this: BreakpointSplitView dips its
|
|
32
|
-
// same-level discordant links, and the pileup overlay dips every
|
|
33
|
-
// (
|
|
34
|
-
//
|
|
35
|
-
//
|
|
32
|
+
// same-level discordant links, and the pileup overlay dips every discordant
|
|
33
|
+
// curve it draws (a normal-orientation pair is a plain line, or bows up over its
|
|
34
|
+
// row where a hidden-segment one would lie on a chain's connecting line). Keep
|
|
35
|
+
// it that way — a renderer that opts out makes "below the reads" mean two
|
|
36
|
+
// different things in two views of the same data.
|
|
36
37
|
//
|
|
37
38
|
// Depth comes from the connection's own horizontal span
|
|
38
39
|
// rather than reaching for some fixed row: with "view as pairs" / "link
|
|
@@ -1,78 +1,24 @@
|
|
|
1
1
|
import type { BgzfWorkerPool } from '@gmod/bgzf-filehandle';
|
|
2
2
|
/**
|
|
3
|
-
* The BGZF inflate pool the indexed-format libraries decompress
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
* ## Call it, don't hoist it
|
|
24
|
-
*
|
|
25
|
-
* This is a function and not an exported constant on purpose: it spawns workers
|
|
26
|
-
* the first time it is called, and a module-level call would spawn them on
|
|
27
|
-
* import, in every context that pulls in anything from `util`, whether or not a
|
|
28
|
-
* bgzip-backed track is ever opened. Call it where a file is constructed.
|
|
29
|
-
*
|
|
30
|
-
* ## The dynamic import is about bundle weight, and only that
|
|
31
|
-
*
|
|
32
|
-
* `@gmod/bgzf-filehandle` inlines its worker bundle as a base64 string, and
|
|
33
|
-
* `getSharedWorkerPool` is what reaches it, so a **static** import pins that
|
|
34
|
-
* blob into the initial bundle of every entry point that reaches this helper.
|
|
35
|
-
* Measured with esbuild, splitting and minifying, on the import alone:
|
|
36
|
-
*
|
|
37
|
-
* ```
|
|
38
|
-
* static entry 54.7kb (23.4kb gzipped) — the blob is in the initial bundle
|
|
39
|
-
* dynamic entry 114b (141b gzipped) + 123.9kb in a split chunk
|
|
40
|
-
* ```
|
|
41
|
-
*
|
|
42
|
-
* So ~23kb gzipped off every bundle that can reach a bgzip adapter, deferred to
|
|
43
|
-
* a chunk that is only fetched once such a track is actually opened. Core's
|
|
44
|
-
* `util/unzip.ts` and `fetchAndMaybeUnzip.ts` dodge it the same way. It costs
|
|
45
|
-
* nothing to do, because the libraries want a promise anyway — their callers'
|
|
46
|
-
* `configure()` is synchronous and the pool is only available asynchronously.
|
|
47
|
-
*
|
|
48
|
-
* **It is not about test speed**, though it has been described that way. That
|
|
49
|
-
* claim was checked here and did not reproduce: three jbrowse-web variant
|
|
50
|
-
* suites ran 13.887s static against 13.856s dynamic, warm cache, and a 29s
|
|
51
|
-
* reading that started this off turned out to be a cold jest transform cache in
|
|
52
|
-
* a fresh worktree. Don't reintroduce a static import on the grounds that the
|
|
53
|
-
* jest argument was wrong — the bundle argument above is the real one, and it
|
|
54
|
-
* stands on its own.
|
|
55
|
-
*
|
|
56
|
-
* The `catch` is deliberate, but for a plain reason rather than a specific
|
|
57
|
-
* failure: a pool is an optimization, `@gmod/bam` and `@gmod/tabix` both await
|
|
58
|
-
* this, and anything going wrong here has to degrade to inflating in process
|
|
59
|
-
* rather than break every read. A documented CJS-interop throw under jest was
|
|
60
|
-
* the original motivation; that no longer reproduces (core's own suite, the
|
|
61
|
-
* BamAdapter suites and jbrowse-web's Alignments suite all pass with the catch
|
|
62
|
-
* removed), so keep it for the invariant, not the anecdote.
|
|
63
|
-
*
|
|
64
|
-
* ## Safe to pass unconditionally
|
|
65
|
-
*
|
|
66
|
-
* Returns a promise, and the libraries await it at the point of use rather than
|
|
67
|
-
* at construction — which is what lets a synchronous `configure()` hand the
|
|
68
|
-
* pending pool straight over. It resolves to `undefined` wherever Workers
|
|
69
|
-
* cannot be created (node, jest), and `@gmod/bam` and `@gmod/tabix` then take
|
|
70
|
-
* their in-process path, so no caller needs an environment check and the test
|
|
71
|
-
* suites are unaffected.
|
|
72
|
-
*
|
|
73
|
-
* Needs no cross-origin isolation: each worker's range is transferred to it as
|
|
74
|
-
* an ArrayBuffer rather than shared, so this works on an ordinary page. That
|
|
75
|
-
* was the point of dropping SharedArrayBuffer in `@gmod/bgzf-filehandle` 6.4.0
|
|
76
|
-
* — measured, the shared transport was at parity at best.
|
|
3
|
+
* The BGZF inflate pool the indexed-format libraries decompress large chunks on,
|
|
4
|
+
* one per JS context like `decompressedBytesBudget`: one per RPC worker plus one
|
|
5
|
+
* on the main thread. BGZF decompression is 70-90% of a cold query (`@gmod/bam`
|
|
6
|
+
* ADR 0003), and its blocks inflate independently.
|
|
7
|
+
*
|
|
8
|
+
* Holding it costs nothing. `@gmod/bgzf-filehandle` 6.7 starts the workers only
|
|
9
|
+
* when a chunk of at least `POOL_MIN_DECOMPRESSED_BYTES` (0.4MB inflated)
|
|
10
|
+
* arrives, inflates in process while they boot, and inflates in process for good
|
|
11
|
+
* if one of them fails, so no read waits on a worker. What it is worth per
|
|
12
|
+
* format, and why GFF3 and GTF go without it: reference/BGZF_WORKER_POOL.md.
|
|
13
|
+
*
|
|
14
|
+
* A function over a dynamic import because the library inlines its worker bundle
|
|
15
|
+
* as a base64 string, and a static import pins it into every entry point that
|
|
16
|
+
* can reach this helper: measured with esbuild, 23.4kb gzipped against 141b. Test
|
|
17
|
+
* speed is not a reason either way; three jbrowse-web variant suites ran 13.887s
|
|
18
|
+
* static against 13.856s dynamic.
|
|
19
|
+
*
|
|
20
|
+
* Resolves to `undefined` wherever Workers cannot be created (node, jest), which
|
|
21
|
+
* keeps `@gmod/bam` and `@gmod/tabix` on their in-process path, and the `catch`
|
|
22
|
+
* keeps anything else going wrong here on it too.
|
|
77
23
|
*/
|
|
78
24
|
export declare function sharedBgzfWorkerPool(): Promise<BgzfWorkerPool | undefined>;
|
|
@@ -1,78 +1,24 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* The BGZF inflate pool the indexed-format libraries decompress
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
* ## Call it, don't hoist it
|
|
23
|
-
*
|
|
24
|
-
* This is a function and not an exported constant on purpose: it spawns workers
|
|
25
|
-
* the first time it is called, and a module-level call would spawn them on
|
|
26
|
-
* import, in every context that pulls in anything from `util`, whether or not a
|
|
27
|
-
* bgzip-backed track is ever opened. Call it where a file is constructed.
|
|
28
|
-
*
|
|
29
|
-
* ## The dynamic import is about bundle weight, and only that
|
|
30
|
-
*
|
|
31
|
-
* `@gmod/bgzf-filehandle` inlines its worker bundle as a base64 string, and
|
|
32
|
-
* `getSharedWorkerPool` is what reaches it, so a **static** import pins that
|
|
33
|
-
* blob into the initial bundle of every entry point that reaches this helper.
|
|
34
|
-
* Measured with esbuild, splitting and minifying, on the import alone:
|
|
35
|
-
*
|
|
36
|
-
* ```
|
|
37
|
-
* static entry 54.7kb (23.4kb gzipped) — the blob is in the initial bundle
|
|
38
|
-
* dynamic entry 114b (141b gzipped) + 123.9kb in a split chunk
|
|
39
|
-
* ```
|
|
40
|
-
*
|
|
41
|
-
* So ~23kb gzipped off every bundle that can reach a bgzip adapter, deferred to
|
|
42
|
-
* a chunk that is only fetched once such a track is actually opened. Core's
|
|
43
|
-
* `util/unzip.ts` and `fetchAndMaybeUnzip.ts` dodge it the same way. It costs
|
|
44
|
-
* nothing to do, because the libraries want a promise anyway — their callers'
|
|
45
|
-
* `configure()` is synchronous and the pool is only available asynchronously.
|
|
46
|
-
*
|
|
47
|
-
* **It is not about test speed**, though it has been described that way. That
|
|
48
|
-
* claim was checked here and did not reproduce: three jbrowse-web variant
|
|
49
|
-
* suites ran 13.887s static against 13.856s dynamic, warm cache, and a 29s
|
|
50
|
-
* reading that started this off turned out to be a cold jest transform cache in
|
|
51
|
-
* a fresh worktree. Don't reintroduce a static import on the grounds that the
|
|
52
|
-
* jest argument was wrong — the bundle argument above is the real one, and it
|
|
53
|
-
* stands on its own.
|
|
54
|
-
*
|
|
55
|
-
* The `catch` is deliberate, but for a plain reason rather than a specific
|
|
56
|
-
* failure: a pool is an optimization, `@gmod/bam` and `@gmod/tabix` both await
|
|
57
|
-
* this, and anything going wrong here has to degrade to inflating in process
|
|
58
|
-
* rather than break every read. A documented CJS-interop throw under jest was
|
|
59
|
-
* the original motivation; that no longer reproduces (core's own suite, the
|
|
60
|
-
* BamAdapter suites and jbrowse-web's Alignments suite all pass with the catch
|
|
61
|
-
* removed), so keep it for the invariant, not the anecdote.
|
|
62
|
-
*
|
|
63
|
-
* ## Safe to pass unconditionally
|
|
64
|
-
*
|
|
65
|
-
* Returns a promise, and the libraries await it at the point of use rather than
|
|
66
|
-
* at construction — which is what lets a synchronous `configure()` hand the
|
|
67
|
-
* pending pool straight over. It resolves to `undefined` wherever Workers
|
|
68
|
-
* cannot be created (node, jest), and `@gmod/bam` and `@gmod/tabix` then take
|
|
69
|
-
* their in-process path, so no caller needs an environment check and the test
|
|
70
|
-
* suites are unaffected.
|
|
71
|
-
*
|
|
72
|
-
* Needs no cross-origin isolation: each worker's range is transferred to it as
|
|
73
|
-
* an ArrayBuffer rather than shared, so this works on an ordinary page. That
|
|
74
|
-
* was the point of dropping SharedArrayBuffer in `@gmod/bgzf-filehandle` 6.4.0
|
|
75
|
-
* — measured, the shared transport was at parity at best.
|
|
2
|
+
* The BGZF inflate pool the indexed-format libraries decompress large chunks on,
|
|
3
|
+
* one per JS context like `decompressedBytesBudget`: one per RPC worker plus one
|
|
4
|
+
* on the main thread. BGZF decompression is 70-90% of a cold query (`@gmod/bam`
|
|
5
|
+
* ADR 0003), and its blocks inflate independently.
|
|
6
|
+
*
|
|
7
|
+
* Holding it costs nothing. `@gmod/bgzf-filehandle` 6.7 starts the workers only
|
|
8
|
+
* when a chunk of at least `POOL_MIN_DECOMPRESSED_BYTES` (0.4MB inflated)
|
|
9
|
+
* arrives, inflates in process while they boot, and inflates in process for good
|
|
10
|
+
* if one of them fails, so no read waits on a worker. What it is worth per
|
|
11
|
+
* format, and why GFF3 and GTF go without it: reference/BGZF_WORKER_POOL.md.
|
|
12
|
+
*
|
|
13
|
+
* A function over a dynamic import because the library inlines its worker bundle
|
|
14
|
+
* as a base64 string, and a static import pins it into every entry point that
|
|
15
|
+
* can reach this helper: measured with esbuild, 23.4kb gzipped against 141b. Test
|
|
16
|
+
* speed is not a reason either way; three jbrowse-web variant suites ran 13.887s
|
|
17
|
+
* static against 13.856s dynamic.
|
|
18
|
+
*
|
|
19
|
+
* Resolves to `undefined` wherever Workers cannot be created (node, jest), which
|
|
20
|
+
* keeps `@gmod/bam` and `@gmod/tabix` on their in-process path, and the `catch`
|
|
21
|
+
* keeps anything else going wrong here on it too.
|
|
76
22
|
*/
|
|
77
23
|
export function sharedBgzfWorkerPool() {
|
|
78
24
|
return import('@gmod/bgzf-filehandle')
|
|
@@ -17,7 +17,7 @@ type OnProgress = (current: number, total?: number) => void;
|
|
|
17
17
|
* moment that fetch was superseded — the display's latest-wins guard gates the
|
|
18
18
|
* old callback off — so the fetch replacing it awaited a multi-GB parse behind
|
|
19
19
|
* a blank loading overlay.
|
|
20
|
-
* - **`
|
|
20
|
+
* - **`signal` is withheld from the shared work.** Honoring one caller's
|
|
21
21
|
* cancel would abort a parse the caller replacing it is already waiting on,
|
|
22
22
|
* and reject them both. A superseded fetch just stops listening. Cancellation
|
|
23
23
|
* stays with the per-call work (indexed range queries), which no one else is
|
package/esm/util/cachedSetup.js
CHANGED
|
@@ -15,7 +15,7 @@ import { downloadStatus } from './progress.js';
|
|
|
15
15
|
* moment that fetch was superseded — the display's latest-wins guard gates the
|
|
16
16
|
* old callback off — so the fetch replacing it awaited a multi-GB parse behind
|
|
17
17
|
* a blank loading overlay.
|
|
18
|
-
* - **`
|
|
18
|
+
* - **`signal` is withheld from the shared work.** Honoring one caller's
|
|
19
19
|
* cancel would abort a parse the caller replacing it is already waiting on,
|
|
20
20
|
* and reject them both. A superseded fetch just stops listening. Cancellation
|
|
21
21
|
* stays with the per-call work (indexed range queries), which no one else is
|
|
@@ -39,7 +39,7 @@ export function cachedSetup({ setup, label, }) {
|
|
|
39
39
|
const run = (opts, onProgress) => {
|
|
40
40
|
cached ??= setup({
|
|
41
41
|
...opts,
|
|
42
|
-
|
|
42
|
+
signal: undefined,
|
|
43
43
|
statusCallback: status => {
|
|
44
44
|
for (const cb of waiting) {
|
|
45
45
|
cb(status);
|