@genome-spy/core 0.78.0 → 0.79.1
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/dist/bundle/{browser-KWU9rWZT.js → browser-CETrb2cm.js} +53 -33
- package/dist/bundle/esm-BdLYkz-m.js +248 -0
- package/dist/bundle/esm-BwiDsqSb.js +1367 -0
- package/dist/bundle/esm-CDFd1cjk.js +441 -0
- package/dist/bundle/{esm-DVOHLB1e.js → esm-CTUHLDbv.js} +30 -30
- package/dist/bundle/{esm-NIYEaYkc.js → esm-Cx-EbkOj.js} +13 -13
- package/dist/bundle/esm-DlYGqi79.js +128 -0
- package/dist/bundle/{esm-BygJiwh0.js → esm-k9p3oHkt.js} +133 -158
- package/dist/bundle/{esm-CT3ygiMq.js → esm-zAZJQO6D.js} +226 -212
- package/dist/bundle/index.es.js +14879 -11656
- package/dist/bundle/index.js +119 -108
- package/dist/bundle/{parquetRead-DG_-F5j5.js → parquetRead-Cad1SOVV.js} +473 -399
- package/dist/schema.json +18940 -6914
- package/dist/src/config/axisConfig.d.ts +2 -2
- package/dist/src/config/axisConfig.d.ts.map +1 -1
- package/dist/src/config/axisConfig.js +28 -44
- package/dist/src/config/configLayers.d.ts +45 -0
- package/dist/src/config/configLayers.d.ts.map +1 -0
- package/dist/src/config/configLayers.js +110 -0
- package/dist/src/config/defaultConfig.d.ts.map +1 -1
- package/dist/src/config/defaultConfig.js +8 -1
- package/dist/src/config/defaults/legendDefaults.d.ts +14 -0
- package/dist/src/config/defaults/legendDefaults.d.ts.map +1 -0
- package/dist/src/config/defaults/legendDefaults.js +46 -0
- package/dist/src/config/defaults/titleDefaults.d.ts.map +1 -1
- package/dist/src/config/defaults/titleDefaults.js +26 -18
- package/dist/src/config/legendConfig.d.ts +11 -0
- package/dist/src/config/legendConfig.d.ts.map +1 -0
- package/dist/src/config/legendConfig.js +63 -0
- package/dist/src/config/styleUtils.d.ts +8 -2
- package/dist/src/config/styleUtils.d.ts.map +1 -1
- package/dist/src/config/styleUtils.js +25 -1
- package/dist/src/config/themes.d.ts.map +1 -1
- package/dist/src/config/themes.js +21 -2
- package/dist/src/config/titleConfig.d.ts.map +1 -1
- package/dist/src/config/titleConfig.js +2 -18
- package/dist/src/data/collector.d.ts.map +1 -1
- package/dist/src/data/collector.js +40 -18
- package/dist/src/data/flowInit.d.ts +6 -0
- package/dist/src/data/flowInit.d.ts.map +1 -1
- package/dist/src/data/flowInit.js +1 -1
- package/dist/src/data/flowNode.d.ts +32 -0
- package/dist/src/data/flowNode.d.ts.map +1 -1
- package/dist/src/data/flowNode.js +59 -0
- package/dist/src/data/sources/lazy/bamSource.d.ts +0 -1
- package/dist/src/data/sources/lazy/bamSource.d.ts.map +1 -1
- package/dist/src/data/sources/lazy/bamSource.js +39 -30
- package/dist/src/data/sources/lazy/bigBedSource.d.ts +0 -10
- package/dist/src/data/sources/lazy/bigBedSource.d.ts.map +1 -1
- package/dist/src/data/sources/lazy/bigBedSource.js +127 -62
- package/dist/src/data/sources/lazy/bigWigSource.d.ts +2 -2
- package/dist/src/data/sources/lazy/bigWigSource.d.ts.map +1 -1
- package/dist/src/data/sources/lazy/bigWigSource.js +234 -81
- package/dist/src/data/sources/lazy/gff3Source.d.ts +7 -3
- package/dist/src/data/sources/lazy/gff3Source.d.ts.map +1 -1
- package/dist/src/data/sources/lazy/gff3Source.js +7 -8
- package/dist/src/data/sources/lazy/indexedFastaSource.d.ts +1 -1
- package/dist/src/data/sources/lazy/indexedFastaSource.d.ts.map +1 -1
- package/dist/src/data/sources/lazy/indexedFastaSource.js +28 -19
- package/dist/src/data/sources/lazy/legendEntriesSource.d.ts +24 -0
- package/dist/src/data/sources/lazy/legendEntriesSource.d.ts.map +1 -0
- package/dist/src/data/sources/lazy/legendEntriesSource.js +218 -0
- package/dist/src/data/sources/lazy/legendGradientSource.d.ts +30 -0
- package/dist/src/data/sources/lazy/legendGradientSource.d.ts.map +1 -0
- package/dist/src/data/sources/lazy/legendGradientSource.js +388 -0
- package/dist/src/data/sources/lazy/mockLazySource.d.ts +4 -1
- package/dist/src/data/sources/lazy/mockLazySource.d.ts.map +1 -1
- package/dist/src/data/sources/lazy/mockLazySource.js +49 -4
- package/dist/src/data/sources/lazy/registerCoreLazySources.js +2 -0
- package/dist/src/data/sources/lazy/singleAxisWindowedSource.d.ts.map +1 -1
- package/dist/src/data/sources/lazy/singleAxisWindowedSource.js +3 -4
- package/dist/src/data/sources/lazy/tabixSource.d.ts +9 -4
- package/dist/src/data/sources/lazy/tabixSource.d.ts.map +1 -1
- package/dist/src/data/sources/lazy/tabixSource.js +201 -70
- package/dist/src/data/sources/lazy/tabixTsvSource.d.ts +2 -3
- package/dist/src/data/sources/lazy/tabixTsvSource.d.ts.map +1 -1
- package/dist/src/data/sources/lazy/tabixTsvSource.js +14 -12
- package/dist/src/data/sources/lazy/vcfSource.d.ts +7 -3
- package/dist/src/data/sources/lazy/vcfSource.d.ts.map +1 -1
- package/dist/src/data/sources/lazy/vcfSource.js +7 -8
- package/dist/src/data/sources/urlDescriptor.d.ts +165 -0
- package/dist/src/data/sources/urlDescriptor.d.ts.map +1 -0
- package/dist/src/data/sources/urlDescriptor.js +473 -0
- package/dist/src/data/sources/urlDescriptorController.d.ts +25 -0
- package/dist/src/data/sources/urlDescriptorController.d.ts.map +1 -0
- package/dist/src/data/sources/urlDescriptorController.js +72 -0
- package/dist/src/data/sources/urlDescriptorState.d.ts +47 -0
- package/dist/src/data/sources/urlDescriptorState.d.ts.map +1 -0
- package/dist/src/data/sources/urlDescriptorState.js +129 -0
- package/dist/src/data/sources/urlSource.d.ts.map +1 -1
- package/dist/src/data/sources/urlSource.js +101 -61
- package/dist/src/data/transforms/packLegendLabels.d.ts +21 -0
- package/dist/src/data/transforms/packLegendLabels.d.ts.map +1 -0
- package/dist/src/data/transforms/packLegendLabels.js +189 -0
- package/dist/src/data/transforms/transformFactory.d.ts.map +1 -1
- package/dist/src/data/transforms/transformFactory.js +4 -0
- package/dist/src/data/transforms/truncateText.d.ts +27 -0
- package/dist/src/data/transforms/truncateText.d.ts.map +1 -0
- package/dist/src/data/transforms/truncateText.js +94 -0
- package/dist/src/debug/dataflowDebugSnapshot.d.ts +58 -0
- package/dist/src/debug/dataflowDebugSnapshot.d.ts.map +1 -0
- package/dist/src/debug/dataflowDebugSnapshot.js +159 -0
- package/dist/src/debug/markDebugSnapshot.d.ts +54 -0
- package/dist/src/debug/markDebugSnapshot.d.ts.map +1 -0
- package/dist/src/debug/markDebugSnapshot.js +100 -0
- package/dist/src/debug/paramDebugSnapshot.d.ts +53 -0
- package/dist/src/debug/paramDebugSnapshot.d.ts.map +1 -0
- package/dist/src/debug/paramDebugSnapshot.js +86 -0
- package/dist/src/debug/resolutionDebugSnapshot.d.ts +155 -0
- package/dist/src/debug/resolutionDebugSnapshot.d.ts.map +1 -0
- package/dist/src/debug/resolutionDebugSnapshot.js +291 -0
- package/dist/src/debug/valuePreview.d.ts +9 -0
- package/dist/src/debug/valuePreview.d.ts.map +1 -0
- package/dist/src/debug/valuePreview.js +57 -0
- package/dist/src/debug/viewDebugSnapshot.d.ts +131 -0
- package/dist/src/debug/viewDebugSnapshot.d.ts.map +1 -0
- package/dist/src/debug/viewDebugSnapshot.js +390 -0
- package/dist/src/embedFactory.d.ts.map +1 -1
- package/dist/src/embedFactory.js +6 -1
- package/dist/src/encoder/encoder.d.ts +2 -2
- package/dist/src/encoder/encoder.d.ts.map +1 -1
- package/dist/src/encoder/encoder.js +5 -4
- package/dist/src/fonts/bmFontManager.d.ts +1 -1
- package/dist/src/fonts/bmFontManager.d.ts.map +1 -1
- package/dist/src/fonts/bmFontManager.js +45 -10
- package/dist/src/fonts/textMetrics.d.ts +69 -0
- package/dist/src/fonts/textMetrics.d.ts.map +1 -0
- package/dist/src/fonts/textMetrics.js +73 -0
- package/dist/src/genomeSpy/headlessBootstrap.d.ts.map +1 -1
- package/dist/src/genomeSpy/headlessBootstrap.js +6 -0
- package/dist/src/genomeSpy/renderCoordinator.d.ts.map +1 -1
- package/dist/src/genomeSpy/renderCoordinator.js +25 -3
- package/dist/src/genomeSpy/viewDataInit.d.ts +14 -0
- package/dist/src/genomeSpy/viewDataInit.d.ts.map +1 -1
- package/dist/src/genomeSpy/viewDataInit.js +45 -8
- package/dist/src/genomeSpyBase.d.ts +6 -0
- package/dist/src/genomeSpyBase.d.ts.map +1 -1
- package/dist/src/genomeSpyBase.js +20 -3
- package/dist/src/gl/glslScaleGenerator.d.ts +17 -0
- package/dist/src/gl/glslScaleGenerator.d.ts.map +1 -1
- package/dist/src/gl/glslScaleGenerator.js +39 -2
- package/dist/src/gl/includes/common.glsl.js +1 -1
- package/dist/src/gl/vertexRangeIndex.d.ts.map +1 -1
- package/dist/src/gl/vertexRangeIndex.js +4 -2
- package/dist/src/gl/webGLHelper.d.ts +1 -1
- package/dist/src/gl/webGLHelper.d.ts.map +1 -1
- package/dist/src/gl/webGLHelper.js +13 -8
- package/dist/src/marks/__snapshots__/shaderSnapshot.test.js.snap +140 -3
- package/dist/src/marks/mark.d.ts +47 -4
- package/dist/src/marks/mark.d.ts.map +1 -1
- package/dist/src/marks/mark.js +158 -54
- package/dist/src/marks/point.d.ts.map +1 -1
- package/dist/src/marks/point.js +4 -0
- package/dist/src/marks/point.vertex.glsl.js +1 -1
- package/dist/src/marks/text.d.ts +1 -1
- package/dist/src/marks/text.d.ts.map +1 -1
- package/dist/src/marks/text.js +2 -7
- package/dist/src/marks/text.vertex.glsl.js +1 -1
- package/dist/src/paramRuntime/paramUtils.d.ts +43 -9
- package/dist/src/paramRuntime/paramUtils.d.ts.map +1 -1
- package/dist/src/paramRuntime/paramUtils.js +61 -1
- package/dist/src/paramRuntime/viewParamRuntime.d.ts +32 -0
- package/dist/src/paramRuntime/viewParamRuntime.d.ts.map +1 -1
- package/dist/src/paramRuntime/viewParamRuntime.js +63 -0
- package/dist/src/scales/axisResolution.d.ts +35 -0
- package/dist/src/scales/axisResolution.d.ts.map +1 -1
- package/dist/src/scales/axisResolution.js +115 -7
- package/dist/src/scales/legendResolution.d.ts +83 -0
- package/dist/src/scales/legendResolution.d.ts.map +1 -0
- package/dist/src/scales/legendResolution.js +461 -0
- package/dist/src/scales/scaleResolution.d.ts +36 -0
- package/dist/src/scales/scaleResolution.d.ts.map +1 -1
- package/dist/src/scales/scaleResolution.js +59 -0
- package/dist/src/scales/viewLevelGuideConfig.d.ts +53 -0
- package/dist/src/scales/viewLevelGuideConfig.d.ts.map +1 -0
- package/dist/src/scales/viewLevelGuideConfig.js +224 -0
- package/dist/src/scales/viewLevelScaleConfig.d.ts.map +1 -1
- package/dist/src/scales/viewLevelScaleConfig.js +13 -2
- package/dist/src/spec/axis.d.ts +109 -3
- package/dist/src/spec/channel.d.ts +23 -4
- package/dist/src/spec/config.d.ts +59 -4
- package/dist/src/spec/data.d.ts +177 -17
- package/dist/src/spec/legend.d.ts +246 -0
- package/dist/src/spec/mark.d.ts +16 -4
- package/dist/src/spec/title.d.ts +58 -1
- package/dist/src/spec/transform.d.ts +149 -0
- package/dist/src/spec/view.d.ts +39 -6
- package/dist/src/types/embedApi.d.ts +262 -6
- package/dist/src/types/rendering.d.ts +19 -3
- package/dist/src/types/viewContext.d.ts +18 -2
- package/dist/src/utils/arrayUtils.d.ts +11 -0
- package/dist/src/utils/arrayUtils.d.ts.map +1 -1
- package/dist/src/utils/arrayUtils.js +23 -0
- package/dist/src/utils/suspension.d.ts +17 -0
- package/dist/src/utils/suspension.d.ts.map +1 -0
- package/dist/src/utils/suspension.js +41 -0
- package/dist/src/view/axisGridView.d.ts.map +1 -1
- package/dist/src/view/axisGridView.js +1 -4
- package/dist/src/view/axisView.d.ts +18 -2
- package/dist/src/view/axisView.d.ts.map +1 -1
- package/dist/src/view/axisView.js +180 -75
- package/dist/src/view/concatView.d.ts +10 -2
- package/dist/src/view/concatView.d.ts.map +1 -1
- package/dist/src/view/concatView.js +46 -9
- package/dist/src/view/containerMutationHelper.d.ts +20 -1
- package/dist/src/view/containerMutationHelper.d.ts.map +1 -1
- package/dist/src/view/containerMutationHelper.js +196 -33
- package/dist/src/view/facetView.d.ts +1 -1
- package/dist/src/view/gridView/gridChild.d.ts +54 -4
- package/dist/src/view/gridView/gridChild.d.ts.map +1 -1
- package/dist/src/view/gridView/gridChild.js +301 -120
- package/dist/src/view/gridView/gridChildLegends.d.ts +57 -0
- package/dist/src/view/gridView/gridChildLegends.d.ts.map +1 -0
- package/dist/src/view/gridView/gridChildLegends.js +503 -0
- package/dist/src/view/gridView/gridView.d.ts +25 -0
- package/dist/src/view/gridView/gridView.d.ts.map +1 -1
- package/dist/src/view/gridView/gridView.js +490 -78
- package/dist/src/view/gridView/legendLayout.d.ts +30 -0
- package/dist/src/view/gridView/legendLayout.d.ts.map +1 -0
- package/dist/src/view/gridView/legendLayout.js +115 -0
- package/dist/src/view/gridView/scrollbar.d.ts.map +1 -1
- package/dist/src/view/gridView/scrollbar.js +1 -4
- package/dist/src/view/gridView/selectionRect.d.ts.map +1 -1
- package/dist/src/view/gridView/selectionRect.js +1 -4
- package/dist/src/view/gridView/separatorView.d.ts.map +1 -1
- package/dist/src/view/gridView/separatorView.js +1 -4
- package/dist/src/view/layerView.d.ts +9 -2
- package/dist/src/view/layerView.d.ts.map +1 -1
- package/dist/src/view/layerView.js +18 -1
- package/dist/src/view/layout/flexLayout.d.ts +20 -4
- package/dist/src/view/layout/flexLayout.d.ts.map +1 -1
- package/dist/src/view/layout/flexLayout.js +331 -31
- package/dist/src/view/layout/rectangle.d.ts +14 -0
- package/dist/src/view/layout/rectangle.d.ts.map +1 -1
- package/dist/src/view/layout/rectangle.js +40 -0
- package/dist/src/view/legend/legendEntries.d.ts +20 -0
- package/dist/src/view/legend/legendEntries.d.ts.map +1 -0
- package/dist/src/view/legend/legendEntries.js +21 -0
- package/dist/src/view/legendView.d.ts +137 -0
- package/dist/src/view/legendView.d.ts.map +1 -0
- package/dist/src/view/legendView.js +1654 -0
- package/dist/src/view/renderingContext/bufferedViewRenderingContext.d.ts.map +1 -1
- package/dist/src/view/renderingContext/bufferedViewRenderingContext.js +26 -4
- package/dist/src/view/renderingContext/clipOptions.d.ts +44 -0
- package/dist/src/view/renderingContext/clipOptions.d.ts.map +1 -0
- package/dist/src/view/renderingContext/clipOptions.js +140 -0
- package/dist/src/view/renderingContext/simpleViewRenderingContext.d.ts.map +1 -1
- package/dist/src/view/renderingContext/simpleViewRenderingContext.js +12 -1
- package/dist/src/view/resolutionPlanner.d.ts +2 -1
- package/dist/src/view/resolutionPlanner.d.ts.map +1 -1
- package/dist/src/view/resolutionPlanner.js +89 -25
- package/dist/src/view/testUtils.d.ts +4 -2
- package/dist/src/view/testUtils.d.ts.map +1 -1
- package/dist/src/view/testUtils.js +60 -7
- package/dist/src/view/titleView.d.ts +37 -0
- package/dist/src/view/titleView.d.ts.map +1 -0
- package/dist/src/view/titleView.js +584 -0
- package/dist/src/view/unitView.d.ts +3 -3
- package/dist/src/view/unitView.d.ts.map +1 -1
- package/dist/src/view/unitView.js +3 -2
- package/dist/src/view/view.d.ts +25 -24
- package/dist/src/view/view.d.ts.map +1 -1
- package/dist/src/view/view.js +126 -16
- package/dist/src/view/viewChrome.d.ts +33 -0
- package/dist/src/view/viewChrome.d.ts.map +1 -0
- package/dist/src/view/viewChrome.js +64 -0
- package/dist/src/view/viewFactory.d.ts +2 -5
- package/dist/src/view/viewFactory.d.ts.map +1 -1
- package/dist/src/view/viewFactory.js +1 -2
- package/dist/src/view/viewIdentityRegistry.d.ts +37 -0
- package/dist/src/view/viewIdentityRegistry.d.ts.map +1 -0
- package/dist/src/view/viewIdentityRegistry.js +71 -0
- package/dist/src/view/viewMutationAcidTestUtils.d.ts +112 -0
- package/dist/src/view/viewMutationAcidTestUtils.d.ts.map +1 -0
- package/dist/src/view/viewMutationAcidTestUtils.js +234 -0
- package/dist/src/view/viewMutationApi.d.ts +42 -0
- package/dist/src/view/viewMutationApi.d.ts.map +1 -0
- package/dist/src/view/viewMutationApi.js +811 -0
- package/dist/src/view/viewSelectors.d.ts +11 -9
- package/dist/src/view/viewSelectors.d.ts.map +1 -1
- package/dist/src/view/viewSelectors.js +28 -17
- package/package.json +4 -4
- package/dist/bundle/esm-CuMSzCHy.js +0 -298
- package/dist/bundle/esm-DAnOffpD.js +0 -1426
- package/dist/bundle/esm-DMXpJXM4.js +0 -369
- package/dist/bundle/esm-DNtC3H80.js +0 -121
- package/dist/src/view/title.d.ts +0 -13
- package/dist/src/view/title.d.ts.map +0 -1
- package/dist/src/view/title.js +0 -154
- /package/dist/bundle/{AbortablePromiseCache-3gHJdF3E.js → AbortablePromiseCache-BTmAcN-t.js} +0 -0
- /package/dist/bundle/{esm-CuVa5T98.js → esm-VvpZ9hsq.js} +0 -0
- /package/dist/bundle/{chunk-DmhlhrBa.js → rolldown-runtime-Dy4uBu1J.js} +0 -0
|
@@ -0,0 +1,473 @@
|
|
|
1
|
+
// @ts-check
|
|
2
|
+
/**
|
|
3
|
+
* Utilities for turning the different URL source shapes accepted by the spec
|
|
4
|
+
* into a common descriptor array used by eager and lazy sources.
|
|
5
|
+
*
|
|
6
|
+
* A descriptor always has a concrete data URL and may also carry an index URL
|
|
7
|
+
* and fields that should be attached to every datum loaded from that URL. URL
|
|
8
|
+
* templates are intentionally resolved here, outside individual source
|
|
9
|
+
* implementations, so BigWig, Tabix, eager URL loading, and test sources share
|
|
10
|
+
* the same ExprRef evaluation, base URL resolution, deduplication, and
|
|
11
|
+
* descriptor-field conflict behavior.
|
|
12
|
+
*/
|
|
13
|
+
import { isExprRef, withoutExprRef } from "../../paramRuntime/paramUtils.js";
|
|
14
|
+
import { concatUrl } from "../../utils/url.js";
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* @typedef {import("../../spec/channel.js").Scalar} Scalar
|
|
18
|
+
* @typedef {import("../../spec/data.js").UrlSourceRef} UrlSourceRef
|
|
19
|
+
* @typedef {import("../../spec/data.js").SingleUrlSourceRef} SingleUrlSourceRef
|
|
20
|
+
* @typedef {import("../../spec/data.js").MultiUrlSourceRef} MultiUrlSourceRef
|
|
21
|
+
* @typedef {import("../../spec/data.js").IndexUrlSourceRef} IndexUrlSourceRef
|
|
22
|
+
* @typedef {import("../../spec/data.js").UrlTemplate} UrlTemplate
|
|
23
|
+
* @typedef {import("../../spec/data.js").IndexUrlTemplate} IndexUrlTemplate
|
|
24
|
+
* @typedef {import("../../spec/parameter.js").ExprRef} ExprRef
|
|
25
|
+
* @typedef {() => unknown} ExpressionFunction
|
|
26
|
+
* @typedef {ExpressionFunction & { subscribe?: (listener: () => void) => () => void }} SubscribableExpressionFunction
|
|
27
|
+
* @typedef {{
|
|
28
|
+
* createExpression: (expr: string) => SubscribableExpressionFunction,
|
|
29
|
+
* watchExpression?: (
|
|
30
|
+
* expr: string,
|
|
31
|
+
* listener: () => void,
|
|
32
|
+
* options?: {
|
|
33
|
+
* scopeOwned?: boolean,
|
|
34
|
+
* registerDisposer?: (disposer: () => void) => void
|
|
35
|
+
* }
|
|
36
|
+
* ) => SubscribableExpressionFunction,
|
|
37
|
+
* }} UrlExpressionRuntime
|
|
38
|
+
*/
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* @typedef {object} UrlDescriptor
|
|
42
|
+
* @prop {string} url
|
|
43
|
+
* @prop {string} [indexUrl]
|
|
44
|
+
* @prop {Record<string, Scalar>} [fields]
|
|
45
|
+
* @prop {"error" | "skip"} [onLoadError]
|
|
46
|
+
*/
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* @typedef {object} UrlDescriptorOptions
|
|
50
|
+
* @prop {UrlSourceRef | SingleUrlSourceRef | MultiUrlSourceRef | unknown} url
|
|
51
|
+
* @prop {IndexUrlSourceRef | unknown} [indexUrl]
|
|
52
|
+
* @prop {string} [baseUrl]
|
|
53
|
+
* @prop {UrlExpressionRuntime} [paramRuntime]
|
|
54
|
+
*/
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Thrown when URL expansion resolves more distinct descriptors than the spec
|
|
58
|
+
* allows. Sources may handle this as an intentional empty data state.
|
|
59
|
+
*/
|
|
60
|
+
export class UrlLimitExceededError extends Error {
|
|
61
|
+
/** @type {number} */
|
|
62
|
+
count;
|
|
63
|
+
|
|
64
|
+
/** @type {number} */
|
|
65
|
+
maxValues;
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* @param {number} count
|
|
69
|
+
* @param {number} maxValues
|
|
70
|
+
*/
|
|
71
|
+
constructor(count, maxValues) {
|
|
72
|
+
super(
|
|
73
|
+
`URL expansion resolved ${count} distinct values, exceeding maxValues ${maxValues}.`
|
|
74
|
+
);
|
|
75
|
+
this.name = "UrlLimitExceededError";
|
|
76
|
+
this.count = count;
|
|
77
|
+
this.maxValues = maxValues;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Expands a URL spec into concrete descriptors, resolves relative URLs against
|
|
83
|
+
* the view base URL, deduplicates the result, and enforces `maxValues`.
|
|
84
|
+
*
|
|
85
|
+
* @param {UrlDescriptorOptions} options
|
|
86
|
+
* @returns {Promise<UrlDescriptor[]>}
|
|
87
|
+
*/
|
|
88
|
+
export async function normalizeUrlDescriptors(options) {
|
|
89
|
+
const descriptors = expandUrl(options.url, options);
|
|
90
|
+
const resolved = descriptors.map((descriptor) => ({
|
|
91
|
+
...descriptor,
|
|
92
|
+
url: concatUrl(options.baseUrl, descriptor.url),
|
|
93
|
+
indexUrl: descriptor.indexUrl
|
|
94
|
+
? concatUrl(options.baseUrl, descriptor.indexUrl)
|
|
95
|
+
: undefined,
|
|
96
|
+
}));
|
|
97
|
+
|
|
98
|
+
return dedupeAndLimit(resolved, getMaxValues(options.url));
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Expands a URL spec that is expected to resolve to exactly one descriptor.
|
|
103
|
+
* Sources that still support only one remote file use this to fail before
|
|
104
|
+
* constructing file handles.
|
|
105
|
+
*
|
|
106
|
+
* @param {UrlDescriptorOptions} options
|
|
107
|
+
* @param {string} sourceName
|
|
108
|
+
* @returns {Promise<UrlDescriptor>}
|
|
109
|
+
*/
|
|
110
|
+
export async function normalizeSingleUrlDescriptor(options, sourceName) {
|
|
111
|
+
const descriptors = await normalizeUrlDescriptors(options);
|
|
112
|
+
if (descriptors.length !== 1) {
|
|
113
|
+
throw new Error(`${sourceName} supports exactly one resolved URL.`);
|
|
114
|
+
}
|
|
115
|
+
return descriptors[0];
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* Subscribes to expressions that affect URL expansion. Sources call this in
|
|
120
|
+
* addition to `activateExprRefProps` because template values are nested under
|
|
121
|
+
* `url.values` and therefore are not top-level data source properties.
|
|
122
|
+
*
|
|
123
|
+
* @param {{
|
|
124
|
+
* url: UrlSourceRef | SingleUrlSourceRef | MultiUrlSourceRef | unknown,
|
|
125
|
+
* indexUrl?: IndexUrlSourceRef | unknown,
|
|
126
|
+
* paramRuntime: UrlExpressionRuntime,
|
|
127
|
+
* listener: () => void,
|
|
128
|
+
* registerDisposer?: (disposer: () => void) => void,
|
|
129
|
+
* }} options
|
|
130
|
+
*/
|
|
131
|
+
export function watchUrlDescriptorExpressions(options) {
|
|
132
|
+
const expressions = collectUrlExpressions(options.url, options.indexUrl);
|
|
133
|
+
for (const expr of expressions) {
|
|
134
|
+
const fn = options.paramRuntime.watchExpression
|
|
135
|
+
? options.paramRuntime.watchExpression(expr, options.listener, {
|
|
136
|
+
scopeOwned: !options.registerDisposer,
|
|
137
|
+
registerDisposer: options.registerDisposer,
|
|
138
|
+
})
|
|
139
|
+
: options.paramRuntime.createExpression(expr);
|
|
140
|
+
if (!options.paramRuntime.watchExpression && fn.subscribe) {
|
|
141
|
+
const unsubscribe = fn.subscribe(options.listener);
|
|
142
|
+
options.registerDisposer?.(unsubscribe);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* Creates a mutating attacher for descriptor fields. Descriptor fields are
|
|
149
|
+
* source context from URL expansion, such as `{ sample: "S1" }`. Source-loaded
|
|
150
|
+
* datums are fresh objects, so mutating them avoids per-row cloning while still
|
|
151
|
+
* detecting ambiguous source metadata.
|
|
152
|
+
*
|
|
153
|
+
* @param {Record<string, Scalar>} [fields]
|
|
154
|
+
* @returns {(datum: Record<string, any>) => Record<string, any>}
|
|
155
|
+
*/
|
|
156
|
+
export function createDescriptorFieldAttacher(fields) {
|
|
157
|
+
if (!fields) {
|
|
158
|
+
return (datum) => datum;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
const entries = Object.entries(fields);
|
|
162
|
+
if (entries.length == 1) {
|
|
163
|
+
const [key, value] = entries[0];
|
|
164
|
+
return (datum) => {
|
|
165
|
+
if (key in datum && datum[key] !== value) {
|
|
166
|
+
throw new Error(
|
|
167
|
+
`Descriptor field "${key}" conflicts with loaded datum.`
|
|
168
|
+
);
|
|
169
|
+
}
|
|
170
|
+
datum[key] = value;
|
|
171
|
+
return datum;
|
|
172
|
+
};
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
return (datum) => {
|
|
176
|
+
for (const [key, value] of entries) {
|
|
177
|
+
if (key in datum && datum[key] !== value) {
|
|
178
|
+
throw new Error(
|
|
179
|
+
`Descriptor field "${key}" conflicts with loaded datum.`
|
|
180
|
+
);
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
for (const [key, value] of entries) {
|
|
185
|
+
datum[key] = value;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
return datum;
|
|
189
|
+
};
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
/**
|
|
193
|
+
* Attaches descriptor fields to a loaded datum.
|
|
194
|
+
*
|
|
195
|
+
* @template {Record<string, any>} T
|
|
196
|
+
* @param {T} datum
|
|
197
|
+
* @param {Record<string, Scalar>} [fields]
|
|
198
|
+
* @returns {T}
|
|
199
|
+
*/
|
|
200
|
+
export function attachDescriptorFields(datum, fields) {
|
|
201
|
+
return /** @type {T} */ (createDescriptorFieldAttacher(fields)(datum));
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
/**
|
|
205
|
+
* @template {Record<string, any>} T
|
|
206
|
+
* @param {T[]} data
|
|
207
|
+
* @param {Record<string, Scalar>} [fields]
|
|
208
|
+
* @returns {T[]}
|
|
209
|
+
*/
|
|
210
|
+
export function attachDescriptorFieldsToData(data, fields) {
|
|
211
|
+
if (!fields) {
|
|
212
|
+
return data;
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
const attach = createDescriptorFieldAttacher(fields);
|
|
216
|
+
for (let i = 0; i < data.length; i++) {
|
|
217
|
+
data[i] = /** @type {T} */ (attach(data[i]));
|
|
218
|
+
}
|
|
219
|
+
return data;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
/**
|
|
223
|
+
* Reports and classifies a failed expanded URL load. Missing partitions can be
|
|
224
|
+
* intentional in template-based sources, but strict failure remains the
|
|
225
|
+
* default behavior.
|
|
226
|
+
*
|
|
227
|
+
* @param {UrlDescriptor} descriptor
|
|
228
|
+
* @param {Error} error
|
|
229
|
+
* @returns {boolean}
|
|
230
|
+
*/
|
|
231
|
+
function shouldSkipUrlLoadError(descriptor, error) {
|
|
232
|
+
if (descriptor.onLoadError == "skip") {
|
|
233
|
+
console.warn(`Skipping failed URL: ${descriptor.url}`, error);
|
|
234
|
+
return true;
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
return false;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
/**
|
|
241
|
+
* Runs a per-descriptor load operation and converts configured failures into
|
|
242
|
+
* skipped results.
|
|
243
|
+
*
|
|
244
|
+
* @template T
|
|
245
|
+
* @param {UrlDescriptor} descriptor
|
|
246
|
+
* @param {() => Promise<T>} load
|
|
247
|
+
* @returns {Promise<T | undefined>}
|
|
248
|
+
*/
|
|
249
|
+
export async function loadUrlDescriptorOrSkip(descriptor, load) {
|
|
250
|
+
try {
|
|
251
|
+
return await load();
|
|
252
|
+
} catch (e) {
|
|
253
|
+
if (shouldSkipUrlLoadError(descriptor, e)) {
|
|
254
|
+
return undefined;
|
|
255
|
+
}
|
|
256
|
+
throw e;
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
/**
|
|
261
|
+
* Returns a stable key for comparing URL descriptors independently of their
|
|
262
|
+
* position in a descriptor array.
|
|
263
|
+
*
|
|
264
|
+
* @param {UrlDescriptor} descriptor
|
|
265
|
+
*/
|
|
266
|
+
export function urlDescriptorKey(descriptor) {
|
|
267
|
+
return JSON.stringify({
|
|
268
|
+
url: descriptor.url,
|
|
269
|
+
indexUrl: descriptor.indexUrl,
|
|
270
|
+
fields: descriptor.fields
|
|
271
|
+
? Object.fromEntries(Object.entries(descriptor.fields).sort())
|
|
272
|
+
: undefined,
|
|
273
|
+
});
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
/**
|
|
277
|
+
* @param {UrlSourceRef | SingleUrlSourceRef | MultiUrlSourceRef | unknown} urlSpec
|
|
278
|
+
* @param {UrlDescriptorOptions} options
|
|
279
|
+
* @returns {UrlDescriptor[]}
|
|
280
|
+
*/
|
|
281
|
+
function expandUrl(urlSpec, options) {
|
|
282
|
+
if (isUrlTemplate(urlSpec)) {
|
|
283
|
+
return expandTemplate(urlSpec, options.indexUrl, options);
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
const value = isExprRef(urlSpec)
|
|
287
|
+
? requireParamRuntime(options).createExpression(urlSpec.expr)()
|
|
288
|
+
: urlSpec;
|
|
289
|
+
const values = Array.isArray(value) ? value : [value];
|
|
290
|
+
return values.map(normalizeDescriptor);
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
/**
|
|
294
|
+
* Expands URL templates using a single scalar field. The optional index URL
|
|
295
|
+
* template deliberately reuses the data URL template's `values` and `field` so
|
|
296
|
+
* data/index pairs cannot drift apart.
|
|
297
|
+
*
|
|
298
|
+
* @param {UrlTemplate} templateSpec
|
|
299
|
+
* @param {IndexUrlSourceRef | unknown} indexUrlSpec
|
|
300
|
+
* @param {UrlDescriptorOptions} options
|
|
301
|
+
* @returns {UrlDescriptor[]}
|
|
302
|
+
*/
|
|
303
|
+
function expandTemplate(templateSpec, indexUrlSpec, options) {
|
|
304
|
+
const values = resolveValues(templateSpec.values, options);
|
|
305
|
+
if (!Array.isArray(values)) {
|
|
306
|
+
throw new Error("URL template values must resolve to an array.");
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
return values.map((value) => {
|
|
310
|
+
const scalar = assertScalar(value);
|
|
311
|
+
const fields =
|
|
312
|
+
templateSpec.attach === false
|
|
313
|
+
? undefined
|
|
314
|
+
: { [templateSpec.field]: scalar };
|
|
315
|
+
return {
|
|
316
|
+
url: fillTemplate(
|
|
317
|
+
templateSpec.template,
|
|
318
|
+
templateSpec.field,
|
|
319
|
+
scalar
|
|
320
|
+
),
|
|
321
|
+
indexUrl: isIndexTemplate(indexUrlSpec)
|
|
322
|
+
? fillTemplate(
|
|
323
|
+
indexUrlSpec.template,
|
|
324
|
+
templateSpec.field,
|
|
325
|
+
scalar
|
|
326
|
+
)
|
|
327
|
+
: /** @type {string | undefined} */ (
|
|
328
|
+
withoutExprRef(indexUrlSpec)
|
|
329
|
+
),
|
|
330
|
+
fields,
|
|
331
|
+
onLoadError: templateSpec.onLoadError,
|
|
332
|
+
};
|
|
333
|
+
});
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
/**
|
|
337
|
+
* @param {UrlTemplate["values"] | unknown} values
|
|
338
|
+
* @param {UrlDescriptorOptions} options
|
|
339
|
+
* @returns {unknown}
|
|
340
|
+
*/
|
|
341
|
+
function resolveValues(values, options) {
|
|
342
|
+
return isExprRef(values)
|
|
343
|
+
? requireParamRuntime(options).createExpression(values.expr)()
|
|
344
|
+
: values;
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
/**
|
|
348
|
+
* @param {unknown} value
|
|
349
|
+
* @returns {UrlDescriptor}
|
|
350
|
+
*/
|
|
351
|
+
function normalizeDescriptor(value) {
|
|
352
|
+
if (typeof value == "string") {
|
|
353
|
+
return { url: value };
|
|
354
|
+
}
|
|
355
|
+
if (
|
|
356
|
+
value &&
|
|
357
|
+
typeof value == "object" &&
|
|
358
|
+
"url" in value &&
|
|
359
|
+
typeof value.url == "string"
|
|
360
|
+
) {
|
|
361
|
+
return /** @type {UrlDescriptor} */ (value);
|
|
362
|
+
}
|
|
363
|
+
throw new Error("URL descriptor must be a string or an object with url.");
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
/**
|
|
367
|
+
* @param {string} template
|
|
368
|
+
* @param {string} field
|
|
369
|
+
* @param {Scalar} value
|
|
370
|
+
*/
|
|
371
|
+
function fillTemplate(template, field, value) {
|
|
372
|
+
const placeholder = "{" + field + "}";
|
|
373
|
+
if (!template.includes(placeholder)) {
|
|
374
|
+
throw new Error(`URL template must contain ${placeholder}.`);
|
|
375
|
+
}
|
|
376
|
+
return template.replaceAll(placeholder, encodeURIComponent(String(value)));
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
/**
|
|
380
|
+
* Deduplicates by the complete data/index URL pair. Different index URLs for
|
|
381
|
+
* the same data URL are preserved because they are distinct source
|
|
382
|
+
* descriptors.
|
|
383
|
+
*
|
|
384
|
+
* @param {UrlDescriptor[]} descriptors
|
|
385
|
+
* @param {number | undefined} maxValues
|
|
386
|
+
*/
|
|
387
|
+
function dedupeAndLimit(descriptors, maxValues) {
|
|
388
|
+
const byKey = new Map();
|
|
389
|
+
for (const descriptor of descriptors) {
|
|
390
|
+
const key = descriptor.url + "\n" + (descriptor.indexUrl ?? "");
|
|
391
|
+
if (!byKey.has(key)) {
|
|
392
|
+
byKey.set(key, descriptor);
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
const result = Array.from(byKey.values());
|
|
397
|
+
if (maxValues !== undefined && result.length > maxValues) {
|
|
398
|
+
throw new UrlLimitExceededError(result.length, maxValues);
|
|
399
|
+
}
|
|
400
|
+
return result;
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
/**
|
|
404
|
+
* @param {unknown} value
|
|
405
|
+
* @returns {Scalar}
|
|
406
|
+
*/
|
|
407
|
+
function assertScalar(value) {
|
|
408
|
+
if (
|
|
409
|
+
value == null ||
|
|
410
|
+
typeof value == "object" ||
|
|
411
|
+
typeof value == "function"
|
|
412
|
+
) {
|
|
413
|
+
throw new Error("URL template values must be scalar in this version.");
|
|
414
|
+
}
|
|
415
|
+
return /** @type {Scalar} */ (value);
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
/**
|
|
419
|
+
* @param {unknown} value
|
|
420
|
+
* @returns {value is UrlTemplate}
|
|
421
|
+
*/
|
|
422
|
+
function isUrlTemplate(value) {
|
|
423
|
+
return Boolean(value && typeof value == "object" && "template" in value);
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
/**
|
|
427
|
+
* @param {unknown} value
|
|
428
|
+
* @returns {value is IndexUrlTemplate}
|
|
429
|
+
*/
|
|
430
|
+
function isIndexTemplate(value) {
|
|
431
|
+
return Boolean(value && typeof value == "object" && "template" in value);
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
/**
|
|
435
|
+
* @param {UrlSourceRef | SingleUrlSourceRef | MultiUrlSourceRef | unknown} value
|
|
436
|
+
* @returns {number | undefined}
|
|
437
|
+
*/
|
|
438
|
+
function getMaxValues(value) {
|
|
439
|
+
return isUrlTemplate(value) ? value.maxValues : undefined;
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
/**
|
|
443
|
+
* @param {UrlDescriptorOptions} options
|
|
444
|
+
*/
|
|
445
|
+
function requireParamRuntime(options) {
|
|
446
|
+
if (!options.paramRuntime) {
|
|
447
|
+
throw new Error("URL ExprRef evaluation requires a parameter runtime.");
|
|
448
|
+
}
|
|
449
|
+
return options.paramRuntime;
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
/**
|
|
453
|
+
* URL expansion only watches expressions that can change the set of resolved
|
|
454
|
+
* descriptors. Expressions in other source properties are handled by the
|
|
455
|
+
* source-specific `activateExprRefProps` wiring.
|
|
456
|
+
*
|
|
457
|
+
* @param {UrlSourceRef | SingleUrlSourceRef | MultiUrlSourceRef | unknown} url
|
|
458
|
+
* @param {IndexUrlSourceRef | unknown} indexUrl
|
|
459
|
+
* @returns {string[]}
|
|
460
|
+
*/
|
|
461
|
+
function collectUrlExpressions(url, indexUrl) {
|
|
462
|
+
const expressions = [];
|
|
463
|
+
if (isExprRef(url)) {
|
|
464
|
+
expressions.push(url.expr);
|
|
465
|
+
}
|
|
466
|
+
if (isUrlTemplate(url) && isExprRef(url.values)) {
|
|
467
|
+
expressions.push(url.values.expr);
|
|
468
|
+
}
|
|
469
|
+
if (isExprRef(indexUrl)) {
|
|
470
|
+
expressions.push(indexUrl.expr);
|
|
471
|
+
}
|
|
472
|
+
return expressions;
|
|
473
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Small source-side wrapper for URL descriptor normalization and expression
|
|
3
|
+
* watching. It deliberately does not know how a source uses descriptors.
|
|
4
|
+
*/
|
|
5
|
+
export default class UrlDescriptorController {
|
|
6
|
+
/**
|
|
7
|
+
* @param {import("./dataSource.js").default} source
|
|
8
|
+
* @param {{
|
|
9
|
+
* getUrl: () => import("../../spec/data.js").UrlSourceRef | import("../../spec/data.js").SingleUrlSourceRef | import("../../spec/data.js").MultiUrlSourceRef | unknown,
|
|
10
|
+
* getIndexUrl?: () => import("../../spec/data.js").IndexUrlSourceRef | unknown,
|
|
11
|
+
* onChange: () => void,
|
|
12
|
+
* }} options
|
|
13
|
+
*/
|
|
14
|
+
constructor(source: import("./dataSource.js").default, options: {
|
|
15
|
+
getUrl: () => import("../../spec/data.js").UrlSourceRef | import("../../spec/data.js").SingleUrlSourceRef | import("../../spec/data.js").MultiUrlSourceRef | unknown;
|
|
16
|
+
getIndexUrl?: () => import("../../spec/data.js").IndexUrlSourceRef | unknown;
|
|
17
|
+
onChange: () => void;
|
|
18
|
+
});
|
|
19
|
+
/**
|
|
20
|
+
* @returns {Promise<import("./urlDescriptor.js").UrlDescriptor[]>}
|
|
21
|
+
*/
|
|
22
|
+
normalize(): Promise<import("./urlDescriptor.js").UrlDescriptor[]>;
|
|
23
|
+
#private;
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=urlDescriptorController.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"urlDescriptorController.d.ts","sourceRoot":"","sources":["../../../../src/data/sources/urlDescriptorController.js"],"names":[],"mappings":"AAMA;;;GAGG;AACH;IAUI;;;;;;;OAOG;IACH,oBAPW,OAAO,iBAAiB,EAAE,OAAO,WACjC;QACJ,MAAM,EAAE,MAAM,OAAO,oBAAoB,EAAE,YAAY,GAAG,OAAO,oBAAoB,EAAE,kBAAkB,GAAG,OAAO,oBAAoB,EAAE,iBAAiB,GAAG,OAAO,CAAC;QACrK,WAAW,CAAC,EAAE,MAAM,OAAO,oBAAoB,EAAE,iBAAiB,GAAG,OAAO,CAAC;QAC7E,QAAQ,EAAE,MAAM,IAAI,CAAC;KACxB,EAsBH;IAED;;OAEG;IACH,aAFa,OAAO,CAAC,OAAO,oBAAoB,EAAE,aAAa,EAAE,CAAC,CASjE;;CACJ"}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { isExprRef } from "../../paramRuntime/paramUtils.js";
|
|
2
|
+
import {
|
|
3
|
+
normalizeUrlDescriptors,
|
|
4
|
+
watchUrlDescriptorExpressions,
|
|
5
|
+
} from "./urlDescriptor.js";
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Small source-side wrapper for URL descriptor normalization and expression
|
|
9
|
+
* watching. It deliberately does not know how a source uses descriptors.
|
|
10
|
+
*/
|
|
11
|
+
export default class UrlDescriptorController {
|
|
12
|
+
/** @type {import("./dataSource.js").default} */
|
|
13
|
+
#source;
|
|
14
|
+
|
|
15
|
+
/** @type {() => import("../../spec/data.js").UrlSourceRef | import("../../spec/data.js").SingleUrlSourceRef | import("../../spec/data.js").MultiUrlSourceRef | unknown} */
|
|
16
|
+
#getUrl;
|
|
17
|
+
|
|
18
|
+
/** @type {(() => import("../../spec/data.js").IndexUrlSourceRef | unknown) | undefined} */
|
|
19
|
+
#getIndexUrl;
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* @param {import("./dataSource.js").default} source
|
|
23
|
+
* @param {{
|
|
24
|
+
* getUrl: () => import("../../spec/data.js").UrlSourceRef | import("../../spec/data.js").SingleUrlSourceRef | import("../../spec/data.js").MultiUrlSourceRef | unknown,
|
|
25
|
+
* getIndexUrl?: () => import("../../spec/data.js").IndexUrlSourceRef | unknown,
|
|
26
|
+
* onChange: () => void,
|
|
27
|
+
* }} options
|
|
28
|
+
*/
|
|
29
|
+
constructor(source, options) {
|
|
30
|
+
this.#source = source;
|
|
31
|
+
this.#getUrl = options.getUrl;
|
|
32
|
+
this.#getIndexUrl = options.getIndexUrl;
|
|
33
|
+
|
|
34
|
+
const url = this.#getUrl();
|
|
35
|
+
const indexUrl = this.#getIndexUrl?.();
|
|
36
|
+
if (
|
|
37
|
+
isWatchableDescriptorSpec(url) ||
|
|
38
|
+
isWatchableDescriptorSpec(indexUrl)
|
|
39
|
+
) {
|
|
40
|
+
watchUrlDescriptorExpressions({
|
|
41
|
+
url,
|
|
42
|
+
indexUrl,
|
|
43
|
+
paramRuntime: source.paramRuntime,
|
|
44
|
+
listener: options.onChange,
|
|
45
|
+
registerDisposer: (disposer) =>
|
|
46
|
+
source.registerDisposer(disposer),
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* @returns {Promise<import("./urlDescriptor.js").UrlDescriptor[]>}
|
|
53
|
+
*/
|
|
54
|
+
async normalize() {
|
|
55
|
+
return normalizeUrlDescriptors({
|
|
56
|
+
url: this.#getUrl(),
|
|
57
|
+
indexUrl: this.#getIndexUrl?.(),
|
|
58
|
+
baseUrl: this.#source.view.getBaseUrl(),
|
|
59
|
+
paramRuntime: this.#source.paramRuntime,
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Top-level ExprRefs are handled by activateExprRefProps. Descriptor
|
|
66
|
+
* controllers watch nested descriptor expressions, such as template values.
|
|
67
|
+
*
|
|
68
|
+
* @param {unknown} value
|
|
69
|
+
*/
|
|
70
|
+
function isWatchableDescriptorSpec(value) {
|
|
71
|
+
return Boolean(value && typeof value == "object" && !isExprRef(value));
|
|
72
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Updates descriptor-backed lazy-source handles using the shared multi-URL
|
|
3
|
+
* loading policy. Over-limit URL expansion is treated as an empty completed
|
|
4
|
+
* source so stale data is cleared without surfacing a runtime error.
|
|
5
|
+
*
|
|
6
|
+
* @template T
|
|
7
|
+
* @template M
|
|
8
|
+
* @param {{
|
|
9
|
+
* controller: { normalize: () => Promise<import("./urlDescriptor.js").UrlDescriptor[]> },
|
|
10
|
+
* state: UrlDescriptorState<T>,
|
|
11
|
+
* clearData: () => void,
|
|
12
|
+
* setLoadingStatus: (status: import("../../types/viewContext.js").DataLoadingStatus, detail?: string) => void,
|
|
13
|
+
* loadModules: () => Promise<M>,
|
|
14
|
+
* createHandle: (descriptor: import("./urlDescriptor.js").UrlDescriptor, modules: M) => Promise<T>,
|
|
15
|
+
* }} options
|
|
16
|
+
*/
|
|
17
|
+
export function updateUrlDescriptorState<T, M>(options: {
|
|
18
|
+
controller: {
|
|
19
|
+
normalize: () => Promise<import("./urlDescriptor.js").UrlDescriptor[]>;
|
|
20
|
+
};
|
|
21
|
+
state: UrlDescriptorState<T>;
|
|
22
|
+
clearData: () => void;
|
|
23
|
+
setLoadingStatus: (status: import("../../types/viewContext.js").DataLoadingStatus, detail?: string) => void;
|
|
24
|
+
loadModules: () => Promise<M>;
|
|
25
|
+
createHandle: (descriptor: import("./urlDescriptor.js").UrlDescriptor, modules: M) => Promise<T>;
|
|
26
|
+
}): Promise<void>;
|
|
27
|
+
/**
|
|
28
|
+
* Tracks active URL descriptors, descriptor-keyed handles, and the descriptor
|
|
29
|
+
* set covered by the last published data batch.
|
|
30
|
+
*
|
|
31
|
+
* @template T
|
|
32
|
+
*/
|
|
33
|
+
export default class UrlDescriptorState<T> {
|
|
34
|
+
get handles(): T[];
|
|
35
|
+
get activeSetLoaded(): boolean;
|
|
36
|
+
markLoaded(): void;
|
|
37
|
+
clearActive(): void;
|
|
38
|
+
/**
|
|
39
|
+
* Refreshes active descriptors while reusing cached handles.
|
|
40
|
+
*
|
|
41
|
+
* @param {import("./urlDescriptor.js").UrlDescriptor[]} descriptors
|
|
42
|
+
* @param {(descriptor: import("./urlDescriptor.js").UrlDescriptor, descriptorKey: string) => Promise<T | undefined>} createHandle
|
|
43
|
+
*/
|
|
44
|
+
update(descriptors: import("./urlDescriptor.js").UrlDescriptor[], createHandle: (descriptor: import("./urlDescriptor.js").UrlDescriptor, descriptorKey: string) => Promise<T | undefined>): Promise<void>;
|
|
45
|
+
#private;
|
|
46
|
+
}
|
|
47
|
+
//# sourceMappingURL=urlDescriptorState.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"urlDescriptorState.d.ts","sourceRoot":"","sources":["../../../../src/data/sources/urlDescriptorState.js"],"names":[],"mappings":"AA0FA;;;;;;;;;;;;;;;GAeG;AACH,yCAXa,CAAC,EACD,CAAC,WACH;IACJ,UAAU,EAAE;QAAE,SAAS,EAAE,MAAM,OAAO,CAAC,OAAO,oBAAoB,EAAE,aAAa,EAAE,CAAC,CAAA;KAAE,CAAC;IACvF,KAAK,EAAE,kBAAkB,CAAC,CAAC,CAAC,CAAC;IAC7B,SAAS,EAAE,MAAM,IAAI,CAAC;IACtB,gBAAgB,EAAE,CAAC,MAAM,EAAE,OAAO,4BAA4B,EAAE,iBAAiB,EAAE,MAAM,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IAC5G,WAAW,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,CAAC;IAC9B,YAAY,EAAE,CAAC,UAAU,EAAE,OAAO,oBAAoB,EAAE,aAAa,EAAE,OAAO,EAAE,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC,CAAC;CACpG,iBAwBH;AA1HD;;;;;GAKG;AACH,wCAFa,CAAC;IAeV,mBAEC;IAED,+BAEC;IAED,mBAEC;IAED,oBAIC;IAED;;;;;OAKG;IACH,oBAHW,OAAO,oBAAoB,EAAE,aAAa,EAAE,gBAC5C,CAAC,UAAU,EAAE,OAAO,oBAAoB,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,KAAK,OAAO,CAAC,CAAC,GAAG,SAAS,CAAC,iBAqBnH;;CAoBJ"}
|