Files
mnote/wolai-frontend/src/app/api/mnote-web/stream/route.ts
T

122 lines
3.3 KiB
TypeScript
Raw Normal View History

import { getAuthedConvexClient } from "@/lib/convex/route";
import {
buildDocumentBridgeContext,
buildDocumentQueryEnvelope,
documentBridgeErrorResponse,
} from "@/lib/documents/bridge";
import {
executeRustBridgeQueryTransport,
resolveRustBridgeQueryPlan,
} from "@/lib/documents/rust-runtime";
import { mapSidebarDatasetListQueryResultToInitialData } from "@/lib/sidebar-data";
2026-04-24 06:10:18 +08:00
import {
attachKernelFileTreeProjection,
resolveKernelFileTreeProjection,
} from "@/lib/server/kernel-file-tree";
export const dynamic = "force-dynamic";
function toSseFrame(event: string, data: unknown) {
return `event: ${event}\ndata: ${JSON.stringify(data ?? null)}\n\n`;
}
export async function GET(request: Request) {
try {
const requestUrl = new URL(request.url);
const workspaceId = String(requestUrl.searchParams.get("workspaceId") || "").trim();
const cursor = String(requestUrl.searchParams.get("cursor") || "").trim() || null;
if (!workspaceId) {
return Response.json({ error: "缺少 workspaceId" }, { status: 400 });
}
2026-04-24 06:10:18 +08:00
const { auth, client } = await getAuthedConvexClient();
const context = await buildDocumentBridgeContext({
request,
workspaceId,
});
const sidebarEnvelope = buildDocumentQueryEnvelope({
name: "sidebar.dataset.list",
payload: {
workspaceId,
},
});
const sidebarPlan = await resolveRustBridgeQueryPlan({
context,
envelope: sidebarEnvelope,
});
const sidebarDataset = await executeRustBridgeQueryTransport({
client,
plan: sidebarPlan,
});
2026-04-24 06:10:18 +08:00
const sidebarDatasetWithFileTree = attachKernelFileTreeProjection({
dataset: sidebarDataset,
projection: await resolveKernelFileTreeProjection({
client,
request,
workspaceId,
actor: {
actorType: "user",
actorId: auth.userId,
sessionId: null,
},
dataset: sidebarDataset,
}),
});
const overviewEnvelope = buildDocumentQueryEnvelope({
name: "bridge.workspace.overview",
payload: {
workspaceId,
limit: 20,
cursor,
commandStatus: null,
eventStatus: null,
targetPageId: null,
targetBlockId: null,
aggregateType: null,
aggregateId: null,
},
});
const overviewPlan = await resolveRustBridgeQueryPlan({
context,
envelope: overviewEnvelope,
});
const overview = await executeRustBridgeQueryTransport({
client,
plan: overviewPlan,
});
const payload = {
kind: "snapshot",
stream: "workspace",
projection: "sidebar_tree",
workspaceId,
rootNodeId: null,
cursor,
requestId: context.requestId,
traceId: context.traceId,
2026-04-24 06:10:18 +08:00
data: mapSidebarDatasetListQueryResultToInitialData(sidebarDatasetWithFileTree),
snapshot: {
2026-04-24 06:10:18 +08:00
dataset: sidebarDatasetWithFileTree,
tree:
sidebarDatasetWithFileTree.kernel_sidebar_projection ??
sidebarDatasetWithFileTree.kernelSidebarProjection ??
null,
},
overview,
};
return new Response(toSseFrame("snapshot", payload), {
status: 200,
headers: {
"content-type": "text/event-stream; charset=utf-8",
"cache-control": "no-store",
},
});
} catch (error) {
return documentBridgeErrorResponse(error);
}
}