@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,4 +1,3 @@
|
|
|
1
|
-
import { adapterConfigKey } from './adapterConfigKey.js';
|
|
2
1
|
import { installFetch } from './installFetch.js';
|
|
3
2
|
/**
|
|
4
3
|
* A **prerequisite read**: one RPC about the adapter itself, beside the
|
|
@@ -36,7 +35,7 @@ import { installFetch } from './installFetch.js';
|
|
|
36
35
|
* nothing; a header is not a load.
|
|
37
36
|
*
|
|
38
37
|
* `createAdapterMetadataFetch` keys on the same adapter config and is
|
|
39
|
-
* deliberately NOT one of these: no trigger, no
|
|
38
|
+
* deliberately NOT one of these: no trigger, no signal and no status,
|
|
40
39
|
* because it is fetched lazily when a details widget opens and the widget opens
|
|
41
40
|
* on the result. A prerequisite read is the one a display's own fetch waits on.
|
|
42
41
|
*
|
|
@@ -53,7 +52,7 @@ import { installFetch } from './installFetch.js';
|
|
|
53
52
|
* Everything the skeleton gives it is the point of going through the skeleton:
|
|
54
53
|
* the latest-wins rotation (so a superseding read aborts the one it replaced,
|
|
55
54
|
* and only a superseding read does — a user cancel of the primary fetch cannot
|
|
56
|
-
* strand the display the way sharing its
|
|
55
|
+
* strand the display the way sharing its signal would), the clear at the start,
|
|
57
56
|
* the currency-guarded error rule, the unconditional `reloadCounter` read that
|
|
58
57
|
* makes the chrome's Retry re-run this, and the retired status slot that keeps a
|
|
59
58
|
* failed read from leaving a progress chip up for good.
|
|
@@ -65,7 +64,7 @@ export function installPrerequisiteFetch(self, { name, delay, report, gate = ()
|
|
|
65
64
|
report,
|
|
66
65
|
gate: () => !self.isMinimized && gate(),
|
|
67
66
|
prepare: () => ({ adapterConfig: self.adapterConfig }),
|
|
68
|
-
fetchKey: ({ adapterConfig }) =>
|
|
67
|
+
fetchKey: ({ adapterConfig }) => adapterConfig,
|
|
69
68
|
run: ({ adapterConfig }, ctx) => run(adapterConfig, ctx),
|
|
70
69
|
commit,
|
|
71
70
|
setError,
|
package/esm/util/io/index.js
CHANGED
|
@@ -19,11 +19,14 @@ export function resolveUriLocation(location) {
|
|
|
19
19
|
: location;
|
|
20
20
|
}
|
|
21
21
|
/**
|
|
22
|
-
* The local path a `file:` URI names, or undefined for
|
|
23
|
-
* Windows URL parses as `/C:/data/x.bam`, whose leading slash
|
|
24
|
-
* grammar rather than the path.
|
|
22
|
+
* The local path a `file:` URI or a bare absolute path names, or undefined for
|
|
23
|
+
* anything else. A Windows URL parses as `/C:/data/x.bam`, whose leading slash
|
|
24
|
+
* is part of the URL grammar rather than the path.
|
|
25
25
|
*/
|
|
26
|
-
function
|
|
26
|
+
function uriToLocalPath(uri) {
|
|
27
|
+
if (uri.startsWith('/') || /^[a-z]:[\\/]/i.test(uri)) {
|
|
28
|
+
return uri;
|
|
29
|
+
}
|
|
27
30
|
if (!uri.startsWith('file:')) {
|
|
28
31
|
return undefined;
|
|
29
32
|
}
|
|
@@ -82,14 +85,11 @@ export function openLocation(location, pluginManager) {
|
|
|
82
85
|
// a config that names its files relative to itself found no account at all
|
|
83
86
|
// and read every one of them unauthenticated.
|
|
84
87
|
const absoluteLocation = resolveUriLocation(location);
|
|
85
|
-
// A file: URI
|
|
86
|
-
//
|
|
87
|
-
//
|
|
88
|
-
// 'reads.bam'
|
|
89
|
-
|
|
90
|
-
// localPath keeps that whole chain on the one code path that can open a
|
|
91
|
-
// local file, instead of a fetch that no range request survives.
|
|
92
|
-
const localPath = fileUrlToLocalPath(absoluteLocation.uri);
|
|
88
|
+
// A file: URI or a bare absolute path names a file on this machine. A
|
|
89
|
+
// config.json opened from disk resolves `uri: 'reads.bam'` against its own
|
|
90
|
+
// directory to file:///dir/reads.bam, and a session built over MCP writes
|
|
91
|
+
// `uri: '/dir/reads.bam'` with no baseUri at all; fetched, either is a 404.
|
|
92
|
+
const localPath = uriToLocalPath(absoluteLocation.uri);
|
|
93
93
|
if (localPath !== undefined && (isNode || isElectron)) {
|
|
94
94
|
return openLocation({ localPath, locationType: 'LocalPathLocation' });
|
|
95
95
|
}
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
* is
|
|
2
|
+
* Whether the key held data was committed under still equals the key a fetch
|
|
3
|
+
* issued now would carry. Keys are values compared structurally, so a stamp
|
|
4
|
+
* that kept its identity short-circuits on `===`, and an `undefined`-valued
|
|
5
|
+
* field or a fieldless class instance is still a distinct state — the two
|
|
6
|
+
* shapes `JSON.stringify` flattened. An `undefined` loaded key is nothing
|
|
7
|
+
* fetched yet, so never current.
|
|
6
8
|
*/
|
|
7
|
-
export declare function isDataCurrent(
|
|
9
|
+
export declare function isDataCurrent(loaded: unknown, current: unknown): boolean;
|
|
@@ -1,9 +1,12 @@
|
|
|
1
|
+
import { compareStructural } from 'mobx';
|
|
1
2
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
* is
|
|
3
|
+
* Whether the key held data was committed under still equals the key a fetch
|
|
4
|
+
* issued now would carry. Keys are values compared structurally, so a stamp
|
|
5
|
+
* that kept its identity short-circuits on `===`, and an `undefined`-valued
|
|
6
|
+
* field or a fieldless class instance is still a distinct state — the two
|
|
7
|
+
* shapes `JSON.stringify` flattened. An `undefined` loaded key is nothing
|
|
8
|
+
* fetched yet, so never current.
|
|
6
9
|
*/
|
|
7
|
-
export function isDataCurrent(
|
|
8
|
-
return
|
|
10
|
+
export function isDataCurrent(loaded, current) {
|
|
11
|
+
return loaded !== undefined && compareStructural(loaded, current);
|
|
9
12
|
}
|
package/esm/util/jexl.js
CHANGED
|
@@ -1,23 +1,10 @@
|
|
|
1
1
|
import { Jexl } from '@jbrowse/jexl';
|
|
2
|
+
import { categoricalColor } from '../ui/colors.js';
|
|
2
3
|
import { randomColor } from './color/index.js';
|
|
3
4
|
import { colord } from './colord.js';
|
|
4
5
|
import { jexlFeatureProxy, unwrapFeature } from './simpleFeature.js';
|
|
5
6
|
export default function JexlF( /* config?: any*/) {
|
|
6
7
|
const j = new Jexl();
|
|
7
|
-
// Memoize compilation on the instance itself. A compiled Expression closes
|
|
8
|
-
// over this instance's grammar (its registered functions), so the cache
|
|
9
|
-
// belongs here and is naturally per-instance — there is no shared cache that
|
|
10
|
-
// could bind an expression to the wrong instance's functions.
|
|
11
|
-
const rawCompile = j.compile.bind(j);
|
|
12
|
-
const cache = new Map();
|
|
13
|
-
j.compile = (code) => {
|
|
14
|
-
let expr = cache.get(code);
|
|
15
|
-
if (expr === undefined) {
|
|
16
|
-
expr = rawCompile(code);
|
|
17
|
-
cache.set(code, expr);
|
|
18
|
-
}
|
|
19
|
-
return expr;
|
|
20
|
-
};
|
|
21
8
|
// someday will make sure all of configs callbacks are added in, including
|
|
22
9
|
// ones passed in
|
|
23
10
|
// below are core functions
|
|
@@ -31,15 +18,29 @@ export default function JexlF( /* config?: any*/) {
|
|
|
31
18
|
return p ? jexlFeatureProxy(p) : undefined;
|
|
32
19
|
});
|
|
33
20
|
j.addFunction('id', (feature) => unwrapFeature(feature).id());
|
|
21
|
+
/**
|
|
22
|
+
* #jexlFunction Feature operations - getInherited | getInherited(feature, 'gene_biotype') | the attribute from the feature, or from its nearest ancestor that has it, so a CDS reads its gene's value
|
|
23
|
+
*/
|
|
24
|
+
j.addFunction('getInherited', (feature, name) => {
|
|
25
|
+
let cur = unwrapFeature(feature);
|
|
26
|
+
while (cur !== undefined) {
|
|
27
|
+
const value = cur.get(name);
|
|
28
|
+
if (value !== undefined) {
|
|
29
|
+
return value;
|
|
30
|
+
}
|
|
31
|
+
cur = cur.parent?.();
|
|
32
|
+
}
|
|
33
|
+
return undefined;
|
|
34
|
+
});
|
|
34
35
|
// let user cast a jexl type into a javascript type
|
|
35
36
|
j.addFunction('cast', (arg) => arg);
|
|
36
|
-
//
|
|
37
|
-
//
|
|
38
|
-
/**
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
37
|
+
// jexl's own list-aware min and max take varargs too; a Math.min
|
|
38
|
+
// registration would replace them
|
|
39
|
+
/**
|
|
40
|
+
* #jexlFunction Math functions | max(0, 2)
|
|
41
|
+
* #jexlFunction Math functions | min(feature.INFO.AF)
|
|
42
|
+
* #jexlFunction Math functions | sqrt(4)
|
|
43
|
+
*/
|
|
43
44
|
j.addFunction('sqrt', Math.sqrt);
|
|
44
45
|
/** #jexlFunction Math functions | ceil(0.5) */
|
|
45
46
|
j.addFunction('ceil', Math.ceil);
|
|
@@ -148,6 +149,8 @@ export default function JexlF( /* config?: any*/) {
|
|
|
148
149
|
// color helpers
|
|
149
150
|
/** #jexlFunction Color functions | randomColor(feature.type) | deterministic color from a string (e.g. a feature type) */
|
|
150
151
|
j.addFunction('randomColor', randomColor);
|
|
152
|
+
/** #jexlFunction Color functions | categoricalColor(getInherited(feature, 'biotype'), ['protein_coding']) | a palette color per value: the values listed take the palette (an optional third argument) in order, any other value a stable color no listed value paints, a missing one grey */
|
|
153
|
+
j.addFunction('categoricalColor', categoricalColor);
|
|
151
154
|
// These take and return CSS color *strings*, not Colord objects: a config
|
|
152
155
|
// `jexl:` expression has no way to construct a Colord, and a color slot
|
|
153
156
|
// holding one resolves to the invalid-color sentinel rather than a color. So
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import type { AstNode, Subject } from '@jbrowse/jexl';
|
|
2
|
+
export type JexlFilterFieldType = 'number' | 'text' | 'flag';
|
|
3
|
+
export type JexlFilterField = {
|
|
4
|
+
label: string;
|
|
5
|
+
/** unset for a field whose values may be numbers or text */
|
|
6
|
+
type?: JexlFilterFieldType;
|
|
7
|
+
group?: string;
|
|
8
|
+
description?: string;
|
|
9
|
+
/** holds several values per feature, so a comparison asks whether any does */
|
|
10
|
+
multi?: boolean;
|
|
11
|
+
values?: string[];
|
|
12
|
+
} & ({
|
|
13
|
+
path: string[];
|
|
14
|
+
} | {
|
|
15
|
+
call: string;
|
|
16
|
+
});
|
|
17
|
+
export interface FieldChoice {
|
|
18
|
+
key: string;
|
|
19
|
+
label: string;
|
|
20
|
+
type?: JexlFilterFieldType;
|
|
21
|
+
subject: Subject;
|
|
22
|
+
group?: string;
|
|
23
|
+
description?: string;
|
|
24
|
+
multi?: boolean;
|
|
25
|
+
values?: string[];
|
|
26
|
+
}
|
|
27
|
+
export type RowOp = '>' | '>=' | '<' | '<=' | '==' | '!=' | 'in' | '~' | 'set' | '!set';
|
|
28
|
+
export declare const OPERATORS: Record<JexlFilterFieldType | 'any', {
|
|
29
|
+
op: RowOp;
|
|
30
|
+
label: string;
|
|
31
|
+
}[]>;
|
|
32
|
+
export interface ConditionRow {
|
|
33
|
+
kind: 'condition';
|
|
34
|
+
id: number;
|
|
35
|
+
line?: number;
|
|
36
|
+
field?: FieldChoice;
|
|
37
|
+
op: RowOp;
|
|
38
|
+
value: string | string[];
|
|
39
|
+
}
|
|
40
|
+
export interface TextRow {
|
|
41
|
+
kind: 'text';
|
|
42
|
+
id: number;
|
|
43
|
+
line?: number;
|
|
44
|
+
text: string;
|
|
45
|
+
}
|
|
46
|
+
export type FilterRow = ConditionRow | TextRow;
|
|
47
|
+
/**
|
|
48
|
+
* Rows keep the index of the stored line they came from until one of that
|
|
49
|
+
* line's rows changes, so an untouched line is written back byte-identical.
|
|
50
|
+
*/
|
|
51
|
+
export interface FilterRows {
|
|
52
|
+
lines: readonly string[];
|
|
53
|
+
rows: FilterRow[];
|
|
54
|
+
}
|
|
55
|
+
interface Parser {
|
|
56
|
+
parse: (text: string) => AstNode | null;
|
|
57
|
+
}
|
|
58
|
+
export declare function resolveFields(fields: readonly JexlFilterField[]): {
|
|
59
|
+
key: string;
|
|
60
|
+
label: string;
|
|
61
|
+
type: JexlFilterFieldType | undefined;
|
|
62
|
+
group: string | undefined;
|
|
63
|
+
description: string | undefined;
|
|
64
|
+
multi: boolean | undefined;
|
|
65
|
+
values: string[] | undefined;
|
|
66
|
+
subject: Subject;
|
|
67
|
+
}[];
|
|
68
|
+
/**
|
|
69
|
+
* The columns an adapter's metadata describes as `{column: description}`, as
|
|
70
|
+
* a BigBed's autoSql does, less those `fields` already lists. Any other
|
|
71
|
+
* metadata describes none.
|
|
72
|
+
*/
|
|
73
|
+
export declare function describedColumns(metadata: unknown, fields: readonly JexlFilterField[]): JexlFilterField[];
|
|
74
|
+
/** A field typed into the picker rather than chosen, read as a dotted path. */
|
|
75
|
+
export declare function typedField(text: string): FieldChoice;
|
|
76
|
+
export declare function stripJexlPrefix(line: string): string;
|
|
77
|
+
export declare function readFilterRows(lines: readonly string[], parser: Parser, choices: readonly FieldChoice[]): FilterRows;
|
|
78
|
+
export declare function addRow(state: FilterRows): FilterRows;
|
|
79
|
+
export declare function replaceRow(state: FilterRows, row: FilterRow): FilterRows;
|
|
80
|
+
export declare function removeRow(state: FilterRows, id: number): FilterRows;
|
|
81
|
+
export declare function withField(row: ConditionRow, field: FieldChoice): ConditionRow;
|
|
82
|
+
export declare function withOp(row: ConditionRow, op: RowOp): ConditionRow;
|
|
83
|
+
/**
|
|
84
|
+
* The stored filters: an untouched line as it was, and every row of an edited
|
|
85
|
+
* line as a line of its own, which is equivalent because lines AND together.
|
|
86
|
+
* Rows left incomplete are dropped.
|
|
87
|
+
*/
|
|
88
|
+
export declare function writeFilterRows({ lines, rows }: FilterRows): string[];
|
|
89
|
+
export {};
|
|
@@ -0,0 +1,252 @@
|
|
|
1
|
+
import { callSubject, conditions, pathSubject, print, printCondition, } from '@jbrowse/jexl';
|
|
2
|
+
import { JEXL_PREFIX, ensureJexlPrefix, isJexl } from './jexlStrings.js';
|
|
3
|
+
export const OPERATORS = {
|
|
4
|
+
number: [
|
|
5
|
+
{ op: '>', label: '>' },
|
|
6
|
+
{ op: '>=', label: '≥' },
|
|
7
|
+
{ op: '<', label: '<' },
|
|
8
|
+
{ op: '<=', label: '≤' },
|
|
9
|
+
{ op: '==', label: '=' },
|
|
10
|
+
{ op: '!=', label: '≠' },
|
|
11
|
+
],
|
|
12
|
+
text: [
|
|
13
|
+
{ op: '==', label: 'is' },
|
|
14
|
+
{ op: '!=', label: 'is not' },
|
|
15
|
+
{ op: 'in', label: 'is one of' },
|
|
16
|
+
{ op: '~', label: 'matches' },
|
|
17
|
+
],
|
|
18
|
+
flag: [
|
|
19
|
+
{ op: 'set', label: 'is set' },
|
|
20
|
+
{ op: '!set', label: 'is not set' },
|
|
21
|
+
],
|
|
22
|
+
any: [
|
|
23
|
+
{ op: '==', label: 'is' },
|
|
24
|
+
{ op: '!=', label: 'is not' },
|
|
25
|
+
{ op: '>', label: '>' },
|
|
26
|
+
{ op: '>=', label: '≥' },
|
|
27
|
+
{ op: '<', label: '<' },
|
|
28
|
+
{ op: '<=', label: '≤' },
|
|
29
|
+
{ op: 'in', label: 'is one of' },
|
|
30
|
+
{ op: '~', label: 'matches' },
|
|
31
|
+
],
|
|
32
|
+
};
|
|
33
|
+
const ROW = 'feature';
|
|
34
|
+
function subjectKey(subject) {
|
|
35
|
+
return JSON.stringify(subject.kind === 'path'
|
|
36
|
+
? ['path', ...subject.path]
|
|
37
|
+
: ['call', subject.name, ...subject.args]);
|
|
38
|
+
}
|
|
39
|
+
export function resolveFields(fields) {
|
|
40
|
+
return fields.map(({ label, type, group, description, multi, values, ...source }) => {
|
|
41
|
+
const subject = 'call' in source
|
|
42
|
+
? callSubject(ROW, source.call)
|
|
43
|
+
: pathSubject(ROW, source.path);
|
|
44
|
+
return {
|
|
45
|
+
key: subjectKey(subject),
|
|
46
|
+
label,
|
|
47
|
+
type,
|
|
48
|
+
group,
|
|
49
|
+
description,
|
|
50
|
+
multi,
|
|
51
|
+
values,
|
|
52
|
+
subject,
|
|
53
|
+
};
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
// a feature carries these as refName, start and end
|
|
57
|
+
const BED_LOCUS_COLUMNS = new Set(['chrom', 'chromStart', 'chromEnd']);
|
|
58
|
+
/**
|
|
59
|
+
* The columns an adapter's metadata describes as `{column: description}`, as
|
|
60
|
+
* a BigBed's autoSql does, less those `fields` already lists. Any other
|
|
61
|
+
* metadata describes none.
|
|
62
|
+
*/
|
|
63
|
+
export function describedColumns(metadata, fields) {
|
|
64
|
+
const entries = metadata && typeof metadata === 'object' ? Object.entries(metadata) : [];
|
|
65
|
+
const listed = new Set(fields.map(field => field.label));
|
|
66
|
+
return entries.every((entry) => typeof entry[1] === 'string')
|
|
67
|
+
? entries
|
|
68
|
+
.filter(([name]) => !listed.has(name) && !BED_LOCUS_COLUMNS.has(name))
|
|
69
|
+
.map(([name, description]) => ({
|
|
70
|
+
label: name,
|
|
71
|
+
path: [name],
|
|
72
|
+
description: description || undefined,
|
|
73
|
+
}))
|
|
74
|
+
: [];
|
|
75
|
+
}
|
|
76
|
+
/** A field typed into the picker rather than chosen, read as a dotted path. */
|
|
77
|
+
export function typedField(text) {
|
|
78
|
+
const subject = pathSubject(ROW, text.split('.'));
|
|
79
|
+
return { key: subjectKey(subject), label: text, subject };
|
|
80
|
+
}
|
|
81
|
+
export function stripJexlPrefix(line) {
|
|
82
|
+
return isJexl(line) ? line.slice(JEXL_PREFIX.length) : line;
|
|
83
|
+
}
|
|
84
|
+
/** A field of no known type writes a value that reads as a number as one. */
|
|
85
|
+
function scalar(type, text) {
|
|
86
|
+
const number = Number(text);
|
|
87
|
+
return type === 'number' ||
|
|
88
|
+
(!type && text.trim() !== '' && Number.isFinite(number))
|
|
89
|
+
? number
|
|
90
|
+
: text;
|
|
91
|
+
}
|
|
92
|
+
function subjectLabel(subject) {
|
|
93
|
+
return subject.kind === 'path'
|
|
94
|
+
? subject.path
|
|
95
|
+
.map((key, i) => typeof key === 'number' ? `[${key}]` : i === 0 ? key : `.${key}`)
|
|
96
|
+
.join('')
|
|
97
|
+
: print(subject.node);
|
|
98
|
+
}
|
|
99
|
+
function conditionRow(c, choices, id, line) {
|
|
100
|
+
const value = 'value' in c ? c.value : undefined;
|
|
101
|
+
const key = subjectKey(c.subject);
|
|
102
|
+
const field = choices.find(f => f.key === key) ?? {
|
|
103
|
+
key,
|
|
104
|
+
label: subjectLabel(c.subject),
|
|
105
|
+
type: value === undefined ? 'flag' : undefined,
|
|
106
|
+
subject: c.subject,
|
|
107
|
+
};
|
|
108
|
+
const op = c.op;
|
|
109
|
+
const values = value === undefined ? [] : [value].flat();
|
|
110
|
+
const writesBack = (v) => op === '~' ? typeof v === 'string' : scalar(field.type, String(v)) === v;
|
|
111
|
+
return OPERATORS[field.type ?? 'any'].some(o => o.op === op) &&
|
|
112
|
+
values.every(writesBack)
|
|
113
|
+
? {
|
|
114
|
+
kind: 'condition',
|
|
115
|
+
id,
|
|
116
|
+
line,
|
|
117
|
+
field,
|
|
118
|
+
op,
|
|
119
|
+
value: Array.isArray(value) ? value.map(String) : String(value ?? ''),
|
|
120
|
+
}
|
|
121
|
+
: undefined;
|
|
122
|
+
}
|
|
123
|
+
function parseConditions(text, parser, calls) {
|
|
124
|
+
try {
|
|
125
|
+
return conditions(parser.parse(text), {
|
|
126
|
+
row: ROW,
|
|
127
|
+
accessors: { get: [] },
|
|
128
|
+
calls,
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
catch {
|
|
132
|
+
return undefined;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
export function readFilterRows(lines, parser, choices) {
|
|
136
|
+
const calls = choices.flatMap(f => f.subject.kind === 'call' ? [f.subject.name] : []);
|
|
137
|
+
const rows = [];
|
|
138
|
+
for (const [line, stored] of lines.entries()) {
|
|
139
|
+
const text = stripJexlPrefix(stored);
|
|
140
|
+
const id = rows.length;
|
|
141
|
+
const read = parseConditions(text, parser, calls)?.map((c, i) => conditionRow(c, choices, id + i, line));
|
|
142
|
+
rows.push(...(read?.every(row => row !== undefined)
|
|
143
|
+
? read
|
|
144
|
+
: [{ kind: 'text', id, line, text: text.trim() }]));
|
|
145
|
+
}
|
|
146
|
+
return { lines, rows };
|
|
147
|
+
}
|
|
148
|
+
function nextId(rows) {
|
|
149
|
+
return rows.reduce((max, row) => Math.max(max, row.id + 1), 0);
|
|
150
|
+
}
|
|
151
|
+
function emptyRow(id) {
|
|
152
|
+
return { kind: 'condition', id, op: '==', value: '' };
|
|
153
|
+
}
|
|
154
|
+
export function addRow(state) {
|
|
155
|
+
return { ...state, rows: [...state.rows, emptyRow(nextId(state.rows))] };
|
|
156
|
+
}
|
|
157
|
+
function detach(rows, id) {
|
|
158
|
+
const line = rows.find(row => row.id === id)?.line;
|
|
159
|
+
return line === undefined
|
|
160
|
+
? rows
|
|
161
|
+
: rows.map(row => (row.line === line ? { ...row, line: undefined } : row));
|
|
162
|
+
}
|
|
163
|
+
export function replaceRow(state, row) {
|
|
164
|
+
return {
|
|
165
|
+
...state,
|
|
166
|
+
rows: detach(state.rows, row.id).map(r => r.id === row.id ? { ...row, line: undefined } : r),
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
export function removeRow(state, id) {
|
|
170
|
+
return {
|
|
171
|
+
...state,
|
|
172
|
+
rows: detach(state.rows, id).filter(row => row.id !== id),
|
|
173
|
+
};
|
|
174
|
+
}
|
|
175
|
+
export function withField(row, field) {
|
|
176
|
+
const sameType = row.field?.type === field.type;
|
|
177
|
+
const ops = OPERATORS[field.type ?? 'any'];
|
|
178
|
+
return {
|
|
179
|
+
...row,
|
|
180
|
+
field,
|
|
181
|
+
op: sameType ? row.op : ops[0].op,
|
|
182
|
+
value: sameType ? row.value : '',
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
export function withOp(row, op) {
|
|
186
|
+
const { value } = row;
|
|
187
|
+
return {
|
|
188
|
+
...row,
|
|
189
|
+
op,
|
|
190
|
+
value: op === 'in'
|
|
191
|
+
? Array.isArray(value)
|
|
192
|
+
? value
|
|
193
|
+
: value
|
|
194
|
+
? [value]
|
|
195
|
+
: []
|
|
196
|
+
: Array.isArray(value)
|
|
197
|
+
? (value[0] ?? '')
|
|
198
|
+
: value,
|
|
199
|
+
};
|
|
200
|
+
}
|
|
201
|
+
function writeCondition({ field, op, value }) {
|
|
202
|
+
if (!field) {
|
|
203
|
+
return undefined;
|
|
204
|
+
}
|
|
205
|
+
const { subject, type } = field;
|
|
206
|
+
const usable = (v) => v.trim() !== '' && (type !== 'number' || Number.isFinite(Number(v)));
|
|
207
|
+
if (op === 'set' || op === '!set') {
|
|
208
|
+
return printCondition({ subject, op });
|
|
209
|
+
}
|
|
210
|
+
if (op === 'in') {
|
|
211
|
+
const list = [value].flat().filter(usable);
|
|
212
|
+
return list.length > 0
|
|
213
|
+
? printCondition({
|
|
214
|
+
subject,
|
|
215
|
+
op,
|
|
216
|
+
value: list.map(v => scalar(type, v)),
|
|
217
|
+
})
|
|
218
|
+
: undefined;
|
|
219
|
+
}
|
|
220
|
+
const text = [value].flat()[0] ?? '';
|
|
221
|
+
return !usable(text)
|
|
222
|
+
? undefined
|
|
223
|
+
: op === '~'
|
|
224
|
+
? printCondition({ subject, op, value: text })
|
|
225
|
+
: printCondition({ subject, op, value: scalar(type, text) });
|
|
226
|
+
}
|
|
227
|
+
function writeRow(row) {
|
|
228
|
+
const text = row.kind === 'text' ? row.text.trim() || undefined : writeCondition(row);
|
|
229
|
+
return text === undefined ? undefined : ensureJexlPrefix(text);
|
|
230
|
+
}
|
|
231
|
+
/**
|
|
232
|
+
* The stored filters: an untouched line as it was, and every row of an edited
|
|
233
|
+
* line as a line of its own, which is equivalent because lines AND together.
|
|
234
|
+
* Rows left incomplete are dropped.
|
|
235
|
+
*/
|
|
236
|
+
export function writeFilterRows({ lines, rows }) {
|
|
237
|
+
const out = [];
|
|
238
|
+
let previous;
|
|
239
|
+
for (const row of rows) {
|
|
240
|
+
if (row.line === undefined) {
|
|
241
|
+
const text = writeRow(row);
|
|
242
|
+
if (text !== undefined) {
|
|
243
|
+
out.push(text);
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
else if (row.line !== previous) {
|
|
247
|
+
out.push(lines[row.line]);
|
|
248
|
+
}
|
|
249
|
+
previous = row.line;
|
|
250
|
+
}
|
|
251
|
+
return out;
|
|
252
|
+
}
|
|
@@ -4,11 +4,13 @@ import type { Reversible } from '../ui/filterMenuItems.ts';
|
|
|
4
4
|
* The two-tier feature-filter contract, shared by every display offering a
|
|
5
5
|
* "Filter by..." row. Two tiers because the setting has two authors:
|
|
6
6
|
*
|
|
7
|
-
* - the **`jexlFilters` config slot
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
* `
|
|
7
|
+
* - the **`jexlFilters` config slot**, which an admin declares in a track
|
|
8
|
+
* config. It stores expressions **unprefixed**, because config-slot values
|
|
9
|
+
* are deferred-evaluation and a stored `jexl:` is what marks a slot as a
|
|
10
|
+
* callback — so the prefix goes on at read time, in `configuredJexlFilters`.
|
|
11
|
+
* The slot is `jexlFilterConfigSchemaFields` in display-kit, spread by the
|
|
12
|
+
* canvas base display schema, the mark display schema and the shared
|
|
13
|
+
* multi-sample variant schema — the three whose models read it.
|
|
12
14
|
* - the **`jexlFiltersSetting` display property**, which the dialog writes and
|
|
13
15
|
* which stores them already prefixed (the runtime convention). Set — *even to
|
|
14
16
|
* an empty list* — it replaces the config tier entirely, which is what makes
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export interface JexlExpression {
|
|
2
2
|
eval(context?: Record<string, unknown>): unknown;
|
|
3
|
-
|
|
3
|
+
readonly source?: string;
|
|
4
4
|
}
|
|
5
5
|
export interface JexlInstance {
|
|
6
6
|
compile(code: string): JexlExpression;
|
|
@@ -11,9 +11,8 @@ export declare function isJexl(str: unknown): str is string;
|
|
|
11
11
|
/** Add the `jexl:` prefix unless the string already carries it. */
|
|
12
12
|
export declare function ensureJexlPrefix(code: string): string;
|
|
13
13
|
/**
|
|
14
|
-
* Compile a `jexl:...` string to an Expression.
|
|
15
|
-
*
|
|
16
|
-
* wrapper.
|
|
14
|
+
* Compile a `jexl:...` string to an Expression. The jexl instance caches
|
|
15
|
+
* compilation, so this only strips the prefix.
|
|
17
16
|
*
|
|
18
17
|
* @param str - string of code like `jexl:...`
|
|
19
18
|
* @param jexl - the instance whose registered functions the expression may call
|
package/esm/util/jexlStrings.js
CHANGED
|
@@ -8,9 +8,8 @@ export function ensureJexlPrefix(code) {
|
|
|
8
8
|
return isJexl(code) ? code : `${JEXL_PREFIX}${code}`;
|
|
9
9
|
}
|
|
10
10
|
/**
|
|
11
|
-
* Compile a `jexl:...` string to an Expression.
|
|
12
|
-
*
|
|
13
|
-
* wrapper.
|
|
11
|
+
* Compile a `jexl:...` string to an Expression. The jexl instance caches
|
|
12
|
+
* compilation, so this only strips the prefix.
|
|
14
13
|
*
|
|
15
14
|
* @param str - string of code like `jexl:...`
|
|
16
15
|
* @param jexl - the instance whose registered functions the expression may call
|
|
@@ -1,31 +1,26 @@
|
|
|
1
|
+
import type { ColorScale } from '../ui/colorScale.ts';
|
|
2
|
+
import type { CategoricalField } from './categoricalField.ts';
|
|
1
3
|
export interface LegendCandidate {
|
|
2
4
|
rowIndex: number;
|
|
3
|
-
|
|
5
|
+
value: string;
|
|
4
6
|
color: number;
|
|
5
7
|
}
|
|
6
8
|
export interface LegendEntry {
|
|
7
|
-
|
|
9
|
+
values: string[];
|
|
8
10
|
color: number;
|
|
9
11
|
}
|
|
10
12
|
export declare const MAX_LEGEND_ENTRIES = 30;
|
|
11
13
|
export declare const MAX_LEGEND_CANDIDATES = 1024;
|
|
12
14
|
/**
|
|
13
|
-
* Accumulator for the distinct (row,
|
|
14
|
-
* past, in first-seen order and bounded
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
* Deduped on the whole triple rather than on (row, color): the union takes the
|
|
19
|
-
* first NAME it sees for a color, so where that name is already spoken for, the
|
|
20
|
-
* second name on that color has to still be in the list to carry it.
|
|
21
|
-
*
|
|
22
|
-
* A nameless feature contributes nothing, which is the union's rule too — so a
|
|
23
|
-
* track whose features have no names ships an empty list rather than one entry
|
|
24
|
-
* per feature.
|
|
15
|
+
* Accumulator for the distinct (row, value, color) combinations a packer walks
|
|
16
|
+
* past, in first-seen order and bounded, so the main thread never re-walks the
|
|
17
|
+
* features. Deduped on the whole triple: a row of the union lists every value
|
|
18
|
+
* painted in its color, so a second value on that color has to still be in the
|
|
19
|
+
* list to reach it.
|
|
25
20
|
*/
|
|
26
21
|
export declare function createLegendCandidateCollector(maxCandidates?: number): {
|
|
27
22
|
candidates: LegendCandidate[];
|
|
28
|
-
add(rowIndex: number,
|
|
23
|
+
add(rowIndex: number, value: string, color: number): void;
|
|
29
24
|
};
|
|
30
25
|
export interface LegendCandidateSource {
|
|
31
26
|
candidates: readonly LegendCandidate[];
|
|
@@ -33,18 +28,27 @@ export interface LegendCandidateSource {
|
|
|
33
28
|
}
|
|
34
29
|
/**
|
|
35
30
|
* The categorical color key over any number of packed regions: one entry per
|
|
36
|
-
* distinct color
|
|
37
|
-
* order.
|
|
38
|
-
*
|
|
39
|
-
*
|
|
40
|
-
* row is normally a toggle and hiding a category hides features BY color, so two
|
|
41
|
-
* names sharing one color must collapse to a single row. A name reused across
|
|
42
|
-
* two colors keeps its first-seen color.
|
|
31
|
+
* distinct color listing every value painted in it, colors in first-seen
|
|
32
|
+
* order. Keyed by color rather than by value because hiding a category hides
|
|
33
|
+
* features BY color, so two values sharing one color are one row that names
|
|
34
|
+
* both; a value met in two colors stays with the first.
|
|
43
35
|
*
|
|
44
|
-
* `[]` when
|
|
45
|
-
* `
|
|
46
|
-
*
|
|
47
|
-
* `regions` is consumed lazily, so a caller able to answer without reading any
|
|
48
|
-
* of them can pass a generator and have none of them touched.
|
|
36
|
+
* `[]` when there are more than `maxEntries` distinct colors, where the data is
|
|
37
|
+
* not a categorical vocabulary. `regions` is consumed lazily.
|
|
49
38
|
*/
|
|
50
39
|
export declare function unionLegendCandidates<T>(regions: Iterable<T>, resolve: (region: T) => LegendCandidateSource, maxEntries?: number): LegendEntry[];
|
|
40
|
+
/**
|
|
41
|
+
* The one categorical key a color channel derives from what a worker painted:
|
|
42
|
+
* the union above over the loaded regions, each row a painted color naming
|
|
43
|
+
* every value in it through `field` and ordered by it, and nothing where the
|
|
44
|
+
* rows would say nothing (`legendIsReadable`). A display resolving its own colors hands the
|
|
45
|
+
* candidates its packer recorded; one resolved by `encodeFeatures` hands the
|
|
46
|
+
* entries of the scale tables that came back. Either way the key lists what
|
|
47
|
+
* the painting holds, and a `closed` field's domain besides once anything
|
|
48
|
+
* painted.
|
|
49
|
+
*/
|
|
50
|
+
export declare function derivedColorScale<T>(regions: Iterable<T>, resolve: (region: T) => LegendCandidateSource, { id, field, maxItems, }: {
|
|
51
|
+
id: string;
|
|
52
|
+
field: CategoricalField;
|
|
53
|
+
maxItems?: number;
|
|
54
|
+
}): ColorScale[];
|