reduce api | version control

This commit is contained in:
taDuc
2026-04-19 00:13:22 +07:00
parent c88a6497f7
commit bc98830871
9 changed files with 1141 additions and 449 deletions

View File

@@ -55,11 +55,17 @@ function geometryEquals(a: Geometry | undefined, b: Geometry | undefined): boole
return JSON.stringify(a) === JSON.stringify(b);
}
function featureEquals(a: Feature | undefined, b: Feature | undefined): boolean {
if (!a || !b) return false;
return JSON.stringify(a.geometry) === JSON.stringify(b.geometry) &&
JSON.stringify(a.properties) === JSON.stringify(b.properties);
}
// Tạo baseline map id -> geometry từ dữ liệu đã lưu.
function buildInitialMap(fc: FeatureCollection) {
const map = new Map<FeatureProperties["id"], Geometry>();
const map = new Map<FeatureProperties["id"], Feature>();
for (const f of fc.features) {
map.set(f.properties.id, deepClone(f.geometry));
map.set(f.properties.id, deepClone(f));
}
return map;
}
@@ -67,7 +73,7 @@ function buildInitialMap(fc: FeatureCollection) {
// Tính diff giữa draft hiện tại và baseline để sinh payload thay đổi.
function diffDraftToInitial(
draft: FeatureCollection,
initialMap: Map<FeatureProperties["id"], Geometry>
initialMap: Map<FeatureProperties["id"], Feature>
) {
const next = new Map<FeatureProperties["id"], Change>();
@@ -78,10 +84,10 @@ function diffDraftToInitial(
for (const f of draft.features) {
const id = f.properties.id;
seen.add(id);
const initialGeom = initialMap.get(id);
if (!initialGeom) {
const initialFeature = initialMap.get(id);
if (!initialFeature) {
next.set(id, { action: "create", feature: deepClone(f) });
} else if (!geometryEquals(initialGeom, f.geometry)) {
} else if (!featureEquals(initialFeature, f)) {
next.set(id, { action: "update", id, geometry: deepClone(f.geometry) });
}
}
@@ -133,7 +139,7 @@ export function useEditorState(initialData: FeatureCollection) {
const [undoStack, setUndoStack] = useState<UndoAction[]>([]);
// baseline to know what is "saved" state
const initialMapRef = useRef<Map<FeatureProperties["id"], Geometry>>(
const initialMapRef = useRef<Map<FeatureProperties["id"], Feature>>(
buildInitialMap(initialData)
);
const draftRef = useRef<FeatureCollection>(deepClone(initialData));