feat: continue tree rust family cutover

- add rust renderer/state-family scaffolds and inline compat host thinning for page tree, file tree, and picker
- route tree/filetree preflight, file projection, resource artifact, and stream delta contracts through rust plans
- preserve canonical move-order validation, file-tree search projection, and related frontend/runtime regression coverage
This commit is contained in:
lix-2026
2026-04-26 19:35:52 +08:00
parent 338bb2e20f
commit e564dfde02
93 changed files with 17492 additions and 1856 deletions
@@ -266,6 +266,458 @@ describe("tree-stream/server", () => {
expect(loadSnapshot).toHaveBeenCalledTimes(2);
});
it("单条新 domain event 携带 streamDelta 时,应直接发 delta", async () => {
const loadOverview = vi
.fn()
.mockResolvedValueOnce({
command_logs: [],
domain_events: [
{
event_id: "evt_1",
created_at: "2026-04-24T00:00:01Z",
},
],
has_more: false,
next_cursor: null,
generated_at: "2026-04-24T00:00:01Z",
})
.mockResolvedValueOnce({
command_logs: [],
domain_events: [
{
event_id: "evt_2",
created_at: "2026-04-24T00:00:02Z",
payload: {
command_name: "tree.node.rename",
streamDelta: {
op: "upsert_document",
document: {
id: "page_2",
title: "新标题",
},
},
},
},
{
event_id: "evt_1",
created_at: "2026-04-24T00:00:01Z",
},
],
has_more: false,
next_cursor: null,
generated_at: "2026-04-24T00:00:02Z",
});
const loadSnapshot = vi.fn().mockResolvedValue({
requestId: "req_1",
traceId: "trace_1",
data: { activeWorkspaceId: "ws_1", documents: [{ id: "page_1" }] },
snapshot: { dataset: { active_workspace_id: "ws_1", documents: [{ id: "page_1" }] }, tree: { items: [] } },
});
const frames = await collectFrames(
streamTreeFrames({
workspaceId: "ws_1",
pollMs: 1,
maxPolls: 1,
loadOverview,
loadSnapshot,
sleep: vi.fn().mockResolvedValue(undefined),
}),
);
expect(frames).toHaveLength(2);
expect(frames[1]).toMatchObject({
event: "delta",
payload: {
kind: "delta",
cursor: JSON.stringify({
createdAt: "2026-04-24T00:00:02Z",
id: "domain_event:evt_2",
}),
data: {
op: "upsert_document",
document: {
id: "page_2",
title: "新标题",
},
},
},
});
expect(loadSnapshot).toHaveBeenCalledTimes(1);
});
it("单条资源 domain event 携带 upsert_assets 时,应直接发 delta", async () => {
const streamDelta = {
op: "upsert_assets",
upsertAssets: [
{
id: "asset_1",
workspace_id: "ws_1",
document_id: "doc_target",
asset_type: "file",
file_url: "/file.pdf",
thumbnail_url: "/file.pdf",
file_name: "file.pdf",
file_size: 1024,
mime_type: "application/pdf",
created_at: "2026-04-26T00:00:00Z",
updated_at: "2026-04-26T00:00:00Z",
},
],
};
const loadOverview = vi
.fn()
.mockResolvedValueOnce({
command_logs: [],
domain_events: [
{
event_id: "evt_1",
created_at: "2026-04-24T00:00:01Z",
},
],
has_more: false,
next_cursor: null,
generated_at: "2026-04-24T00:00:01Z",
})
.mockResolvedValueOnce({
command_logs: [],
domain_events: [
{
event_id: "evt_2",
created_at: "2026-04-24T00:00:02Z",
payload: {
schema: "mnote.tree.domain_event",
eventType: "tree.resource.moved",
streamDelta,
},
},
{
event_id: "evt_1",
created_at: "2026-04-24T00:00:01Z",
},
],
has_more: false,
next_cursor: null,
generated_at: "2026-04-24T00:00:02Z",
});
const loadSnapshot = vi.fn().mockResolvedValue({
requestId: "req_1",
traceId: "trace_1",
data: { activeWorkspaceId: "ws_1", documents: [{ id: "page_1" }] },
snapshot: { dataset: { active_workspace_id: "ws_1", documents: [{ id: "page_1" }] }, tree: { items: [] } },
});
const frames = await collectFrames(
streamTreeFrames({
workspaceId: "ws_1",
pollMs: 1,
maxPolls: 1,
loadOverview,
loadSnapshot,
sleep: vi.fn().mockResolvedValue(undefined),
}),
);
expect(frames).toHaveLength(2);
expect(frames[1]).toMatchObject({
event: "delta",
payload: {
kind: "delta",
data: streamDelta,
},
});
expect(loadSnapshot).toHaveBeenCalledTimes(1);
});
it("单条新 domain event 缺少可识别 streamDelta 时,应保守回退 resync", async () => {
const loadOverview = vi
.fn()
.mockResolvedValueOnce({
command_logs: [],
domain_events: [
{
event_id: "evt_1",
created_at: "2026-04-24T00:00:01Z",
},
],
has_more: false,
next_cursor: null,
generated_at: "2026-04-24T00:00:01Z",
})
.mockResolvedValueOnce({
command_logs: [],
domain_events: [
{
event_id: "evt_2",
created_at: "2026-04-24T00:00:02Z",
payload: {
schema: "mnote.tree.domain_event",
schemaVersion: 1,
eventType: "tree.node.unknown",
},
},
{
event_id: "evt_1",
created_at: "2026-04-24T00:00:01Z",
},
],
has_more: false,
next_cursor: null,
generated_at: "2026-04-24T00:00:02Z",
});
const loadSnapshot = vi
.fn()
.mockResolvedValueOnce({
requestId: "req_1",
traceId: "trace_1",
data: { activeWorkspaceId: "ws_1", documents: [{ id: "page_1" }] },
snapshot: { dataset: { active_workspace_id: "ws_1", documents: [{ id: "page_1" }] }, tree: { items: [] } },
})
.mockResolvedValueOnce({
requestId: "req_2",
traceId: "trace_2",
data: { activeWorkspaceId: "ws_1", documents: [{ id: "page_2" }] },
snapshot: { dataset: { active_workspace_id: "ws_1", documents: [{ id: "page_2" }] }, tree: { items: [] } },
});
const frames = await collectFrames(
streamTreeFrames({
workspaceId: "ws_1",
pollMs: 1,
maxPolls: 1,
loadOverview,
loadSnapshot,
sleep: vi.fn().mockResolvedValue(undefined),
}),
);
expect(frames).toHaveLength(2);
expect(frames[1]).toMatchObject({
event: "resync",
payload: {
kind: "resync",
cursor: JSON.stringify({
createdAt: "2026-04-24T00:00:02Z",
id: "domain_event:evt_2",
}),
},
});
expect(loadSnapshot).toHaveBeenCalledTimes(2);
});
it("同一命令的 command log 与 domain event 同时推进且 delta 一致时,应发一次 delta", async () => {
const streamDelta = {
op: "upsert_document",
document: { id: "page_2", title: "同一标题" },
};
const loadOverview = vi
.fn()
.mockResolvedValueOnce(
buildOverview([{ id: "clog_1", command_id: "cmd_1", created_at: "2026-04-24T00:00:01Z" }]),
)
.mockResolvedValueOnce({
command_logs: [
{
id: "clog_2",
command_id: "cmd_2",
created_at: "2026-04-24T00:00:02Z",
command_name: "tree.node.rename",
payload: { streamDelta },
},
{ id: "clog_1", command_id: "cmd_1", created_at: "2026-04-24T00:00:01Z" },
],
domain_events: [
{
event_id: "evt_2",
command_id: "cmd_2",
created_at: "2026-04-24T00:00:02Z",
payload: { streamDelta },
},
],
has_more: false,
next_cursor: null,
generated_at: "2026-04-24T00:00:02Z",
});
const loadSnapshot = vi.fn().mockResolvedValue({
requestId: "req_1",
traceId: "trace_1",
data: { activeWorkspaceId: "ws_1", documents: [{ id: "page_1" }] },
snapshot: { dataset: { active_workspace_id: "ws_1", documents: [{ id: "page_1" }] }, tree: { items: [] } },
});
const frames = await collectFrames(
streamTreeFrames({
workspaceId: "ws_1",
pollMs: 1,
maxPolls: 1,
loadOverview,
loadSnapshot,
sleep: vi.fn().mockResolvedValue(undefined),
}),
);
expect(frames).toHaveLength(2);
expect(frames[1]).toMatchObject({
event: "delta",
payload: {
kind: "delta",
cursor: JSON.stringify({
createdAt: "2026-04-24T00:00:02Z",
id: "clog_2",
}),
data: streamDelta,
},
});
expect(loadSnapshot).toHaveBeenCalledTimes(1);
});
it("上一帧 cursor 来自 command log 时,应按时间排除旧 domain event 后再做双写去重", async () => {
const streamDelta = {
op: "move_document",
documentId: "page_2",
parentId: "page_1",
sortOrder: 2,
};
const loadOverview = vi
.fn()
.mockResolvedValueOnce(
buildOverview([{ id: "clog_1", command_id: "cmd_1", created_at: "2026-04-24T00:00:01Z" }]),
)
.mockResolvedValueOnce({
command_logs: [
{
id: "clog_2",
command_id: "cmd_2",
created_at: "2026-04-24T00:00:02Z",
command_name: "tree.subtree.move",
payload: { streamDelta },
},
{ id: "clog_1", command_id: "cmd_1", created_at: "2026-04-24T00:00:01Z" },
],
domain_events: [
{
event_id: "evt_2",
command_id: "cmd_2",
created_at: "2026-04-24T00:00:02Z",
payload: { streamDelta },
},
{
event_id: "evt_1",
command_id: "cmd_1",
created_at: "2026-04-24T00:00:01Z",
payload: {
streamDelta: {
op: "noop",
},
},
},
],
has_more: false,
next_cursor: null,
generated_at: "2026-04-24T00:00:02Z",
});
const loadSnapshot = vi.fn().mockResolvedValue({
requestId: "req_1",
traceId: "trace_1",
data: { activeWorkspaceId: "ws_1", documents: [{ id: "page_1" }] },
snapshot: { dataset: { active_workspace_id: "ws_1", documents: [{ id: "page_1" }] }, tree: { items: [] } },
});
const frames = await collectFrames(
streamTreeFrames({
workspaceId: "ws_1",
pollMs: 1,
maxPolls: 1,
loadOverview,
loadSnapshot,
sleep: vi.fn().mockResolvedValue(undefined),
}),
);
expect(frames).toHaveLength(2);
expect(frames[1]).toMatchObject({
event: "delta",
payload: {
kind: "delta",
data: streamDelta,
},
});
expect(loadSnapshot).toHaveBeenCalledTimes(1);
});
it("command log 与 domain event 同时推进且 delta 不一致时,应回退 resync 避免漏发", async () => {
const loadOverview = vi
.fn()
.mockResolvedValueOnce(
buildOverview([{ id: "clog_1", created_at: "2026-04-24T00:00:01Z" }]),
)
.mockResolvedValueOnce({
command_logs: [
{
id: "clog_2",
created_at: "2026-04-24T00:00:03Z",
command_name: "tree.node.rename",
payload: {
streamDelta: {
op: "upsert_document",
document: { id: "page_2", title: "命令标题" },
},
},
},
{ id: "clog_1", created_at: "2026-04-24T00:00:01Z" },
],
domain_events: [
{
event_id: "evt_2",
created_at: "2026-04-24T00:00:02Z",
payload: {
streamDelta: {
op: "remove_document",
documentId: "page_3",
},
},
},
],
has_more: false,
next_cursor: null,
generated_at: "2026-04-24T00:00:03Z",
});
const loadSnapshot = vi
.fn()
.mockResolvedValueOnce({
requestId: "req_1",
traceId: "trace_1",
data: { activeWorkspaceId: "ws_1", documents: [{ id: "page_1" }] },
snapshot: { dataset: { active_workspace_id: "ws_1", documents: [{ id: "page_1" }] }, tree: { items: [] } },
})
.mockResolvedValueOnce({
requestId: "req_2",
traceId: "trace_2",
data: { activeWorkspaceId: "ws_1", documents: [{ id: "page_2" }] },
snapshot: { dataset: { active_workspace_id: "ws_1", documents: [{ id: "page_2" }] }, tree: { items: [] } },
});
const frames = await collectFrames(
streamTreeFrames({
workspaceId: "ws_1",
pollMs: 1,
maxPolls: 1,
loadOverview,
loadSnapshot,
sleep: vi.fn().mockResolvedValue(undefined),
}),
);
expect(frames).toHaveLength(2);
expect(frames[1]).toMatchObject({
event: "resync",
payload: {
kind: "resync",
},
});
expect(loadSnapshot).toHaveBeenCalledTimes(2);
});
it("单条新命令缺少可稳定解释的 streamDelta 时,应回退 resync", async () => {
const loadOverview = vi
.fn()
@@ -374,7 +826,7 @@ describe("tree-stream/server", () => {
expect(loadSnapshot).toHaveBeenCalledTimes(1);
});
it("move 这类附带 replace_documents 的新命令应直接发 delta,而不是触发 resync", async () => {
it("move 这类附带 move_document 的新命令应直接发 delta,而不是触发 resync", async () => {
const sidebarSnapshot = {
activeWorkspaceId: "ws_1",
workspaces: [],
@@ -428,8 +880,11 @@ describe("tree-stream/server", () => {
payload: {
documentId: "page_1",
streamDelta: {
op: "replace_documents",
documents: sidebarSnapshot.documents,
op: "move_document",
documentId: "page_1",
parentId: null,
sortOrder: 0,
updatedAt: "2026-04-24T00:01:00Z",
},
},
},
@@ -460,12 +915,82 @@ describe("tree-stream/server", () => {
payload: {
kind: "delta",
data: {
op: "replace_documents",
documents: expect.arrayContaining([
op: "move_document",
documentId: "page_1",
parentId: null,
sortOrder: 0,
updatedAt: "2026-04-24T00:01:00Z",
},
},
});
expect(loadSnapshot).toHaveBeenCalledTimes(1);
});
it("copy 这类附带 upsert_documents 的新命令应保留批量文档字段", async () => {
const loadOverview = vi
.fn()
.mockResolvedValueOnce(
buildOverview([{ id: "clog_1", created_at: "2026-04-24T00:00:01Z" }]),
)
.mockResolvedValueOnce(
buildOverview([
{
id: "clog_2",
created_at: "2026-04-24T00:00:02Z",
command_name: "tree.subtree.copy",
payload: {
streamDelta: {
op: "upsert_documents",
upsertDocuments: [
{
id: "copy_1",
workspace_id: "ws_1",
title: "Copy",
parent_id: null,
sort_order: 2,
is_starred: false,
access_scope: "private",
is_template: false,
created_at: "2026-04-24T00:00:02Z",
updated_at: "2026-04-24T00:00:02Z",
},
],
},
},
},
{ id: "clog_1", created_at: "2026-04-24T00:00:01Z" },
]),
);
const loadSnapshot = vi.fn().mockResolvedValue({
requestId: "req_1",
traceId: "trace_1",
data: { activeWorkspaceId: "ws_1", documents: [] },
snapshot: { dataset: { active_workspace_id: "ws_1", documents: [] }, tree: { items: [] } },
});
const frames = await collectFrames(
streamTreeFrames({
workspaceId: "ws_1",
pollMs: 1,
maxPolls: 1,
loadOverview,
loadSnapshot,
sleep: vi.fn().mockResolvedValue(undefined),
}),
);
expect(frames[1]).toMatchObject({
event: "delta",
payload: {
kind: "delta",
data: {
op: "upsert_documents",
upsertDocuments: [
expect.objectContaining({
id: "page_1",
id: "copy_1",
workspace_id: "ws_1",
}),
]),
],
},
},
});