fix(source): open pending tab while loading object source

This commit is contained in:
Abeautifulsnow authored and GitHub committed 2026-09-14 19:59:21 +08:00
1 parent eba6853480
commit 760d2c6409
14 files changed
+824 -149

No files matched your search

@@ -62,6 +62,20 @@ describe("openTabsPersistence originalSql round-trip", () => {
expect(restored.objectSource).toBeUndefined();
});
it("does not persist a pending object-source tab without its in-flight request", () => {
const pending = queryTab({
id: "pending-source",
title: "Source - v_orders",
sourceView: true,
sourceLoad: {
startedAt: Date.now(),
request: { name: "v_orders", objectType: "VIEW" },
},
});
expect(serializeOpenTabs([pending])).toEqual([]);
});
it("keeps legacy query tabs without source intent compatible", () => {
const [restored] = roundTrip([queryTab({ sql: "SELECT 1" })]);
expect(restored.sourceView).toBeUndefined();
@@ -104,6 +104,13 @@ function shouldPersistTabSql(tab: QueryTab) {
return tab.originalSql !== undefined && tab.sql !== tab.originalSql;
}
// Pending object-source tabs are transient work surfaces. Persisting one while
// its request is in flight would restore an empty source tab after restart,
// because the request itself is intentionally not durable.
function shouldPersistOpenTab(tab: QueryTab): boolean {
return !tab.sourceLoad;
}
function restoredOriginalSql(tab: SavedOpenTab, mode: QueryTab["mode"], sql: string) {
if (mode !== "query") return undefined;
if (tab.externalSqlPath) return tab.originalSql ?? sql;
@@ -149,7 +156,7 @@ function restoredTabUiState(tab: SavedOpenTab): QueryTab["uiState"] {
}
export function serializeOpenTabs(tabs: QueryTab[]): SavedOpenTab[] {
return tabs.map((tab) => ({
return tabs.filter(shouldPersistOpenTab).map((tab) => ({
id: tab.id,
...(typeof tab.createdAt === "number" ? { createdAt: tab.createdAt } : {}),
title: tab.title,
@@ -259,6 +266,9 @@ function restoreOpenTabsArray(parsed: unknown, rawActiveTabId: string | null, op
redisMonitorActive: false,
isCancelling: false,
queryExecutionStartedAt: undefined,
// sourceLoad 是纯运行期态(serializeOpenTabs 不落盘)。这里显式清空,
// 让「恢复后的 tab 不会停在加载中」成为不变量,而不是依赖白名单的副作用。
sourceLoad: undefined,
executingResultRunId: undefined,
editorViewport: restoredEditorViewport(tab),
editorSelection: restoredEditorSelection(tab, typeof tab.sql === "string" ? tab.sql.length : 0),