diff --git a/web-common/src/features/canvas/components/markdown/util.spec.ts b/web-common/src/features/canvas/components/markdown/util.spec.ts new file mode 100644 index 000000000000..0dff6a12cedf --- /dev/null +++ b/web-common/src/features/canvas/components/markdown/util.spec.ts @@ -0,0 +1,52 @@ +import type { MarkdownCanvasComponent } from "@rilldata/web-common/features/canvas/components/markdown"; +import { getResolveTemplatedStringQueryOptions } from "@rilldata/web-common/features/canvas/components/markdown/util"; +import type { V1Expression } from "@rilldata/web-common/runtime-client"; +import { RuntimeClient } from "@rilldata/web-common/runtime-client/v2"; +import { writable } from "svelte/store"; +import { describe, expect, it } from "vitest"; + +describe("getResolveTemplatedStringQueryOptions", () => { + it("Should release the parent spec once unsubscribed, however often the filters changed", () => { + const exprByMetricsView = writable>({}); + + // Counts the live subscriptions to the parent canvas spec. + let parentSpecSubscribers = 0; + const parentSpec = writable({ data: { metricsViews: {} } }); + const parentSpecStore = { + subscribe: (run: (value: unknown) => void) => { + parentSpecSubscribers++; + const unsubscribe = parentSpec.subscribe(run); + return () => { + parentSpecSubscribers--; + unsubscribe(); + }; + }, + }; + + const component = { + specStore: writable({ content: "{{ metrics_sql 'select 1' }}" }), + timeAndFilterStore: writable({ timeRange: undefined }), + parent: { + specStore: parentSpecStore, + expressionFilterManager: { + exprByMetricsViewStore: exprByMetricsView, + }, + timeManager: { hasTimeSeriesStore: writable(false) }, + }, + } as unknown as MarkdownCanvasComponent; + + const optionsStore = getResolveTemplatedStringQueryOptions( + component, + new RuntimeClient({ host: "http://localhost", instanceId: "test" }), + ); + + const unsubscribe = optionsStore.subscribe(() => {}); + // Every filter change re-runs the outer derived, which builds a new inner one. + exprByMetricsView.set({ mv: { ident: "a" } }); + exprByMetricsView.set({ mv: { ident: "b" } }); + expect(parentSpecSubscribers).toBe(1); + + unsubscribe(); + expect(parentSpecSubscribers).toBe(0); + }); +}); diff --git a/web-common/src/features/canvas/components/markdown/util.ts b/web-common/src/features/canvas/components/markdown/util.ts index 0bb22347f512..832924f2ccaf 100644 --- a/web-common/src/features/canvas/components/markdown/util.ts +++ b/web-common/src/features/canvas/components/markdown/util.ts @@ -127,7 +127,7 @@ export function getResolveTemplatedStringQueryOptions( return derived( [component.parent.expressionFilterManager.exprByMetricsViewStore], ([exprByMetricsView], set) => { - derived( + return derived( [ component.specStore, component.timeAndFilterStore, diff --git a/web-common/src/features/dashboards/time-series/totals-data-store.ts b/web-common/src/features/dashboards/time-series/totals-data-store.ts index 0b677d741908..531b3d2c460e 100644 --- a/web-common/src/features/dashboards/time-series/totals-data-store.ts +++ b/web-common/src/features/dashboards/time-series/totals-data-store.ts @@ -58,7 +58,7 @@ export function createUnfilteredTotalsForMeasure( const updatedFilter = getFiltersForOtherDimensions(filter, dimensionName); - createQueryServiceMetricsViewAggregation( + return createQueryServiceMetricsViewAggregation( ctx.runtimeClient, { metricsView: metricsViewName, diff --git a/web-common/src/features/models/selectors.ts b/web-common/src/features/models/selectors.ts index b58dd37fd71d..ceec98488691 100644 --- a/web-common/src/features/models/selectors.ts +++ b/web-common/src/features/models/selectors.ts @@ -36,7 +36,7 @@ export function useAllModelColumns( return; } - derived( + return derived( allModels.data.map((r) => createTableColumnsWithName( queryClient, diff --git a/web-common/src/features/sources/selectors.ts b/web-common/src/features/sources/selectors.ts index 7469e7016120..33a27b3de36f 100644 --- a/web-common/src/features/sources/selectors.ts +++ b/web-common/src/features/sources/selectors.ts @@ -84,7 +84,7 @@ export function useAllSourceColumns( return; } - derived( + return derived( allSources.data.map((r) => createTableColumnsWithName( queryClient,