import { randomUUID } from "crypto"; import type { ConvexHttpClient } from "convex/browser"; import type { FunctionReference } from "convex/server"; import type { SidebarInitialData } from "@/components/sidebar/types"; import type { DocumentRecord } from "@/lib/documents"; import { api } from "@/lib/convex/api"; import { mapSidebarDatasetListQueryResultToInitialData, type SidebarDatasetListQueryResult, } from "@/lib/sidebar-data"; import type { WorkspaceSummary } from "@/lib/workspaces"; type LoadSidebarDataFromConvexInput = { client: ConvexHttpClient; fallbackName: string; requestedWorkspaceId?: string | null; }; type LoadSidebarDataFromConvexResult = { workspaces: WorkspaceSummary[]; activeWorkspaceId: string; targetWorkspaceId: string | null; sidebarDataset: SidebarDatasetListQueryResult | null; sidebarInitialData: SidebarInitialData | null; documents: DocumentRecord[]; }; const sidebarDatasetListQuery = ((api as unknown as Record).sidebar as | Record | undefined)?.datasetList as FunctionReference< "query", "public", { workspaceId: string }, SidebarDatasetListQueryResult >; export async function loadSidebarDataFromConvex( input: LoadSidebarDataFromConvexInput, ): Promise { const bootstrap = await input.client.mutation(api.workspaces.ensureDefaultWorkspace, { fallbackName: input.fallbackName, workspaceIdIfCreate: randomUUID(), }); const workspaces = bootstrap.workspaces; const activeWorkspaceId = bootstrap.activeWorkspaceId; const targetWorkspaceId = input.requestedWorkspaceId?.trim() || activeWorkspaceId || null; if (!targetWorkspaceId) { return { workspaces, activeWorkspaceId, targetWorkspaceId: null, sidebarDataset: null, sidebarInitialData: null, documents: [], }; } // 说明:SSR 首屏阶段必须优先保证“可进入页面”。 // mnote-web compat sidebar 仍处于渐进接入期,若这里优先走远端/Rust 兼容接口, // 一旦 actor/header 权限链不一致,就会把整个 (app) layout 阻塞住,表现为“登录后进不去页面”。 // 因此服务端首屏一律先走稳定的 Convex 直查;mnote-web 仅允许用于客户端树壳渐进增强。 const sidebarDataset = (await input.client.query(sidebarDatasetListQuery, { workspaceId: targetWorkspaceId, })) as SidebarDatasetListQueryResult; const normalizedDocuments = (sidebarDataset.documents ?? []) as DocumentRecord[]; return { workspaces: sidebarDataset.workspaces ?? workspaces, activeWorkspaceId, targetWorkspaceId, sidebarDataset, sidebarInitialData: mapSidebarDatasetListQueryResultToInitialData(sidebarDataset), documents: normalizedDocuments, }; }