@jbrowse/core 5.0.0-beta.1 → 5.0.0-beta.11
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 +1709 -390
- package/esm/BaseFeatureWidget/BaseFeatureDetail/ArrayValue.d.ts +3 -2
- package/esm/BaseFeatureWidget/BaseFeatureDetail/ArrayValue.js +5 -5
- package/esm/BaseFeatureWidget/BaseFeatureDetail/Attributes.d.ts +3 -5
- package/esm/BaseFeatureWidget/BaseFeatureDetail/Attributes.js +34 -29
- package/esm/BaseFeatureWidget/BaseFeatureDetail/BaseCard.js +1 -4
- package/esm/BaseFeatureWidget/BaseFeatureDetail/BasicValue.d.ts +11 -0
- package/esm/BaseFeatureWidget/BaseFeatureDetail/BasicValue.js +37 -14
- package/esm/BaseFeatureWidget/BaseFeatureDetail/CoreDetails.d.ts +1 -1
- package/esm/BaseFeatureWidget/BaseFeatureDetail/CoreDetails.js +15 -31
- package/esm/BaseFeatureWidget/BaseFeatureDetail/FeatureDetails.d.ts +4 -3
- package/esm/BaseFeatureWidget/BaseFeatureDetail/FeatureDetails.js +12 -25
- package/esm/BaseFeatureWidget/BaseFeatureDetail/FeatureDetailsFrame.d.ts +11 -0
- package/esm/BaseFeatureWidget/BaseFeatureDetail/FeatureDetailsFrame.js +11 -0
- package/esm/BaseFeatureWidget/BaseFeatureDetail/FieldActionsButton.d.ts +8 -0
- package/esm/BaseFeatureWidget/BaseFeatureDetail/FieldActionsButton.js +24 -0
- package/esm/BaseFeatureWidget/BaseFeatureDetail/Formatter.js +6 -4
- package/esm/BaseFeatureWidget/BaseFeatureDetail/ParentFeatureLine.d.ts +4 -0
- package/esm/BaseFeatureWidget/BaseFeatureDetail/ParentFeatureLine.js +17 -0
- package/esm/BaseFeatureWidget/BaseFeatureDetail/SimpleField.d.ts +3 -2
- package/esm/BaseFeatureWidget/BaseFeatureDetail/SimpleField.js +5 -3
- package/esm/BaseFeatureWidget/BaseFeatureDetail/index.d.ts +6 -2
- package/esm/BaseFeatureWidget/BaseFeatureDetail/index.js +7 -18
- package/esm/BaseFeatureWidget/BaseFeatureDetail/jexlFilterActions.d.ts +16 -0
- package/esm/BaseFeatureWidget/BaseFeatureDetail/jexlFilterActions.js +49 -0
- package/esm/BaseFeatureWidget/BaseFeatureDetail/util.d.ts +0 -8
- package/esm/BaseFeatureWidget/BaseFeatureDetail/util.js +6 -29
- package/esm/BaseFeatureWidget/SequenceFeatureDetails/SequenceContents.js +7 -34
- package/esm/BaseFeatureWidget/SequenceFeatureDetails/SequenceFeaturePanel.d.ts +2 -2
- package/esm/BaseFeatureWidget/SequenceFeatureDetails/SequenceName.js +2 -2
- package/esm/BaseFeatureWidget/SequenceFeatureDetails/dialogs/TranscriptSelector.js +3 -1
- package/esm/BaseFeatureWidget/SequenceFeatureDetails/model.d.ts +12 -0
- package/esm/BaseFeatureWidget/SequenceFeatureDetails/model.js +12 -5
- package/esm/BaseFeatureWidget/SequenceFeatureDetails/useSequenceData.js +8 -5
- package/esm/BaseFeatureWidget/configSchema.d.ts +1 -1
- package/esm/BaseFeatureWidget/formatDetails.d.ts +13 -29
- package/esm/BaseFeatureWidget/formatDetails.js +62 -83
- package/esm/BaseFeatureWidget/index.d.ts +2 -1
- package/esm/BaseFeatureWidget/stateModelFactory.d.ts +42 -29
- package/esm/BaseFeatureWidget/stateModelFactory.js +98 -98
- package/esm/BaseFeatureWidget/types.d.ts +12 -6
- package/esm/BaseFeatureWidget/util.d.ts +0 -10
- package/esm/BaseFeatureWidget/util.js +0 -17
- package/esm/CorePlugin.js +34 -3
- package/esm/PluginLoader.d.ts +24 -13
- package/esm/PluginLoader.js +167 -51
- package/esm/PluginManager.d.ts +130 -24
- package/esm/PluginManager.js +180 -32
- package/esm/ReExports/MuiDataGridReExports.d.ts +1 -0
- package/esm/ReExports/MuiDataGridReExports.js +2 -2
- package/esm/ReExports/coreModules.generated.d.ts +2 -0
- package/esm/ReExports/coreModules.generated.js +530 -0
- package/esm/ReExports/coreWorkerModules.generated.d.ts +2 -0
- package/esm/ReExports/coreWorkerModules.generated.js +490 -0
- package/esm/ReExports/frameworkModules.d.ts +2 -0
- package/esm/ReExports/frameworkModules.js +68 -0
- package/esm/ReExports/frameworkShared.d.ts +12 -0
- package/esm/ReExports/frameworkShared.js +16 -0
- package/esm/ReExports/frameworkWorkerModules.generated.d.ts +2 -0
- package/esm/ReExports/frameworkWorkerModules.generated.js +130 -0
- package/esm/ReExports/list.js +528 -79
- package/esm/ReExports/modules.d.ts +1 -1
- package/esm/ReExports/modules.js +10 -165
- package/esm/ReExports/registry.d.ts +1 -0
- package/esm/ReExports/registry.js +23 -5
- package/esm/ReExports/uiStub.d.ts +3 -0
- package/esm/ReExports/uiStub.js +33 -0
- package/esm/ReExports/workerModules.d.ts +2 -0
- package/esm/ReExports/workerModules.js +11 -0
- package/esm/TextSearch/TextSearchManager.d.ts +27 -13
- package/esm/TextSearch/TextSearchManager.js +77 -36
- package/esm/TextSearch/places.d.ts +12 -0
- package/esm/TextSearch/places.js +94 -0
- package/esm/assemblyManager/assembly.d.ts +21 -19
- package/esm/assemblyManager/assembly.js +28 -26
- package/esm/assemblyManager/assemblyAdapters.d.ts +1 -1
- package/esm/assemblyManager/assemblyAdapters.js +8 -2
- package/esm/assemblyManager/assemblyConfigSchema.d.ts +31 -90
- package/esm/assemblyManager/assemblyConfigSchema.js +35 -47
- package/esm/assemblyManager/assemblyManager.d.ts +35 -180
- package/esm/assemblyManager/assemblyManager.js +47 -51
- package/esm/assemblyManager/expandAssemblyConfigShorthand.d.ts +25 -18
- package/esm/assemblyManager/expandAssemblyConfigShorthand.js +78 -49
- package/esm/assemblyManager/geneticCodes.js +2 -5
- package/esm/assemblyManager/getSequenceAdapterConfig.d.ts +10 -0
- package/esm/assemblyManager/getSequenceAdapterConfig.js +10 -0
- package/esm/assemblyManager/indexAssemblyNames.d.ts +9 -0
- package/esm/assemblyManager/indexAssemblyNames.js +22 -0
- package/esm/assemblyManager/loadRefNameMap.d.ts +1 -1
- package/esm/assemblyManager/loadRefNameMap.js +4 -9
- package/esm/assemblyManager/refNameMapKey.d.ts +7 -0
- package/esm/assemblyManager/refNameMapKey.js +12 -0
- package/esm/checkPlugins.d.ts +2 -0
- package/esm/checkPlugins.js +38 -17
- package/esm/configuration/bamIndexFields.d.ts +49 -0
- package/esm/configuration/bamIndexFields.js +41 -0
- package/esm/configuration/configurationSchema.d.ts +101 -71
- package/esm/configuration/configurationSchema.js +207 -134
- package/esm/configuration/configurationSchemaUnion.d.ts +39 -0
- package/esm/configuration/configurationSchemaUnion.js +56 -0
- package/esm/configuration/configurationSlot.d.ts +150 -60
- package/esm/configuration/configurationSlot.js +103 -75
- package/esm/configuration/fillLocations.d.ts +14 -0
- package/esm/configuration/fillLocations.js +14 -0
- package/esm/configuration/formatAboutConfigSchema.d.ts +7 -21
- package/esm/configuration/formatDetailsConfigSchema.d.ts +11 -37
- package/esm/configuration/formatDetailsConfigSchema.js +10 -13
- package/esm/configuration/fullConfSnapshot.d.ts +4 -19
- package/esm/configuration/fullConfSnapshot.js +30 -52
- package/esm/configuration/getConf.d.ts +45 -41
- package/esm/configuration/getConf.js +111 -44
- package/esm/configuration/index.d.ts +26 -11
- package/esm/configuration/index.js +16 -7
- package/esm/configuration/indexType.d.ts +26 -0
- package/esm/configuration/indexType.js +38 -0
- package/esm/configuration/mergeFormatCallbacks.d.ts +6 -7
- package/esm/configuration/mergeFormatCallbacks.js +13 -10
- package/esm/configuration/plot.d.ts +61 -0
- package/esm/configuration/plot.js +142 -0
- package/esm/configuration/readConfObject.d.ts +2 -24
- package/esm/configuration/readConfObject.js +20 -63
- package/esm/configuration/requirements.d.ts +37 -0
- package/esm/configuration/requirements.js +88 -0
- package/esm/configuration/schemaRegistry.d.ts +32 -15
- package/esm/configuration/schemaRegistry.js +33 -35
- package/esm/configuration/schemaTypes.d.ts +21 -5
- package/esm/configuration/schemaTypes.js +66 -55
- package/esm/configuration/slotFacade.d.ts +12 -29
- package/esm/configuration/slotFacade.js +44 -23
- package/esm/configuration/snapshotPreprocess.d.ts +43 -0
- package/esm/configuration/snapshotPreprocess.js +161 -0
- package/esm/configuration/tabixIndexFields.d.ts +30 -4
- package/esm/configuration/tabixIndexFields.js +21 -4
- package/esm/configuration/tabixShorthand.d.ts +34 -17
- package/esm/configuration/tabixShorthand.js +49 -22
- package/esm/configuration/types.d.ts +182 -43
- package/esm/configuration/uriShorthand.d.ts +9 -0
- package/esm/configuration/uriShorthand.js +16 -0
- package/esm/data_adapters/BaseAdapter/BaseAdapter.d.ts +13 -19
- package/esm/data_adapters/BaseAdapter/BaseAdapter.js +12 -19
- package/esm/data_adapters/BaseAdapter/BaseFeatureDataAdapter.d.ts +40 -2
- package/esm/data_adapters/BaseAdapter/BaseFeatureDataAdapter.js +68 -5
- package/esm/data_adapters/BaseAdapter/featureDensity.d.ts +40 -0
- package/esm/data_adapters/BaseAdapter/featureDensity.js +31 -0
- package/esm/data_adapters/BaseAdapter/index.d.ts +23 -3
- package/esm/data_adapters/BaseAdapter/index.js +1 -0
- package/esm/data_adapters/BaseAdapter/rowSources.d.ts +37 -0
- package/esm/data_adapters/BaseAdapter/rowSources.js +7 -0
- package/esm/data_adapters/BaseAdapter/stats.d.ts +33 -1
- package/esm/data_adapters/BaseAdapter/stats.js +52 -13
- package/esm/data_adapters/BaseAdapter/types.d.ts +8 -12
- package/esm/data_adapters/BaseAdapter/zoomRange.d.ts +10 -0
- package/esm/data_adapters/CytobandAdapter/CytobandAdapter.js +1 -1
- package/esm/data_adapters/CytobandAdapter/configSchema.d.ts +7 -11
- package/esm/data_adapters/CytobandAdapter/configSchema.js +3 -17
- package/esm/data_adapters/dataAdapterCache.d.ts +19 -2
- package/esm/data_adapters/dataAdapterCache.js +44 -10
- package/esm/data_adapters/getFeatureAdapter.d.ts +6 -4
- package/esm/data_adapters/getFeatureAdapter.js +8 -8
- package/esm/data_adapters/getSequenceSubAdapter.d.ts +7 -9
- package/esm/data_adapters/getSequenceSubAdapter.js +8 -10
- package/esm/pluggableElementTypes/AdapterType.d.ts +8 -8
- package/esm/pluggableElementTypes/AdapterType.js +1 -1
- package/esm/pluggableElementTypes/DisplayType.d.ts +53 -16
- package/esm/pluggableElementTypes/DisplayType.js +28 -12
- package/esm/pluggableElementTypes/LazyStateModelElement.d.ts +32 -0
- package/esm/pluggableElementTypes/LazyStateModelElement.js +77 -0
- package/esm/pluggableElementTypes/PluggableElementBase.d.ts +3 -5
- package/esm/pluggableElementTypes/PluggableElementBase.js +3 -5
- package/esm/pluggableElementTypes/RpcMethodType.d.ts +11 -1
- package/esm/pluggableElementTypes/RpcMethodType.js +25 -9
- package/esm/pluggableElementTypes/RpcMethodTypeWithFiltersAndRenameRegions.d.ts +1 -2
- package/esm/pluggableElementTypes/TextSearchAdapterType.d.ts +7 -7
- package/esm/pluggableElementTypes/ViewType.d.ts +20 -4
- package/esm/pluggableElementTypes/ViewType.js +32 -4
- package/esm/pluggableElementTypes/WidgetType.d.ts +6 -0
- package/esm/pluggableElementTypes/WidgetType.js +6 -0
- package/esm/pluggableElementTypes/addMenuItems.d.ts +3 -2
- package/esm/pluggableElementTypes/extendElementType.d.ts +1 -2
- package/esm/pluggableElementTypes/extendElementType.js +9 -5
- package/esm/pluggableElementTypes/index.d.ts +2 -1
- package/esm/pluggableElementTypes/index.js +2 -9
- package/esm/pluggableElementTypes/models/BaseConnectionModelFactory.d.ts +19 -9
- package/esm/pluggableElementTypes/models/BaseDisplayModel.d.ts +122 -28
- package/esm/pluggableElementTypes/models/BaseDisplayModel.js +155 -11
- package/esm/pluggableElementTypes/models/BaseTrackModel.d.ts +65 -16
- package/esm/pluggableElementTypes/models/BaseTrackModel.js +179 -117
- package/esm/pluggableElementTypes/models/BaseViewModel.d.ts +87 -18
- package/esm/pluggableElementTypes/models/BaseViewModel.js +54 -11
- package/esm/pluggableElementTypes/models/InternetAccountModel.d.ts +26 -16
- package/esm/pluggableElementTypes/models/assertDisplayContract.d.ts +15 -11
- package/esm/pluggableElementTypes/models/assertDisplayContract.js +25 -32
- package/esm/pluggableElementTypes/models/baseConnectionConfig.d.ts +22 -18
- package/esm/pluggableElementTypes/models/baseConnectionConfig.js +5 -5
- package/esm/pluggableElementTypes/models/baseInternetAccountConfig.d.ts +26 -31
- package/esm/pluggableElementTypes/models/baseTrackConfig.d.ts +108 -147
- package/esm/pluggableElementTypes/models/baseTrackConfig.js +96 -73
- package/esm/pluggableElementTypes/models/components/SaveTrackData.js +4 -6
- package/esm/pluggableElementTypes/models/components/fetchTrackData.d.ts +3 -4
- package/esm/pluggableElementTypes/models/components/fetchTrackData.js +3 -3
- package/esm/pluggableElementTypes/models/expandTrackConfigShorthand.d.ts +23 -13
- package/esm/pluggableElementTypes/models/expandTrackConfigShorthand.js +80 -48
- package/esm/pluggableElementTypes/models/index.d.ts +2 -3
- package/esm/pluggableElementTypes/models/index.js +2 -3
- package/esm/pluggableElementTypes/models/migrateTrackConfig.d.ts +15 -1
- package/esm/pluggableElementTypes/models/migrateTrackConfig.js +85 -25
- package/esm/pluggableElementTypes/models/saveTrackFileTypes/genbank.d.ts +4 -3
- package/esm/pluggableElementTypes/models/saveTrackFileTypes/genbank.js +141 -19
- package/esm/pluggableElementTypes/models/saveTrackFileTypes/types.d.ts +3 -3
- package/esm/pluginDefinitions.d.ts +34 -7
- package/esm/pluginDefinitions.js +54 -20
- package/esm/rpc/BaseRpcDriver.d.ts +2 -2
- package/esm/rpc/BaseRpcDriver.js +25 -30
- package/esm/rpc/MainThreadRpcDriver.d.ts +2 -2
- package/esm/rpc/MainThreadRpcDriver.js +13 -8
- package/esm/rpc/RpcClient.d.ts +18 -6
- package/esm/rpc/RpcClient.js +51 -16
- package/esm/rpc/RpcManager.d.ts +14 -10
- package/esm/rpc/RpcManager.js +11 -1
- package/esm/rpc/RpcRegistry.d.ts +40 -7
- package/esm/rpc/RpcServer.d.ts +3 -1
- package/esm/rpc/RpcServer.js +19 -12
- package/esm/rpc/WebWorkerRpcDriver.d.ts +11 -4
- package/esm/rpc/WebWorkerRpcDriver.js +64 -68
- package/esm/rpc/byteBudget.d.ts +20 -5
- package/esm/rpc/byteBudget.js +16 -5
- package/esm/rpc/configSchema.d.ts +7 -21
- package/esm/rpc/coreRpcMethods.d.ts +4 -0
- package/esm/rpc/coreRpcMethods.js +4 -0
- package/esm/rpc/methods/CoreGetEncodedFeature.d.ts +13 -0
- package/esm/rpc/methods/CoreGetEncodedFeature.js +32 -0
- package/esm/rpc/methods/CoreGetEncodedLayers.d.ts +16 -0
- package/esm/rpc/methods/CoreGetEncodedLayers.js +59 -0
- package/esm/rpc/methods/CoreGetExportData.js +3 -4
- package/esm/rpc/methods/CoreGetFeatureDensity.d.ts +11 -0
- package/esm/rpc/methods/CoreGetFeatureDensity.js +22 -0
- package/esm/rpc/methods/CoreGetFeatures.js +3 -5
- package/esm/rpc/methods/CoreGetRefNames.js +2 -12
- package/esm/rpc/methods/CoreGetRegionByteEstimate.js +1 -1
- package/esm/rpc/methods/CoreGetSequence.js +2 -2
- package/esm/rpc/methods/CoreLoadAdapterCode.d.ts +13 -0
- package/esm/rpc/methods/CoreLoadAdapterCode.js +16 -0
- package/esm/rpc/methods/layerFeatures.d.ts +33 -0
- package/esm/rpc/methods/layerFeatures.js +29 -0
- package/esm/svg/SvgExport.js +6 -7
- package/esm/svg/SvgThemeProviders.d.ts +12 -0
- package/esm/svg/SvgThemeProviders.js +15 -0
- package/esm/svg/exportViewSvg.d.ts +28 -0
- package/esm/svg/exportViewSvg.js +13 -0
- package/esm/svg/normalizeSvgMarkup.d.ts +7 -0
- package/esm/svg/normalizeSvgMarkup.js +99 -0
- package/esm/svg/serializeSvg.d.ts +7 -0
- package/esm/svg/serializeSvg.js +11 -0
- package/esm/svg/svgId.d.ts +1 -1
- package/esm/svg/svgId.js +1 -1
- package/esm/svg/svgReady.d.ts +9 -7
- package/esm/svg/svgReady.js +8 -7
- package/esm/svg/trackNames.d.ts +7 -5
- package/esm/svg/trackNames.js +12 -9
- package/esm/svg/wrapSvgExport.js +6 -74
- package/esm/ui/AddCustomPluginDialog.js +3 -8
- package/esm/ui/AppReadyMarker.d.ts +45 -0
- package/esm/ui/AppReadyMarker.js +89 -0
- package/esm/ui/BaseExportSvgDialog.d.ts +1 -1
- package/esm/ui/CascadingMenu.js +181 -104
- package/esm/ui/DropDownMenu.js +2 -1
- package/esm/ui/ErrorBanner.js +1 -1
- package/esm/ui/ErrorBoundary.d.ts +2 -2
- package/esm/ui/ErrorMessageStackTraceContents.js +2 -1
- package/esm/ui/ErrorMessageStackTraceDialog.js +5 -11
- package/esm/ui/ExportSvgDialog.d.ts +1 -1
- package/esm/ui/FileDropZone.js +2 -1
- package/esm/ui/FileSelector/useInternetAccounts.d.ts +156 -96
- package/esm/ui/HoverMenu.d.ts +1 -2
- package/esm/ui/HoverMenu.js +6 -3
- package/esm/ui/JexlFilterDialog.d.ts +13 -10
- package/esm/ui/JexlFilterDialog.js +122 -50
- package/esm/ui/JexlFilterRowEditors.d.ts +15 -0
- package/esm/ui/JexlFilterRowEditors.js +90 -0
- package/esm/ui/LazyBaseTooltip.d.ts +4 -0
- package/esm/ui/LazyBaseTooltip.js +9 -0
- package/esm/ui/LegendSwatchGlyph.js +26 -21
- package/esm/ui/LoadingOverlay.d.ts +14 -0
- package/esm/ui/LoadingOverlay.js +4 -2
- package/esm/ui/MenuTypes.d.ts +23 -53
- package/esm/ui/MenuTypes.js +3 -0
- package/esm/ui/MonospaceTextField.d.ts +2 -1
- package/esm/ui/MonospaceTextField.js +23 -20
- package/esm/ui/PaletteContext.d.ts +10 -5
- package/esm/ui/PaletteContext.js +44 -6
- package/esm/ui/RefNameAutocomplete/SearchOption.d.ts +13 -0
- package/esm/ui/RefNameAutocomplete/SearchOption.js +45 -0
- package/esm/ui/RefNameAutocomplete/index.d.ts +1 -2
- package/esm/ui/RefNameAutocomplete/index.js +8 -2
- package/esm/ui/RefNameAutocomplete/util.d.ts +13 -0
- package/esm/ui/RefNameAutocomplete/util.js +42 -1
- package/esm/ui/ResizeHandle.d.ts +3 -1
- package/esm/ui/ResizeHandle.js +44 -11
- package/esm/ui/ScrollChrome.d.ts +13 -0
- package/esm/ui/ScrollChrome.js +11 -0
- package/esm/ui/ScrollEdgeShadow.d.ts +6 -9
- package/esm/ui/ScrollEdgeShadow.js +14 -35
- package/esm/ui/ScrollZoomToggle.d.ts +4 -27
- package/esm/ui/ScrollZoomToggle.js +34 -51
- package/esm/ui/SessionJsonPanel.d.ts +3 -0
- package/esm/ui/SessionJsonPanel.js +14 -0
- package/esm/ui/SettingsChangesTable.d.ts +1 -0
- package/esm/ui/SettingsChangesTable.js +49 -11
- package/esm/ui/ShareLinkField.d.ts +1 -3
- package/esm/ui/ShareLinkField.js +13 -40
- package/esm/ui/SizeSliderRow.d.ts +1 -3
- package/esm/ui/SizeSliderRow.js +4 -6
- package/esm/ui/SnackbarModel.js +79 -67
- package/esm/ui/StatusProgressBar.js +2 -2
- package/esm/ui/SvgColorLegend.d.ts +9 -4
- package/esm/ui/SvgColorLegend.js +82 -41
- package/esm/ui/VerticalScrollbar.d.ts +13 -34
- package/esm/ui/VerticalScrollbar.js +29 -83
- package/esm/ui/ViewLoadingScreen.d.ts +5 -4
- package/esm/ui/ViewLoadingScreen.js +8 -32
- package/esm/ui/colorScale.d.ts +92 -0
- package/esm/ui/colorScale.js +72 -0
- package/esm/ui/colors.d.ts +64 -0
- package/esm/ui/colors.js +230 -1
- package/esm/ui/hoverBoxStyle.d.ts +14 -2
- package/esm/ui/hoverBoxStyle.js +17 -2
- package/esm/ui/index.d.ts +12 -12
- package/esm/ui/index.js +14 -22
- package/esm/ui/launchViewMenu.js +15 -5
- package/esm/ui/legendMenuItem.d.ts +10 -32
- package/esm/ui/legendMenuItem.js +9 -36
- package/esm/ui/legendSpec.d.ts +15 -8
- package/esm/ui/legendSpec.js +14 -23
- package/esm/ui/makeSizeMenu.d.ts +0 -6
- package/esm/ui/makeSizeMenu.js +6 -30
- package/esm/ui/measureLegendText.js +1 -1
- package/esm/ui/menuItemAdornment.d.ts +9 -20
- package/esm/ui/menuItemAdornment.js +10 -32
- package/esm/ui/menuItems.d.ts +2 -7
- package/esm/ui/menuItems.js +1 -6
- package/esm/ui/multiTrackMenuItems.d.ts +6 -0
- package/esm/ui/palette.d.ts +118 -116
- package/esm/ui/palette.js +114 -75
- package/esm/ui/replaceViewAction.d.ts +1 -1
- package/esm/ui/replaceViewAction.js +1 -1
- package/esm/ui/theme.d.ts +43 -119
- package/esm/ui/theme.js +62 -78
- package/esm/ui/toggleMenuItems.d.ts +1 -3
- package/esm/ui/toggleMenuItems.js +6 -5
- package/esm/ui/useAssemblySelection.d.ts +4 -4
- package/esm/ui/viewHeaderHeight.d.ts +1 -0
- package/esm/ui/viewHeaderHeight.js +1 -0
- package/esm/util/Base1DUtils.d.ts +5 -3
- package/esm/util/Base1DUtils.js +14 -6
- package/esm/util/Base1DViewModel.d.ts +2 -1
- package/esm/util/Base1DViewModel.js +3 -2
- package/esm/util/SvgCanvas.d.ts +15 -13
- package/esm/util/SvgCanvas.js +76 -56
- package/esm/util/TimeTraveller.d.ts +3 -0
- package/esm/util/TimeTraveller.js +34 -2
- package/esm/util/aborting.d.ts +39 -0
- package/esm/util/aborting.js +88 -6
- package/esm/util/adapterMetadata.d.ts +1 -1
- package/esm/util/adapterMetadata.js +6 -5
- package/esm/util/addAndShowTrack.d.ts +2 -5
- package/esm/util/addAndShowTrack.js +5 -1
- package/esm/util/addRelativeUris.d.ts +17 -5
- package/esm/util/addRelativeUris.js +46 -10
- package/esm/util/addTrackFromWidget.d.ts +2 -5
- package/esm/util/addTrackFromWidget.js +5 -4
- package/esm/util/aggregateFieldName.d.ts +10 -0
- package/esm/util/aggregateFieldName.js +8 -0
- package/esm/util/analytics.js +46 -13
- package/esm/util/animationAllowed.d.ts +9 -0
- package/esm/util/animationAllowed.js +13 -0
- package/esm/util/applyRowResizeWheel.d.ts +10 -5
- package/esm/util/applyRowResizeWheel.js +10 -21
- package/esm/util/bandHeight.d.ts +10 -0
- package/esm/util/bandHeight.js +29 -0
- package/esm/util/bandLayout.d.ts +4 -4
- package/esm/util/bandLayout.js +4 -4
- package/esm/util/baseDisplayConfig.d.ts +8 -0
- package/esm/util/baseDisplayConfig.js +27 -0
- package/esm/util/bezierConnector.d.ts +4 -3
- package/esm/util/bezierConnector.js +38 -45
- package/esm/util/bgzfWorkerPool.d.ts +20 -74
- package/esm/util/bgzfWorkerPool.js +20 -74
- package/esm/util/binnedAggregate.d.ts +17 -0
- package/esm/util/binnedAggregate.js +275 -0
- package/esm/util/cacheBudgets.d.ts +22 -19
- package/esm/util/cacheBudgets.js +22 -19
- package/esm/util/cachedSetup.d.ts +16 -6
- package/esm/util/cachedSetup.js +108 -38
- package/esm/util/categoricalField.d.ts +56 -0
- package/esm/util/categoricalField.js +73 -0
- package/esm/util/cellMatches.d.ts +23 -0
- package/esm/util/cellMatches.js +264 -0
- package/esm/util/cellsStep.d.ts +29 -0
- package/esm/util/cellsStep.js +437 -0
- package/esm/util/clampToContig.d.ts +17 -0
- package/esm/util/clampToContig.js +19 -0
- package/esm/util/coarseStripHTML.js +1 -2
- package/esm/util/color/cssColorsLevel4.d.ts +1 -0
- package/esm/util/color/cssColorsLevel4.js +1 -0
- package/esm/util/color/index.d.ts +5 -3
- package/esm/util/color/index.js +7 -4
- package/esm/util/colorBits.d.ts +3 -3
- package/esm/util/colorBits.js +19 -44
- package/esm/util/colorRamp.d.ts +49 -5
- package/esm/util/colorRamp.js +169 -18
- package/esm/util/colorScale.d.ts +156 -0
- package/esm/util/colorScale.js +243 -0
- package/esm/util/colorSchemes.d.ts +21 -0
- package/esm/util/colorSchemes.js +30 -0
- package/esm/util/copyToClipboard.js +8 -1
- package/esm/util/{createStopTokenRotation.d.ts → createAbortRotation.d.ts} +21 -23
- package/esm/util/{createStopTokenRotation.js → createAbortRotation.js} +21 -52
- package/esm/util/createSvgRasterCanvas.d.ts +10 -0
- package/esm/util/cssColorParse.d.ts +15 -0
- package/esm/util/cssColorParse.js +53 -0
- package/esm/util/diagonalizeRegions.d.ts +2 -3
- package/esm/util/diagonalizeRegions.js +8 -13
- package/esm/util/expandLooseSearchIndex.d.ts +19 -0
- package/esm/util/expandLooseSearchIndex.js +29 -0
- package/esm/util/featureTable.d.ts +224 -0
- package/esm/util/featureTable.js +366 -0
- package/esm/util/featureTransforms.d.ts +81 -0
- package/esm/util/featureTransforms.js +1231 -0
- package/esm/util/featureTypes.d.ts +24 -0
- package/esm/util/featureTypes.js +35 -0
- package/esm/util/fetchAndMaybeUnzip.js +16 -9
- package/esm/util/fetchContext.d.ts +7 -8
- package/esm/util/fetchContext.js +3 -3
- package/esm/util/fetchHub.d.ts +4 -2
- package/esm/util/fetchHub.js +2 -2
- package/esm/util/fetchPhases.d.ts +10 -10
- package/esm/util/fetchSeq.d.ts +2 -3
- package/esm/util/fetchSeq.js +2 -2
- package/esm/util/fieldReader.d.ts +17 -0
- package/esm/util/fieldReader.js +62 -0
- package/esm/util/formatBytes.js +1 -1
- package/esm/util/formatGuessers.d.ts +25 -14
- package/esm/util/formatGuessers.js +42 -27
- package/esm/util/formatRelativeTime.js +1 -1
- package/esm/util/freezeDeep.d.ts +8 -10
- package/esm/util/freezeDeep.js +8 -10
- package/esm/util/getLocationUri.d.ts +2 -1
- package/esm/util/getLocationUri.js +8 -2
- package/esm/util/groupKeys.d.ts +76 -0
- package/esm/util/groupKeys.js +156 -0
- package/esm/util/highlights.d.ts +10 -6
- package/esm/util/highlights.js +12 -25
- package/esm/util/hooks.d.ts +31 -2
- package/esm/util/hooks.js +72 -3
- package/esm/util/index.d.ts +11 -11
- package/esm/util/index.js +11 -10
- package/esm/util/indexCandidates.d.ts +1 -31
- package/esm/util/indexCandidates.js +5 -63
- package/esm/util/installFetch.d.ts +77 -37
- package/esm/util/installFetch.js +65 -38
- package/esm/util/installInitAutorun.d.ts +14 -13
- package/esm/util/installInitAutorun.js +17 -17
- package/esm/util/installPrerequisiteFetch.d.ts +115 -0
- package/esm/util/installPrerequisiteFetch.js +111 -0
- package/esm/util/intervals.js +9 -4
- package/esm/util/io/index.js +22 -15
- package/esm/util/isDataCurrent.d.ts +7 -5
- package/esm/util/isDataCurrent.js +9 -6
- package/esm/util/isTextEntryFocused.d.ts +7 -0
- package/esm/util/isTextEntryFocused.js +16 -0
- package/esm/util/jexl.js +24 -21
- package/esm/util/jexlFilterRows.d.ts +89 -0
- package/esm/util/jexlFilterRows.js +252 -0
- package/esm/util/jexlFilters.d.ts +32 -57
- package/esm/util/jexlFilters.js +31 -29
- package/esm/util/jexlStrings.d.ts +3 -4
- package/esm/util/jexlStrings.js +2 -3
- package/esm/util/layouts/GranularRectLayout.d.ts +8 -1
- package/esm/util/layouts/GranularRectLayout.js +25 -8
- package/esm/util/lazyAfterAttach.d.ts +13 -0
- package/esm/util/lazyAfterAttach.js +31 -0
- package/esm/util/lazyWithPreload.d.ts +19 -0
- package/esm/util/lazyWithPreload.js +27 -0
- package/esm/util/legendCandidates.d.ts +72 -0
- package/esm/util/legendCandidates.js +138 -0
- package/esm/util/locString.js +5 -2
- package/esm/util/localStorage.js +4 -4
- package/esm/util/markEncoding.d.ts +150 -0
- package/esm/util/markEncoding.js +885 -0
- package/esm/util/markEncodingTypes.d.ts +595 -0
- package/esm/util/markEncodingTypes.js +8 -0
- package/esm/util/mst-reflection.d.ts +2 -20
- package/esm/util/mst-reflection.js +3 -53
- package/esm/util/mstUtils.d.ts +31 -23
- package/esm/util/mstUtils.js +39 -24
- package/esm/util/numericUtils.d.ts +7 -0
- package/esm/util/numericUtils.js +16 -0
- package/esm/util/numericValue.d.ts +14 -0
- package/esm/util/numericValue.js +34 -0
- package/esm/util/openFeatureWidget.d.ts +5 -0
- package/esm/util/openFeatureWidget.js +2 -2
- package/esm/util/openViews.d.ts +17 -0
- package/esm/util/openViews.js +22 -0
- package/esm/util/parentWalk.d.ts +1 -1
- package/esm/util/parentWalk.js +1 -1
- package/esm/util/parseLineByLine.d.ts +4 -5
- package/esm/util/parseLineByLine.js +8 -14
- package/esm/util/pluginStore.d.ts +6 -8
- package/esm/util/pluginStore.js +17 -16
- package/esm/util/preloadComponent.d.ts +5 -0
- package/esm/util/preloadComponent.js +11 -0
- package/esm/util/progress.d.ts +22 -22
- package/esm/util/progress.js +27 -26
- package/esm/util/quantileExtent.d.ts +49 -0
- package/esm/util/quantileExtent.js +162 -0
- package/esm/util/range.d.ts +13 -9
- package/esm/util/range.js +17 -8
- package/esm/util/renameRegions.d.ts +26 -6
- package/esm/util/renameRegions.js +68 -54
- package/esm/util/renderToStaticMarkup.js +24 -14
- package/esm/util/rxjs.d.ts +23 -8
- package/esm/util/rxjs.js +61 -15
- package/esm/util/samplesTsv.d.ts +49 -0
- package/esm/util/samplesTsv.js +86 -0
- package/esm/util/scheduleDetachedDestroy.d.ts +18 -0
- package/esm/util/scheduleDetachedDestroy.js +24 -0
- package/esm/util/scrollLatch.d.ts +1 -0
- package/esm/util/scrollLatch.js +8 -0
- package/esm/util/selectEncodedFeature.d.ts +16 -0
- package/esm/util/selectEncodedFeature.js +34 -0
- package/esm/util/sessionSharing.d.ts +7 -5
- package/esm/util/sessionSharing.js +23 -23
- package/esm/util/shapeNameList.d.ts +2 -0
- package/esm/util/shapeNameList.js +6 -0
- package/esm/util/shapeNames.d.ts +7 -0
- package/esm/util/shapeNames.js +11 -0
- package/esm/util/simpleFeature.d.ts +0 -1
- package/esm/util/springAnimate.js +1 -1
- package/esm/util/starFusion.d.ts +26 -0
- package/esm/util/starFusion.js +37 -0
- package/esm/util/stepTables.d.ts +96 -0
- package/esm/util/stepTables.js +277 -0
- package/esm/util/svAlt.d.ts +145 -0
- package/esm/util/svAlt.js +364 -0
- package/esm/util/svgColorProps.d.ts +11 -0
- package/esm/util/svgColorProps.js +28 -1
- package/esm/util/systemColorScheme.d.ts +12 -0
- package/esm/util/systemColorScheme.js +27 -0
- package/esm/util/tabix.d.ts +19 -10
- package/esm/util/tabix.js +19 -14
- package/esm/util/thresholdScale.d.ts +91 -0
- package/esm/util/thresholdScale.js +166 -0
- package/esm/util/timeGate.d.ts +4 -5
- package/esm/util/timeGate.js +4 -5
- package/esm/util/trackConfigDelta.d.ts +26 -26
- package/esm/util/trackConfigDelta.js +63 -47
- package/esm/util/tracks.d.ts +120 -66
- package/esm/util/tracks.js +501 -151
- package/esm/util/translateTranscript.d.ts +44 -0
- package/esm/util/translateTranscript.js +102 -0
- package/esm/util/types/data.d.ts +0 -2
- package/esm/util/types/index.d.ts +121 -22
- package/esm/util/types/index.js +9 -0
- package/esm/util/types/mst.d.ts +3 -0
- package/esm/util/types/mst.js +4 -0
- package/esm/util/types/renameIds.d.ts +1 -0
- package/esm/util/types/renameIds.js +29 -0
- package/esm/util/types/services.d.ts +1 -1
- package/esm/util/unknownSnapshotKeys.d.ts +53 -0
- package/esm/util/unknownSnapshotKeys.js +76 -0
- package/esm/util/useFeatureSequence.js +5 -5
- package/esm/util/useFetch.d.ts +3 -4
- package/esm/util/useFetch.js +19 -10
- package/esm/util/useFetchPlugins.d.ts +6 -2
- package/esm/util/useFetchPlugins.js +7 -3
- package/esm/util/usePanZoom.js +10 -3
- package/esm/util/usePanelVirtualScroll.d.ts +7 -35
- package/esm/util/usePanelVirtualScroll.js +9 -36
- package/esm/util/useRafCommit.js +1 -0
- package/esm/util/useRowVirtualScroll.d.ts +6 -29
- package/esm/util/useRowVirtualScroll.js +8 -49
- package/esm/util/useVirtualScrollWheel.d.ts +20 -4
- package/esm/util/useVirtualScrollWheel.js +40 -74
- package/esm/util/viewHighlights.d.ts +3 -0
- package/esm/util/viewHighlights.js +5 -0
- package/esm/util/viewStatus.d.ts +47 -15
- package/esm/util/viewStatus.js +34 -0
- package/esm/util/wheelZoom.d.ts +7 -1
- package/esm/util/wheelZoom.js +85 -19
- package/esm/util/whenViewSettled.d.ts +55 -8
- package/esm/util/whenViewSettled.js +56 -7
- package/esm/util/withFeatureDetails.js +4 -0
- package/esm/util/withLaunchInput.d.ts +174 -0
- package/esm/util/withLaunchInput.js +274 -0
- package/package.json +75 -24
- package/esm/BaseFeatureWidget/BaseFeatureDetail/Position.d.ts +0 -2
- package/esm/BaseFeatureWidget/BaseFeatureDetail/Position.js +0 -8
- package/esm/BaseFeatureWidget/BaseFeatureDetail/types.d.ts +0 -8
- package/esm/BaseFeatureWidget/SequenceFeatureDetails/test_data/DLGAP3.d.ts +0 -80
- package/esm/BaseFeatureWidget/SequenceFeatureDetails/test_data/DLGAP3.js +0 -583
- package/esm/BaseFeatureWidget/SequenceFeatureDetails/test_data/NCDN.d.ts +0 -141
- package/esm/BaseFeatureWidget/SequenceFeatureDetails/test_data/NCDN.js +0 -1116
- package/esm/ReExports/BaseFeatureDetails.d.ts +0 -1
- package/esm/ReExports/BaseFeatureDetails.js +0 -10
- package/esm/ReExports/index.d.ts +0 -1
- package/esm/ReExports/index.js +0 -1
- package/esm/ReExports/publicUtil.d.ts +0 -1
- package/esm/ReExports/publicUtil.js +0 -28
- package/esm/configuration/promotableDefaults.d.ts +0 -199
- package/esm/configuration/promotableDefaults.js +0 -326
- package/esm/configuration/promotablePin.d.ts +0 -55
- package/esm/configuration/promotablePin.js +0 -1
- package/esm/configuration/promotableResolve.d.ts +0 -108
- package/esm/configuration/promotableResolve.js +0 -117
- package/esm/configuration/promotableSlots.d.ts +0 -12
- package/esm/configuration/promotableSlots.js +0 -45
- package/esm/configuration/slotShape.d.ts +0 -12
- package/esm/configuration/slotShape.js +0 -84
- package/esm/pluggableElementTypes/models/HighlightsMixin.d.ts +0 -51
- package/esm/pluggableElementTypes/models/HighlightsMixin.js +0 -78
- package/esm/ui/PinAdornment.d.ts +0 -5
- package/esm/ui/PinAdornment.js +0 -79
- package/esm/ui/SvgGradientLegend.d.ts +0 -26
- package/esm/ui/SvgGradientLegend.js +0 -26
- package/esm/ui/highlightChipReveal.d.ts +0 -32
- package/esm/ui/highlightChipReveal.js +0 -39
- package/esm/ui/promotableMenuItems.d.ts +0 -19
- package/esm/ui/promotableMenuItems.js +0 -89
- package/esm/ui/promotablePinCoverage.d.ts +0 -44
- package/esm/ui/promotablePinCoverage.js +0 -87
- package/esm/util/applyInitSettings.d.ts +0 -79
- package/esm/util/applyInitSettings.js +0 -91
- package/esm/util/openDisplays.d.ts +0 -23
- package/esm/util/openDisplays.js +0 -79
- package/esm/util/stopToken.d.ts +0 -211
- package/esm/util/stopToken.js +0 -438
- /package/esm/{BaseFeatureWidget/BaseFeatureDetail/types.js → data_adapters/BaseAdapter/zoomRange.js} +0 -0
package/esm/util/tabix.js
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { createStatusFanOut, downloadStatus } from './progress.js';
|
|
2
2
|
import { calculateRedispatchRange } from './range.js';
|
|
3
|
-
import { withStopTokenSignal } from './stopToken.js';
|
|
4
3
|
/**
|
|
5
4
|
* Read the feature type (column 3) from a raw GFF3/GTF line without a full
|
|
6
5
|
* split. Used only to classify a line for redispatch.
|
|
@@ -18,15 +17,15 @@ function extractType(line) {
|
|
|
18
17
|
* label, capturing each line's byte offset, indexed start/end, and feature type
|
|
19
18
|
* into a {@link TabixLine}. Shared by the GFF3 and GTF tabix adapters.
|
|
20
19
|
*
|
|
21
|
-
* The
|
|
20
|
+
* The signal becomes the read's `AbortSignal`, so a cancelled fetch drops
|
|
22
21
|
* its block reads at the socket instead of downloading them and discarding the
|
|
23
22
|
* lines. @gmod/tabix aborts a block shared between callers only once every
|
|
24
23
|
* joined caller has aborted (`AggregateAbortController`), so this can't cancel a
|
|
25
24
|
* chunk another region still needs.
|
|
26
25
|
*/
|
|
27
|
-
export function readTabixLines(gff, refName, start, end, statusCallback,
|
|
26
|
+
export function readTabixLines(gff, refName, start, end, statusCallback, signal) {
|
|
28
27
|
const lines = [];
|
|
29
|
-
return
|
|
28
|
+
return downloadStatus('Downloading features', statusCallback, onProgress => gff.getLines(refName, start, end, {
|
|
30
29
|
lineCallback: (line, offset, s, e) => {
|
|
31
30
|
lines.push({
|
|
32
31
|
line,
|
|
@@ -38,15 +37,21 @@ export function readTabixLines(gff, refName, start, end, statusCallback, stopTok
|
|
|
38
37
|
},
|
|
39
38
|
onProgress,
|
|
40
39
|
signal,
|
|
41
|
-
}))
|
|
40
|
+
})).then(() => lines);
|
|
42
41
|
}
|
|
43
42
|
/**
|
|
44
43
|
* Read a region's tabix lines, then — if any feature found there extends past
|
|
45
44
|
* the query — read the overhang on either side, so a parent line's children (a
|
|
46
45
|
* gene's exons, a transcript's CDS) outside the original window are pulled in
|
|
47
|
-
* and the parent/child tree resolves fully.
|
|
48
|
-
*
|
|
49
|
-
*
|
|
46
|
+
* and the parent/child tree resolves fully. `expands` decides which lines widen
|
|
47
|
+
* the bound, so one chromosome-spanning record can't force a whole-chromosome
|
|
48
|
+
* refetch; {@link calculateRedispatchRange} says why that is a predicate.
|
|
49
|
+
*
|
|
50
|
+
* **There is one control, and skipping the expansion is a value of it**: an
|
|
51
|
+
* `expands` that admits nothing reads the query and stops. A caller that wants
|
|
52
|
+
* that says so to its adapter, which is the layer that knows whether its format
|
|
53
|
+
* can honour it — see `Gff3TabixAdapter`, and `GtfTabixAdapter` for a format
|
|
54
|
+
* that cannot.
|
|
50
55
|
*
|
|
51
56
|
* **The flanks, not the union.** Re-reading `[minStart, maxEnd]` returns
|
|
52
57
|
* everything the first read already had — a second full read of the query range
|
|
@@ -74,13 +79,13 @@ export function readTabixLines(gff, refName, start, end, statusCallback, stopTok
|
|
|
74
79
|
export async function readTabixLinesRedispatched(file,
|
|
75
80
|
// the region's locus only — kept structural, like TabixLineSource above, so
|
|
76
81
|
// this module stays free of the `types` barrel and its MST models
|
|
77
|
-
query,
|
|
78
|
-
const { statusCallback,
|
|
82
|
+
query, expands, opts = {}) {
|
|
83
|
+
const { statusCallback, signal } = opts;
|
|
79
84
|
// `cb` is not optional: each read decides where it reports, and the flanks
|
|
80
85
|
// report somewhere the first read does not
|
|
81
|
-
const read = (start, end, cb) => readTabixLines(file, query.refName, start, end, cb,
|
|
86
|
+
const read = (start, end, cb) => readTabixLines(file, query.refName, start, end, cb, signal);
|
|
82
87
|
const lines = await read(query.start, query.end, statusCallback);
|
|
83
|
-
const redispatch = calculateRedispatchRange(lines,
|
|
88
|
+
const redispatch = calculateRedispatchRange(lines, expands, query.start, query.end);
|
|
84
89
|
if (redispatch) {
|
|
85
90
|
const slot = createStatusFanOut(statusCallback);
|
|
86
91
|
const flanks = await Promise.all([
|
|
@@ -138,6 +143,6 @@ function mergeTabixLines(...groups) {
|
|
|
138
143
|
* commented block and then the counted rows used to fetch and decompress the
|
|
139
144
|
* same bytes twice, which every bare-header file did on every call.
|
|
140
145
|
*/
|
|
141
|
-
export function readTabixHeaderLines(file) {
|
|
142
|
-
return file.getHeaderLines();
|
|
146
|
+
export function readTabixHeaderLines(file, opts) {
|
|
147
|
+
return file.getHeaderLines(opts);
|
|
143
148
|
}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import type { CategoricalScale } from '../ui/colorScale.ts';
|
|
2
|
+
import type { CategoricalField } from './categoricalField.ts';
|
|
3
|
+
/**
|
|
4
|
+
* #api
|
|
5
|
+
* A domain written as strings — the shared `domain` slot is a `stringArray` —
|
|
6
|
+
* read back as the numbers it names. A member that is not a number reads NaN,
|
|
7
|
+
* which every comparison against it declines.
|
|
8
|
+
*/
|
|
9
|
+
export declare function numericDomain(domain: readonly (string | number)[]): number[];
|
|
10
|
+
/**
|
|
11
|
+
* #api
|
|
12
|
+
* A threshold scale's cut points as {@link thresholdIndex} walks them: the
|
|
13
|
+
* numbers the domain names, ascending. Cuts written high to low, as p-value
|
|
14
|
+
* thresholds often are, left the middle interval unreachable, the walk stopping
|
|
15
|
+
* at the first cut a value is under.
|
|
16
|
+
*/
|
|
17
|
+
export declare function thresholdCuts(domain: readonly (string | number)[]): number[];
|
|
18
|
+
/**
|
|
19
|
+
* #api
|
|
20
|
+
* The bin a value falls in: how many of the ascending cut points it is at or
|
|
21
|
+
* past, so a palette with one more entry than the domain paints it as
|
|
22
|
+
* `palette[thresholdIndex(value, domain)]`. A value that is not a number is
|
|
23
|
+
* in no bin and answers -1; an infinite one takes the end bin on its side, as
|
|
24
|
+
* d3's threshold scale places it, so a `-log10` of a zero p-value lands in
|
|
25
|
+
* the top bin.
|
|
26
|
+
*/
|
|
27
|
+
export declare function thresholdIndex(value: unknown, domain: readonly number[]): number;
|
|
28
|
+
/**
|
|
29
|
+
* #api
|
|
30
|
+
* The colour of each interval, in order: the declared palette, and the
|
|
31
|
+
* default categorical palette where it runs out.
|
|
32
|
+
*/
|
|
33
|
+
export declare function thresholdPalette(bins: number, palette?: readonly string[]): string[];
|
|
34
|
+
/**
|
|
35
|
+
* #api
|
|
36
|
+
* What a threshold scale's bins are called in a key, one label per palette
|
|
37
|
+
* entry: `< a` below the first cut, `a – b` between two, `≥ b` past the last.
|
|
38
|
+
*/
|
|
39
|
+
export declare function thresholdLabels(domain: readonly number[]): string[];
|
|
40
|
+
/**
|
|
41
|
+
* #api
|
|
42
|
+
* The key a value holding text that is no number files under on a threshold
|
|
43
|
+
* scale, painted the misconfiguration grey rather than passing for a missing
|
|
44
|
+
* value.
|
|
45
|
+
*/
|
|
46
|
+
export declare const NOT_A_NUMBER_LABEL = "(not a number)";
|
|
47
|
+
/**
|
|
48
|
+
* #api
|
|
49
|
+
* A threshold key's rows: every interval, painted or not, since the bins are
|
|
50
|
+
* the whole domain, then the not-a-number and no-value rows where a feature
|
|
51
|
+
* took one, in the order `thresholdField` sorts them.
|
|
52
|
+
*/
|
|
53
|
+
export declare function thresholdKeyEntries(cuts: readonly number[], range: readonly string[] | undefined, met: {
|
|
54
|
+
missing?: boolean;
|
|
55
|
+
notNumber?: boolean;
|
|
56
|
+
}, names?: readonly string[]): {
|
|
57
|
+
value: string;
|
|
58
|
+
label: string;
|
|
59
|
+
color: string;
|
|
60
|
+
missing?: true;
|
|
61
|
+
}[];
|
|
62
|
+
/**
|
|
63
|
+
* #api
|
|
64
|
+
* The rows a ramp's key lists beside its bar once a feature painted one: the
|
|
65
|
+
* not-a-number and no-value rows a threshold's key ends with. Empty while
|
|
66
|
+
* neither painted.
|
|
67
|
+
*/
|
|
68
|
+
export declare function rampGapScales(id: string, met: {
|
|
69
|
+
missing?: boolean;
|
|
70
|
+
notNumber?: boolean;
|
|
71
|
+
}): CategoricalScale[];
|
|
72
|
+
/**
|
|
73
|
+
* #api
|
|
74
|
+
* Whether a field holds no value at all, as against text that fails to parse:
|
|
75
|
+
* absent, empty, or a VCF's `AF=.`, which arrives as `[undefined]`.
|
|
76
|
+
*/
|
|
77
|
+
export declare function isMissing(value: unknown): boolean;
|
|
78
|
+
/**
|
|
79
|
+
* #api
|
|
80
|
+
* A threshold scale read the way every categorical channel reads its field: a
|
|
81
|
+
* value files under the label of the bin it falls in, a feature with no value
|
|
82
|
+
* under `''`, and text that is no number under {@link NOT_A_NUMBER_LABEL}.
|
|
83
|
+
* The bins are the whole domain, so a key lists each one. `labels` names the
|
|
84
|
+
* bins in a key, one each from the lowest, where a config spells them for a
|
|
85
|
+
* reader; a bin's key stays its interval.
|
|
86
|
+
*/
|
|
87
|
+
export declare function thresholdField(field: string, { domain, range, labels: names, }?: {
|
|
88
|
+
domain?: readonly string[];
|
|
89
|
+
range?: readonly string[];
|
|
90
|
+
labels?: readonly string[];
|
|
91
|
+
}): CategoricalField;
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
import { categoricalPalette } from '../ui/colors.js';
|
|
2
|
+
import { NO_VALUE_LABEL, keyNames } from './categoricalField.js';
|
|
3
|
+
import { MISCONFIGURED_COLOR, NO_CATEGORY_COLOR } from './color/index.js';
|
|
4
|
+
import { groupKeyComparator, valueText } from './groupKeys.js';
|
|
5
|
+
import { numericValue } from './numericValue.js';
|
|
6
|
+
/**
|
|
7
|
+
* #api
|
|
8
|
+
* A domain written as strings — the shared `domain` slot is a `stringArray` —
|
|
9
|
+
* read back as the numbers it names. A member that is not a number reads NaN,
|
|
10
|
+
* which every comparison against it declines.
|
|
11
|
+
*/
|
|
12
|
+
export function numericDomain(domain) {
|
|
13
|
+
return domain.map(Number);
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* #api
|
|
17
|
+
* A threshold scale's cut points as {@link thresholdIndex} walks them: the
|
|
18
|
+
* numbers the domain names, ascending. Cuts written high to low, as p-value
|
|
19
|
+
* thresholds often are, left the middle interval unreachable, the walk stopping
|
|
20
|
+
* at the first cut a value is under.
|
|
21
|
+
*/
|
|
22
|
+
export function thresholdCuts(domain) {
|
|
23
|
+
return numericDomain(domain)
|
|
24
|
+
.filter(cut => Number.isFinite(cut))
|
|
25
|
+
.sort((a, b) => a - b);
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* #api
|
|
29
|
+
* The bin a value falls in: how many of the ascending cut points it is at or
|
|
30
|
+
* past, so a palette with one more entry than the domain paints it as
|
|
31
|
+
* `palette[thresholdIndex(value, domain)]`. A value that is not a number is
|
|
32
|
+
* in no bin and answers -1; an infinite one takes the end bin on its side, as
|
|
33
|
+
* d3's threshold scale places it, so a `-log10` of a zero p-value lands in
|
|
34
|
+
* the top bin.
|
|
35
|
+
*/
|
|
36
|
+
export function thresholdIndex(value, domain) {
|
|
37
|
+
const v = numericValue(value);
|
|
38
|
+
if (Number.isNaN(v)) {
|
|
39
|
+
return -1;
|
|
40
|
+
}
|
|
41
|
+
let i = 0;
|
|
42
|
+
while (i < domain.length && v >= domain[i]) {
|
|
43
|
+
i++;
|
|
44
|
+
}
|
|
45
|
+
return i;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* #api
|
|
49
|
+
* The colour of each interval, in order: the declared palette, and the
|
|
50
|
+
* default categorical palette where it runs out.
|
|
51
|
+
*/
|
|
52
|
+
export function thresholdPalette(bins, palette = []) {
|
|
53
|
+
return Array.from({ length: bins }, (_, i) => palette[i] ?? categoricalPalette[i % categoricalPalette.length]);
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* #api
|
|
57
|
+
* What a threshold scale's bins are called in a key, one label per palette
|
|
58
|
+
* entry: `< a` below the first cut, `a – b` between two, `≥ b` past the last.
|
|
59
|
+
*/
|
|
60
|
+
export function thresholdLabels(domain) {
|
|
61
|
+
if (domain.length === 0) {
|
|
62
|
+
return ['any value'];
|
|
63
|
+
}
|
|
64
|
+
return [
|
|
65
|
+
`< ${domain[0]}`,
|
|
66
|
+
...domain.slice(1).map((cut, i) => `${domain[i]} – ${cut}`),
|
|
67
|
+
`≥ ${domain.at(-1)}`,
|
|
68
|
+
];
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* #api
|
|
72
|
+
* The key a value holding text that is no number files under on a threshold
|
|
73
|
+
* scale, painted the misconfiguration grey rather than passing for a missing
|
|
74
|
+
* value.
|
|
75
|
+
*/
|
|
76
|
+
export const NOT_A_NUMBER_LABEL = '(not a number)';
|
|
77
|
+
/**
|
|
78
|
+
* #api
|
|
79
|
+
* A threshold key's rows: every interval, painted or not, since the bins are
|
|
80
|
+
* the whole domain, then the not-a-number and no-value rows where a feature
|
|
81
|
+
* took one, in the order `thresholdField` sorts them.
|
|
82
|
+
*/
|
|
83
|
+
export function thresholdKeyEntries(cuts, range, met, names = []) {
|
|
84
|
+
const labels = thresholdLabels(cuts);
|
|
85
|
+
const colors = thresholdPalette(labels.length, range);
|
|
86
|
+
return [
|
|
87
|
+
...labels.map((label, i) => ({
|
|
88
|
+
value: label,
|
|
89
|
+
label: names[i] ?? label,
|
|
90
|
+
color: colors[i],
|
|
91
|
+
})),
|
|
92
|
+
...(met.notNumber
|
|
93
|
+
? [
|
|
94
|
+
{
|
|
95
|
+
value: NOT_A_NUMBER_LABEL,
|
|
96
|
+
label: NOT_A_NUMBER_LABEL,
|
|
97
|
+
color: MISCONFIGURED_COLOR,
|
|
98
|
+
},
|
|
99
|
+
]
|
|
100
|
+
: []),
|
|
101
|
+
...(met.missing
|
|
102
|
+
? [
|
|
103
|
+
{
|
|
104
|
+
value: '',
|
|
105
|
+
label: NO_VALUE_LABEL,
|
|
106
|
+
color: NO_CATEGORY_COLOR,
|
|
107
|
+
missing: true,
|
|
108
|
+
},
|
|
109
|
+
]
|
|
110
|
+
: []),
|
|
111
|
+
];
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* #api
|
|
115
|
+
* The rows a ramp's key lists beside its bar once a feature painted one: the
|
|
116
|
+
* not-a-number and no-value rows a threshold's key ends with. Empty while
|
|
117
|
+
* neither painted.
|
|
118
|
+
*/
|
|
119
|
+
export function rampGapScales(id, met) {
|
|
120
|
+
const entries = thresholdKeyEntries([], undefined, met).slice(1);
|
|
121
|
+
return entries.length > 0 ? [{ kind: 'categorical', id, entries }] : [];
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* #api
|
|
125
|
+
* Whether a field holds no value at all, as against text that fails to parse:
|
|
126
|
+
* absent, empty, or a VCF's `AF=.`, which arrives as `[undefined]`.
|
|
127
|
+
*/
|
|
128
|
+
export function isMissing(value) {
|
|
129
|
+
return Array.isArray(value)
|
|
130
|
+
? value.every(v => v === undefined || v === null)
|
|
131
|
+
: valueText(value) === '';
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* #api
|
|
135
|
+
* A threshold scale read the way every categorical channel reads its field: a
|
|
136
|
+
* value files under the label of the bin it falls in, a feature with no value
|
|
137
|
+
* under `''`, and text that is no number under {@link NOT_A_NUMBER_LABEL}.
|
|
138
|
+
* The bins are the whole domain, so a key lists each one. `labels` names the
|
|
139
|
+
* bins in a key, one each from the lowest, where a config spells them for a
|
|
140
|
+
* reader; a bin's key stays its interval.
|
|
141
|
+
*/
|
|
142
|
+
export function thresholdField(field, { domain = [], range = [], labels: names = [], } = {}) {
|
|
143
|
+
const cuts = thresholdCuts(domain);
|
|
144
|
+
const labels = thresholdLabels(cuts);
|
|
145
|
+
const named = keyNames(labels, names);
|
|
146
|
+
const palette = thresholdPalette(labels.length, range);
|
|
147
|
+
const colorOf = new Map(labels.map((label, i) => [label, palette[i]]));
|
|
148
|
+
return {
|
|
149
|
+
field,
|
|
150
|
+
domain: labels,
|
|
151
|
+
closed: true,
|
|
152
|
+
key: value => {
|
|
153
|
+
if (isMissing(value)) {
|
|
154
|
+
return '';
|
|
155
|
+
}
|
|
156
|
+
const bin = thresholdIndex(value, cuts);
|
|
157
|
+
return bin < 0 ? NOT_A_NUMBER_LABEL : labels[bin];
|
|
158
|
+
},
|
|
159
|
+
compare: groupKeyComparator([...labels, NOT_A_NUMBER_LABEL]),
|
|
160
|
+
label: key => (key === '' ? NO_VALUE_LABEL : (named.get(key) ?? key)),
|
|
161
|
+
sectionLabel: key => `${field}: ${key === '' ? 'none' : key}`,
|
|
162
|
+
color: key => key === ''
|
|
163
|
+
? NO_CATEGORY_COLOR
|
|
164
|
+
: (colorOf.get(key) ?? MISCONFIGURED_COLOR),
|
|
165
|
+
};
|
|
166
|
+
}
|
package/esm/util/timeGate.d.ts
CHANGED
|
@@ -5,8 +5,8 @@
|
|
|
5
5
|
*
|
|
6
6
|
* `Date.now()` costs ~40ns, invisible until the loop is a 666k-read pileup —
|
|
7
7
|
* there it measured ~28ms per gated callsite, and the alignments worker has two
|
|
8
|
-
* of them (the progress emit in `createProgressReporter` and the
|
|
9
|
-
*
|
|
8
|
+
* of them (the progress emit in `createProgressReporter` and the yield in
|
|
9
|
+
* `createAbortBreakpoint`). Both previously read the clock per call, on the
|
|
10
10
|
* documented reasoning that it was negligible next to the per-item work; at
|
|
11
11
|
* this item count it measurably isn't.
|
|
12
12
|
*
|
|
@@ -18,9 +18,8 @@
|
|
|
18
18
|
* measure a low rate and hold a stride of 1, gating on time alone as before,
|
|
19
19
|
* while a millions-of-calls loop thins itself out.
|
|
20
20
|
*
|
|
21
|
-
* `intervalMs` is per call rather than fixed at construction
|
|
22
|
-
*
|
|
23
|
-
* linearly over a long loop. Both current callers pass a constant.
|
|
21
|
+
* `intervalMs` is per call rather than fixed at construction; both current
|
|
22
|
+
* callers pass a constant.
|
|
24
23
|
*/
|
|
25
24
|
export declare function createTimeGate(): (intervalMs: number) => boolean;
|
|
26
25
|
export type TimeGate = ReturnType<typeof createTimeGate>;
|
package/esm/util/timeGate.js
CHANGED
|
@@ -24,8 +24,8 @@ const STRIDE_GROWTH_LIMIT = 8;
|
|
|
24
24
|
*
|
|
25
25
|
* `Date.now()` costs ~40ns, invisible until the loop is a 666k-read pileup —
|
|
26
26
|
* there it measured ~28ms per gated callsite, and the alignments worker has two
|
|
27
|
-
* of them (the progress emit in `createProgressReporter` and the
|
|
28
|
-
*
|
|
27
|
+
* of them (the progress emit in `createProgressReporter` and the yield in
|
|
28
|
+
* `createAbortBreakpoint`). Both previously read the clock per call, on the
|
|
29
29
|
* documented reasoning that it was negligible next to the per-item work; at
|
|
30
30
|
* this item count it measurably isn't.
|
|
31
31
|
*
|
|
@@ -37,9 +37,8 @@ const STRIDE_GROWTH_LIMIT = 8;
|
|
|
37
37
|
* measure a low rate and hold a stride of 1, gating on time alone as before,
|
|
38
38
|
* while a millions-of-calls loop thins itself out.
|
|
39
39
|
*
|
|
40
|
-
* `intervalMs` is per call rather than fixed at construction
|
|
41
|
-
*
|
|
42
|
-
* linearly over a long loop. Both current callers pass a constant.
|
|
40
|
+
* `intervalMs` is per call rather than fixed at construction; both current
|
|
41
|
+
* callers pass a constant.
|
|
43
42
|
*/
|
|
44
43
|
export function createTimeGate() {
|
|
45
44
|
let stride = 1;
|
|
@@ -12,24 +12,22 @@
|
|
|
12
12
|
* - `diffTrackConfig(base, edited)` — the minimal delta
|
|
13
13
|
* - `mergeTrackConfig(base, delta)` — reconstruct the effective config
|
|
14
14
|
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
* customized tracks" exists to unset a slot, and an admin config is free to set
|
|
28
|
-
* one. That branch now keeps the working copy; see the comment there.
|
|
15
|
+
* A delta is a JSON Merge Patch (RFC 7396) over the base, so a `null` member is
|
|
16
|
+
* a reset: the merge removes the member and the schema's default applies. That
|
|
17
|
+
* is ADR-146's spelling of a reset, and the diff writes one wherever the base
|
|
18
|
+
* sets a member the edited config lacks — a slot put back to its default, or a
|
|
19
|
+
* list emptied, since `stripDefault` drops both from a snapshot. Where the edit
|
|
20
|
+
* left a whole namespace at its default, the nulls land on the members the base
|
|
21
|
+
* set inside it rather than on the namespace, so a member the admin adds there
|
|
22
|
+
* later still flows through. The inference
|
|
23
|
+
* is exact only because both sides are post-`stripDefault` snapshots: a member
|
|
24
|
+
* the admin wrote at its default is absent from both, where a `null` for it
|
|
25
|
+
* would block a later admin value. As in RFC 7396, a delta cannot set a member
|
|
26
|
+
* to a literal `null`; null and absent are one state.
|
|
29
27
|
*
|
|
30
28
|
* `displays` is merged by `displayId` so an edit to one display doesn't pin the
|
|
31
|
-
* others. Nested config objects (e.g. `adapter`) recurse. Any other array (value
|
|
32
|
-
* arrays like `
|
|
29
|
+
* others, and by `type` where the base has no display of that id. Nested config objects (e.g. `adapter`) recurse. Any other array (value
|
|
30
|
+
* arrays like `filter`, `assemblyNames`) is replaced wholesale when changed.
|
|
33
31
|
*
|
|
34
32
|
* Subtlety worth not "optimizing": when the base has NO `displays` array but the
|
|
35
33
|
* edited snapshot does (common — a track config that omits displays gets a stub
|
|
@@ -44,24 +42,26 @@ type Json = string | number | boolean | null | undefined | Json[] | {
|
|
|
44
42
|
[key: string]: Json;
|
|
45
43
|
};
|
|
46
44
|
/**
|
|
47
|
-
* Minimal delta of `edited` against `base
|
|
48
|
-
*
|
|
49
|
-
*
|
|
50
|
-
* self-identifying.
|
|
45
|
+
* Minimal delta of `edited` against `base`, both post-stripDefault snapshots. A
|
|
46
|
+
* member `base` sets and `edited` lacks is a `null` (see the module note).
|
|
47
|
+
* Always retains `trackId` so the delta is self-identifying.
|
|
51
48
|
*/
|
|
52
49
|
export declare function diffTrackConfig(base: Record<string, unknown>, edited: Record<string, unknown>): Record<string, unknown>;
|
|
53
50
|
/**
|
|
54
51
|
* Reconstruct the effective config by layering `delta` over the live `base`.
|
|
55
|
-
*
|
|
52
|
+
* A `null` removes the member it names, and one naming something the base no
|
|
53
|
+
* longer has is dropped, so no `null` member reaches the config a track
|
|
54
|
+
* hydrates from.
|
|
56
55
|
*/
|
|
57
56
|
export declare function mergeTrackConfig(base: Record<string, unknown>, delta: Record<string, unknown>): Record<string, unknown>;
|
|
58
|
-
/**
|
|
57
|
+
/**
|
|
58
|
+
* A single overridden slot: the dotted `path`, its base `from` and edited `to`,
|
|
59
|
+
* which is `undefined` for a reset.
|
|
60
|
+
*/
|
|
59
61
|
export interface TrackConfigChange {
|
|
60
62
|
/**
|
|
61
|
-
* Where the setting lives
|
|
62
|
-
* `
|
|
63
|
-
* into the type and slot it clears. So a producer that wants a friendlier
|
|
64
|
-
* heading sets `label` and leaves this alone.
|
|
63
|
+
* Where the setting lives. A producer that wants a friendlier heading sets
|
|
64
|
+
* `label` and leaves this alone.
|
|
65
65
|
*/
|
|
66
66
|
path: string[];
|
|
67
67
|
from: Json;
|
|
@@ -12,24 +12,22 @@
|
|
|
12
12
|
* - `diffTrackConfig(base, edited)` — the minimal delta
|
|
13
13
|
* - `mergeTrackConfig(base, delta)` — reconstruct the effective config
|
|
14
14
|
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
* customized tracks" exists to unset a slot, and an admin config is free to set
|
|
28
|
-
* one. That branch now keeps the working copy; see the comment there.
|
|
15
|
+
* A delta is a JSON Merge Patch (RFC 7396) over the base, so a `null` member is
|
|
16
|
+
* a reset: the merge removes the member and the schema's default applies. That
|
|
17
|
+
* is ADR-146's spelling of a reset, and the diff writes one wherever the base
|
|
18
|
+
* sets a member the edited config lacks — a slot put back to its default, or a
|
|
19
|
+
* list emptied, since `stripDefault` drops both from a snapshot. Where the edit
|
|
20
|
+
* left a whole namespace at its default, the nulls land on the members the base
|
|
21
|
+
* set inside it rather than on the namespace, so a member the admin adds there
|
|
22
|
+
* later still flows through. The inference
|
|
23
|
+
* is exact only because both sides are post-`stripDefault` snapshots: a member
|
|
24
|
+
* the admin wrote at its default is absent from both, where a `null` for it
|
|
25
|
+
* would block a later admin value. As in RFC 7396, a delta cannot set a member
|
|
26
|
+
* to a literal `null`; null and absent are one state.
|
|
29
27
|
*
|
|
30
28
|
* `displays` is merged by `displayId` so an edit to one display doesn't pin the
|
|
31
|
-
* others. Nested config objects (e.g. `adapter`) recurse. Any other array (value
|
|
32
|
-
* arrays like `
|
|
29
|
+
* others, and by `type` where the base has no display of that id. Nested config objects (e.g. `adapter`) recurse. Any other array (value
|
|
30
|
+
* arrays like `filter`, `assemblyNames`) is replaced wholesale when changed.
|
|
33
31
|
*
|
|
34
32
|
* Subtlety worth not "optimizing": when the base has NO `displays` array but the
|
|
35
33
|
* edited snapshot does (common — a track config that omits displays gets a stub
|
|
@@ -51,10 +49,14 @@ function isDisplayArray(v) {
|
|
|
51
49
|
v.length > 0 &&
|
|
52
50
|
v.every(e => isPlainObject(e) && typeof e.displayId === 'string'));
|
|
53
51
|
}
|
|
54
|
-
// Sentinel returned by diffValue when a value is unchanged, so callers can tell
|
|
55
|
-
// "no delta" apart from a legitimate `undefined` slot value.
|
|
56
52
|
const UNCHANGED = Symbol('unchanged');
|
|
57
53
|
function diffValue(base, edited) {
|
|
54
|
+
if (edited == null) {
|
|
55
|
+
if (base == null) {
|
|
56
|
+
return UNCHANGED;
|
|
57
|
+
}
|
|
58
|
+
return isPlainObject(base) ? diffValue(base, {}) : null;
|
|
59
|
+
}
|
|
58
60
|
if (deepEqual(base, edited)) {
|
|
59
61
|
return UNCHANGED;
|
|
60
62
|
}
|
|
@@ -67,13 +69,10 @@ function diffValue(base, edited) {
|
|
|
67
69
|
if (baseDisplay) {
|
|
68
70
|
const d = diffValue(baseDisplay, editedDisplay);
|
|
69
71
|
if (d !== UNCHANGED) {
|
|
70
|
-
// always re-key the delta entry by displayId so merge can realign it
|
|
71
72
|
out.push({ ...d, displayId: id });
|
|
72
73
|
}
|
|
73
74
|
}
|
|
74
75
|
else {
|
|
75
|
-
// a display present only in the edited config (e.g. an added display):
|
|
76
|
-
// carry it whole
|
|
77
76
|
out.push(editedDisplay);
|
|
78
77
|
}
|
|
79
78
|
}
|
|
@@ -81,25 +80,20 @@ function diffValue(base, edited) {
|
|
|
81
80
|
}
|
|
82
81
|
if (isPlainObject(edited) && isPlainObject(base)) {
|
|
83
82
|
const out = {};
|
|
84
|
-
for (const
|
|
85
|
-
const d = diffValue(base[k],
|
|
83
|
+
for (const k of new Set([...Object.keys(base), ...Object.keys(edited)])) {
|
|
84
|
+
const d = diffValue(base[k], edited[k]);
|
|
86
85
|
if (d !== UNCHANGED) {
|
|
87
86
|
out[k] = d;
|
|
88
87
|
}
|
|
89
88
|
}
|
|
90
|
-
// an object whose only difference from base is dropped keys (a reset the
|
|
91
|
-
// delta can't express, see module note) yields no adds/changes: treat it as
|
|
92
|
-
// unchanged rather than emitting a content-free entry
|
|
93
89
|
return Object.keys(out).length > 0 ? out : UNCHANGED;
|
|
94
90
|
}
|
|
95
|
-
// scalar, or an object/array replacing a scalar (or a value array): replace
|
|
96
91
|
return edited;
|
|
97
92
|
}
|
|
98
93
|
/**
|
|
99
|
-
* Minimal delta of `edited` against `base
|
|
100
|
-
*
|
|
101
|
-
*
|
|
102
|
-
* self-identifying.
|
|
94
|
+
* Minimal delta of `edited` against `base`, both post-stripDefault snapshots. A
|
|
95
|
+
* member `base` sets and `edited` lacks is a `null` (see the module note).
|
|
96
|
+
* Always retains `trackId` so the delta is self-identifying.
|
|
103
97
|
*/
|
|
104
98
|
export function diffTrackConfig(base, edited) {
|
|
105
99
|
const d = diffValue(base, edited);
|
|
@@ -107,35 +101,57 @@ export function diffTrackConfig(base, edited) {
|
|
|
107
101
|
const trackId = (edited.trackId ?? base.trackId);
|
|
108
102
|
return { ...delta, trackId };
|
|
109
103
|
}
|
|
104
|
+
// A delta display naming an id the base lacks lands on the base display of its
|
|
105
|
+
// type, keeping the base's id: a track holds one display per type, and a
|
|
106
|
+
// migrated session addresses the display by the id its old type minted.
|
|
110
107
|
function mergeValue(base, delta) {
|
|
111
|
-
if (isDisplayArray(delta)
|
|
112
|
-
const
|
|
113
|
-
const
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
});
|
|
117
|
-
// displays present only in the delta (added by the user) append after base
|
|
118
|
-
const baseIds = new Set(base.map(d => d.displayId));
|
|
108
|
+
if (isDisplayArray(delta)) {
|
|
109
|
+
const baseDisplays = isDisplayArray(base) ? base : [];
|
|
110
|
+
const baseIds = new Set(baseDisplays.map(d => d.displayId));
|
|
111
|
+
const deltaByBaseId = new Map();
|
|
112
|
+
const added = [];
|
|
119
113
|
for (const d of delta) {
|
|
120
|
-
|
|
121
|
-
|
|
114
|
+
const byType = baseIds.has(d.displayId)
|
|
115
|
+
? undefined
|
|
116
|
+
: baseDisplays.find(b => d.type !== undefined && b.type === d.type);
|
|
117
|
+
const id = (byType?.displayId ?? d.displayId);
|
|
118
|
+
if (baseIds.has(id)) {
|
|
119
|
+
const onId = { ...d, displayId: id };
|
|
120
|
+
const earlier = deltaByBaseId.get(id);
|
|
121
|
+
deltaByBaseId.set(id, earlier ? mergeValue(earlier, onId) : onId);
|
|
122
|
+
}
|
|
123
|
+
else {
|
|
124
|
+
added.push(d);
|
|
122
125
|
}
|
|
123
126
|
}
|
|
127
|
+
const merged = baseDisplays.map(baseDisplay => {
|
|
128
|
+
const d = deltaByBaseId.get(baseDisplay.displayId);
|
|
129
|
+
return d ? mergeValue(baseDisplay, d) : baseDisplay;
|
|
130
|
+
});
|
|
131
|
+
for (const d of added) {
|
|
132
|
+
merged.push(mergeValue(undefined, d));
|
|
133
|
+
}
|
|
124
134
|
return merged;
|
|
125
135
|
}
|
|
126
|
-
if (isPlainObject(delta)
|
|
127
|
-
const out = { ...base };
|
|
136
|
+
if (isPlainObject(delta)) {
|
|
137
|
+
const out = isPlainObject(base) ? { ...base } : {};
|
|
128
138
|
for (const [k, v] of Object.entries(delta)) {
|
|
129
|
-
|
|
139
|
+
if (v === null) {
|
|
140
|
+
delete out[k];
|
|
141
|
+
}
|
|
142
|
+
else {
|
|
143
|
+
out[k] = mergeValue(out[k], v);
|
|
144
|
+
}
|
|
130
145
|
}
|
|
131
146
|
return out;
|
|
132
147
|
}
|
|
133
|
-
// scalar / value array / type mismatch: delta wins
|
|
134
148
|
return delta;
|
|
135
149
|
}
|
|
136
150
|
/**
|
|
137
151
|
* Reconstruct the effective config by layering `delta` over the live `base`.
|
|
138
|
-
*
|
|
152
|
+
* A `null` removes the member it names, and one naming something the base no
|
|
153
|
+
* longer has is dropped, so no `null` member reaches the config a track
|
|
154
|
+
* hydrates from.
|
|
139
155
|
*/
|
|
140
156
|
export function mergeTrackConfig(base, delta) {
|
|
141
157
|
return mergeValue(base, delta);
|
|
@@ -174,7 +190,7 @@ function walkDelta(base, delta, path, out, identityKeys = IDENTITY_KEYS) {
|
|
|
174
190
|
}
|
|
175
191
|
}
|
|
176
192
|
else {
|
|
177
|
-
out.push({ path, from: base, to: delta });
|
|
193
|
+
out.push({ path, from: base, to: delta ?? undefined });
|
|
178
194
|
}
|
|
179
195
|
}
|
|
180
196
|
/**
|