Skip to content

Commit

Permalink
fix: Invalid cache update after multiple deletion
Browse files Browse the repository at this point in the history
  • Loading branch information
miyanokomiya committed Oct 8, 2024
1 parent 1e90553 commit be6e07b
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 1 deletion.
17 changes: 17 additions & 0 deletions src/stores/core/entities.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -110,9 +110,26 @@ describe("newEntityStore", () => {
const store = newEntityStore({ name: "test", ydoc });
store.addEntity({ id: "a", findex: "0" });
store.addEntity({ id: "b", findex: "1" });
store.getEntities();
store.deleteEntities(["a"]);
expect(store.getEntities()).toEqual([{ id: "b", findex: "1" }]);
});

test("should remove multiple entities: complex deletion order", () => {
const ydoc = new Y.Doc();
const store = newEntityStore({ name: "test", ydoc });
store.addEntity({ id: "a", findex: "0" });
store.addEntity({ id: "b", findex: "1" });
store.addEntity({ id: "c", findex: "2" });
store.addEntity({ id: "d", findex: "3" });
store.addEntity({ id: "e", findex: "4" });
store.getEntities();
store.deleteEntities(["e", "b", "d"]);
expect(store.getEntities()).toEqual([
{ id: "a", findex: "0" },
{ id: "c", findex: "2" },
]);
});
});

describe("patchEntity", () => {
Expand Down
16 changes: 15 additions & 1 deletion src/stores/core/entities.ts
Original file line number Diff line number Diff line change
Expand Up @@ -244,19 +244,33 @@ function newEntityListCache<T extends Entity>(entityMap: Y.Map<Y.Map<any>>) {
if (dirtyKeyMap.size === 0) return;

const indexMap = new Map<string, number>();
const targetInOrder = new Set<string>();
let shift = 0;

// Check concurrent entities in order.
entityListCache.forEach((entity, i) => {
const v = dirtyKeyMap!.get(entity.id);
if (!v) return;

targetInOrder.add(entity.id);
indexMap.set(entity.id, i + shift);
if (v.action === "delete") {
shift--;
}
});

// Check new entities.
for (const [id] of dirtyKeyMap) {
if (!targetInOrder.has(id)) {
targetInOrder.add(id);
}
}

entityListCache = entityListCache.concat();
for (const [id, v] of dirtyKeyMap) {
for (const id of targetInOrder) {
const v = dirtyKeyMap.get(id);
if (!v) continue;

switch (v.action) {
case "add":
case "update":
Expand Down

0 comments on commit be6e07b

Please sign in to comment.