refactor(canvas): extract sync engine hook
This commit is contained in:
77
components/canvas/__tests__/use-canvas-sync-engine.test.ts
Normal file
77
components/canvas/__tests__/use-canvas-sync-engine.test.ts
Normal file
@@ -0,0 +1,77 @@
|
||||
import { describe, expect, it, vi } from "vitest";
|
||||
|
||||
import type { Id } from "@/convex/_generated/dataModel";
|
||||
import { createCanvasSyncEngineController } from "@/components/canvas/use-canvas-sync-engine";
|
||||
|
||||
const asCanvasId = (id: string): Id<"canvases"> => id as Id<"canvases">;
|
||||
const asNodeId = (id: string): Id<"nodes"> => id as Id<"nodes">;
|
||||
describe("useCanvasSyncEngine", () => {
|
||||
it("hands off an optimistic create to the real node id before replaying a deferred move", async () => {
|
||||
const enqueueSyncMutation = vi.fn(async () => undefined);
|
||||
const runBatchRemoveNodes = vi.fn(async () => undefined);
|
||||
const runSplitEdgeAtExistingNode = vi.fn(async () => undefined);
|
||||
|
||||
const controller = createCanvasSyncEngineController({
|
||||
canvasId: asCanvasId("canvas-1"),
|
||||
isSyncOnline: true,
|
||||
enqueueSyncMutation,
|
||||
runBatchRemoveNodes,
|
||||
runSplitEdgeAtExistingNode,
|
||||
});
|
||||
|
||||
controller.pendingMoveAfterCreateRef.current.set("req-1", {
|
||||
positionX: 320,
|
||||
positionY: 180,
|
||||
});
|
||||
|
||||
await controller.syncPendingMoveForClientRequest("req-1", asNodeId("node-real"));
|
||||
|
||||
expect(enqueueSyncMutation).toHaveBeenCalledWith("moveNode", {
|
||||
nodeId: asNodeId("node-real"),
|
||||
positionX: 320,
|
||||
positionY: 180,
|
||||
});
|
||||
expect(
|
||||
controller.pendingLocalPositionUntilConvexMatchesRef.current.get("node-real"),
|
||||
).toEqual({ x: 320, y: 180 });
|
||||
expect(controller.resolvedRealIdByClientRequestRef.current.get("req-1")).toBe(
|
||||
asNodeId("node-real"),
|
||||
);
|
||||
expect(controller.pendingMoveAfterCreateRef.current.has("req-1")).toBe(false);
|
||||
expect(runBatchRemoveNodes).not.toHaveBeenCalled();
|
||||
expect(runSplitEdgeAtExistingNode).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("defers resize and data updates for an optimistic node until the real id is known", async () => {
|
||||
const enqueueSyncMutation = vi.fn(async () => undefined);
|
||||
|
||||
const controller = createCanvasSyncEngineController({
|
||||
canvasId: asCanvasId("canvas-1"),
|
||||
isSyncOnline: true,
|
||||
enqueueSyncMutation,
|
||||
runBatchRemoveNodes: vi.fn(async () => undefined),
|
||||
runSplitEdgeAtExistingNode: vi.fn(async () => undefined),
|
||||
});
|
||||
|
||||
await controller.queueNodeResize({
|
||||
nodeId: asNodeId("optimistic_req-2"),
|
||||
width: 640,
|
||||
height: 360,
|
||||
});
|
||||
await controller.queueNodeDataUpdate({
|
||||
nodeId: asNodeId("optimistic_req-2"),
|
||||
data: { label: "Updated" },
|
||||
});
|
||||
|
||||
expect(enqueueSyncMutation).not.toHaveBeenCalled();
|
||||
|
||||
await controller.syncPendingMoveForClientRequest("req-2", asNodeId("node-2"));
|
||||
|
||||
expect(enqueueSyncMutation.mock.calls).toEqual([
|
||||
["resizeNode", { nodeId: asNodeId("node-2"), width: 640, height: 360 }],
|
||||
["updateData", { nodeId: asNodeId("node-2"), data: { label: "Updated" } }],
|
||||
]);
|
||||
expect(controller.pendingResizeAfterCreateRef.current.has("req-2")).toBe(false);
|
||||
expect(controller.pendingDataAfterCreateRef.current.has("req-2")).toBe(false);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user