prasi-bun/app/srv/ws/edit/action/diff-local.ts

139 lines
4.4 KiB
TypeScript

import { gzipAsync } from "../../sync/entity/zlib";
import { eg } from "../edit-global";
const history = {} as Record<string, string>;
export const diffLocal = (ws: any, msg: any) => {
return new Promise<void>((resolve) => {
const diff_local = Uint8Array.from(
msg.diff_local.split(",").map((x: any) => parseInt(x, 10))
);
let doc = null as unknown as Y.Doc;
let wss: Set<any> = null as any;
let um: Y.UndoManager = null as any;
if (msg.mode === "page") {
doc = eg.edit.page[msg.id].doc as any;
wss = eg.edit.page[msg.id].ws;
um = eg.edit.page[msg.id].undoManager;
} else if (msg.mode === "comp") {
doc = eg.edit.comp[msg.id].doc as any;
wss = eg.edit.comp[msg.id].ws;
um = eg.edit.comp[msg.id].undoManager;
} else if (msg.mode === "site") {
doc = eg.edit.site[msg.id].doc as any;
wss = eg.edit.site[msg.id].ws;
um = eg.edit.site[msg.id].undoManager;
}
if (doc && wss) {
Y.applyUpdate(doc, diff_local);
if (msg.mode === "page") {
clearTimeout(eg.edit.page[msg.id].saveTimeout);
eg.edit.page[msg.id].saveTimeout = setTimeout(async () => {
if (msg.id) {
const page = eg.edit.page[msg.id].doc.getMap("map").toJSON();
try {
const id = msg.id;
let mode = "create" as "create" | "update";
const cur = Math.round(Date.now() / 5000) + "";
if (history[id] && history[id] === cur) {
mode = "update";
}
history[id] = cur;
if (mode === "create") {
await _db.page_history.create({
data: {
id_page: id,
content_tree: await gzipAsync(
JSON.stringify(page.content_tree)
),
ts: history[id],
},
});
const res = await _db.page_history.findMany({
where: {
id_page: id,
},
select: {
id: true,
ts: true,
},
orderBy: {
ts: "desc",
},
});
const ids = [];
for (let i = 0; i < res.length; i++) {
if (i > 25) {
ids.push(res[i].id);
}
}
await _db.page_history.deleteMany({
where: { id: { in: ids } },
});
} else {
await _db.page_history.updateMany({
data: {
content_tree: await gzipAsync(
JSON.stringify(page.content_tree)
),
},
where: {
id_page: id,
ts: history[id],
},
});
}
await _db.page.update({
where: { id: page.id },
data: {
content_tree: page.content_tree,
updated_at: new Date(),
},
});
resolve();
} catch (e) {
console.error(e);
console.error({
...page,
updated_at: new Date(),
});
}
}
}, 1500);
} else if (msg.mode === "comp") {
clearTimeout(eg.edit.comp[msg.id].saveTimeout);
eg.edit.comp[msg.id].saveTimeout = setTimeout(async () => {
const comp = eg.edit.comp[msg.id].doc.getMap("map").toJSON();
await _db.component.update({
where: {
id: msg.id,
},
data: {
name: comp.name,
content_tree: comp.content_tree,
updated_at: new Date(),
},
});
}, 1500);
} else if (msg.mode === "site") {
clearTimeout(eg.edit.site[msg.id].saveTimeout);
eg.edit.site[msg.id].saveTimeout = setTimeout(async () => {
const site = eg.edit.site[msg.id].doc.getMap("site").toJSON();
delete site.page;
await _db.site.update({
where: {
id: msg.id,
},
data: {
...site,
},
});
}, 1500);
}
}
});
};