Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { MultiFileDiff } from "@pierre/diffs/react";
import { toast } from "@superset/ui/sonner";
import { workspaceTrpc } from "@superset/workspace-client";
import { useQuery } from "@tanstack/react-query";
import { memo, useMemo } from "react";
import { useCopyToClipboard } from "renderer/hooks/useCopyToClipboard";
import { electronTrpc } from "renderer/lib/electron-trpc";
import { electronTrpcClient } from "renderer/lib/trpc-client";
import {
getDiffsTheme,
Expand Down Expand Up @@ -47,10 +47,11 @@ export const WorkspaceDiff = memo(function WorkspaceDiff({
onOpenFile,
}: WorkspaceDiffProps) {
const activeTheme = useResolvedTheme();
const { data: fontSettings } = electronTrpc.settings.getFontSettings.useQuery(
undefined,
{ staleTime: 30_000 },
);
const { data: fontSettings } = useQuery({
queryKey: ["electron", "settings", "getFontSettings"],
Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai Bot Apr 13, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: Cache invalidation is broken for these vanilla useQuery calls. The queryKey here (["electron", "settings", "getFontSettings"]) doesn't match the tRPC-generated key structure ([["settings", "getFontSettings"], { input: undefined, type: "query" }]), so when FontSettingSection calls utils.settings.getFontSettings.invalidate() after saving, it won't invalidate these entries. Users will see stale font settings for up to 30 s (the staleTime) after changing them.

Two options:

  1. Use getQueryKey from @trpc/react-query to derive the exact tRPC key and pass it here, so the existing invalidate() covers these entries automatically.
  2. Add a matching queryClient.invalidateQueries({ queryKey: ["electron", "settings", "getFontSettings"] }) in FontSettingSection's onSettled callback alongside the existing utils call.

The same issue applies to WorkspaceDiff.tsx and CodeEditor.tsx.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At apps/desktop/src/renderer/routes/_authenticated/_dashboard/v2-workspace/$workspaceId/hooks/usePaneRegistry/components/DiffPane/components/WorkspaceDiff/WorkspaceDiff.tsx, line 55:

<comment>Cache invalidation is broken for these vanilla `useQuery` calls. The `queryKey` here (`["electron", "settings", "getFontSettings"]`) doesn't match the tRPC-generated key structure (`[["settings", "getFontSettings"], { input: undefined, type: "query" }]`), so when `FontSettingSection` calls `utils.settings.getFontSettings.invalidate()` after saving, it won't invalidate these entries. Users will see stale font settings for up to 30 s (the `staleTime`) after changing them.

Two options:
1. Use `getQueryKey` from `@trpc/react-query` to derive the exact tRPC key and pass it here, so the existing `invalidate()` covers these entries automatically.
2. Add a matching `queryClient.invalidateQueries({ queryKey: ["electron", "settings", "getFontSettings"] })` in `FontSettingSection`'s `onSettled` callback alongside the existing `utils` call.

The same issue applies to `WorkspaceDiff.tsx` and `CodeEditor.tsx`.</comment>

<file context>
@@ -47,10 +47,15 @@ export const WorkspaceDiff = memo(function WorkspaceDiff({
+	// singleton — nesting workspaceTrpc.Provider overrides it and silently
+	// routes electronTrpc hooks through the host-service HTTP link.
+	const { data: fontSettings } = useQuery({
+		queryKey: ["electron", "settings", "getFontSettings"],
+		queryFn: () => electronTrpcClient.settings.getFontSettings.query(),
+		staleTime: 30_000,
</file context>
Fix with Cubic

queryFn: () => electronTrpcClient.settings.getFontSettings.query(),
staleTime: 30_000,
});
const shikiTheme = getDiffsTheme(activeTheme);
const parsedEditorFontSize =
typeof fontSettings?.editorFontSize === "number"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,23 +1,23 @@
import { useQuery } from "@tanstack/react-query";
import { useMemo } from "react";
import { electronTrpc } from "renderer/lib/electron-trpc";
import {
DEFAULT_TERMINAL_FONT_FAMILY,
DEFAULT_TERMINAL_FONT_SIZE,
getDefaultTerminalAppearance,
type TerminalAppearance,
} from "renderer/lib/terminal/appearance";
import { electronTrpcClient } from "renderer/lib/trpc-client";
import { useTerminalTheme } from "renderer/stores/theme";

const fallbackTheme = getDefaultTerminalAppearance().theme;

export function useTerminalAppearance(): TerminalAppearance {
const terminalTheme = useTerminalTheme();
const { data: fontSettings } = electronTrpc.settings.getFontSettings.useQuery(
undefined,
{
staleTime: 30_000,
},
);
const { data: fontSettings } = useQuery({
queryKey: ["electron", "settings", "getFontSettings"],
queryFn: () => electronTrpcClient.settings.getFontSettings.query(),
staleTime: 30_000,
});
Comment on lines +16 to +20
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Cache key divergence breaks reactivity when font settings change

The new queryKey: ["electron", "settings", "getFontSettings"] is a plain React Query key that does not match the internal key that @trpc/react-query generates for electronTrpc.settings.getFontSettings.useQuery(). tRPC generates a nested key structure like [["settings", "getFontSettings"], { input: undefined, type: "query" }].

FontSettingSection.tsx calls utils.settings.getFontSettings.invalidate() in its mutation's onSettled callback. That call targets only the tRPC-managed cache entry — it will not reach the vanilla useQuery entries in this hook, WorkspaceDiff, or CodeEditor. After a user saves new font settings, these three components will continue displaying the old values until the 30 s staleTime expires and a natural refetch fires (e.g. window focus or remount).

The same issue exists in WorkspaceDiff.tsx and CodeEditor.tsx.

One way to close the gap without restructuring provider wiring: add a matching queryClient.invalidateQueries call in FontSettingSection's onSettled alongside the existing utils call:

queryClient.invalidateQueries({ queryKey: ["electron", "settings", "getFontSettings"] });

Alternatively, use getQueryKey (exported from @trpc/react-query) to derive the exact tRPC-generated key and supply it to these vanilla useQuery calls, so that utils.settings.getFontSettings.invalidate() covers them automatically.


return useMemo(() => {
const theme = terminalTheme ?? fallbackTheme;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,9 @@ import {
lineNumbers,
} from "@codemirror/view";
import { cn } from "@superset/ui/utils";
import { useQuery } from "@tanstack/react-query";
import { type MutableRefObject, useEffect, useRef } from "react";
import { electronTrpc } from "renderer/lib/electron-trpc";
import { electronTrpcClient } from "renderer/lib/trpc-client";
import type { CodeEditorAdapter } from "renderer/screens/main/components/WorkspaceView/ContentView/components";
import { getCodeSyntaxHighlighting } from "renderer/screens/main/components/WorkspaceView/utils/code-theme";
import { useResolvedTheme } from "renderer/stores/theme";
Expand Down Expand Up @@ -179,12 +180,11 @@ export function CodeEditor({
const onSaveRef = useRef(onSave);
// Guards against re-entrant onChange calls triggered by the value-sync effect's own dispatch.
const isExternalUpdateRef = useRef(false);
const { data: fontSettings } = electronTrpc.settings.getFontSettings.useQuery(
undefined,
{
staleTime: 30_000,
},
);
const { data: fontSettings } = useQuery({
queryKey: ["electron", "settings", "getFontSettings"],
queryFn: () => electronTrpcClient.settings.getFontSettings.query(),
staleTime: 30_000,
});
const editorFontFamily = fontSettings?.editorFontFamily ?? undefined;
const editorFontSize = fontSettings?.editorFontSize ?? undefined;
const activeTheme = useResolvedTheme();
Expand Down
Loading