This commit is contained in:
Rizky 2024-01-11 13:24:56 +07:00
parent 8717951270
commit 5522b5fa33
5 changed files with 111 additions and 48 deletions

View File

@ -95,7 +95,7 @@ export const SyncActions = {
({}) as Record<string, { id: string; username: string }>, ({}) as Record<string, { id: string; username: string }>,
}, },
code: { code: {
load: async (id: string, type: "src" | "built") => load: async (id: string, type: "src" | "build") =>
({}) as { ({}) as {
id: string; id: string;
snapshot: null | Uint8Array; snapshot: null | Uint8Array;

View File

@ -1,41 +1,20 @@
import { dir } from "dir";
import { g } from "utils/global";
import { DCode } from "../../../../web/src/utils/types/root";
import { readDirectoryRecursively } from "../../../api/site-export";
import { SAction } from "../actions"; import { SAction } from "../actions";
import { docs } from "../entity/docs"; import { getCode, prepDCode } from "../editor/code/prep-code";
import { SyncConnection } from "../type"; import { SyncConnection } from "../type";
import { getCode } from "../editor/code/prep-code";
export const code_load: SAction["code"]["load"] = async function ( export const code_load: SAction["code"]["load"] = async function (
this: SyncConnection, this: SyncConnection,
site_id, site_id,
type type
) { ) {
let result = null as unknown as Awaited<ReturnType<SAction["code"]["load"]>>;
const code = await getCode(site_id, "site"); const code = await getCode(site_id, "site");
if (code) { if (code) {
if (!docs.code[site_id]) { const prep = await prepDCode(site_id);
docs.code[site_id] = { if (prep) {
id: site_id, return { id: site_id, snapshot: prep.bin[type] };
src: loadFolderAsDCode(dir.path(`${g.datadir}/site/code/${code.id}`)),
build: loadFolderAsDCode(
dir.path(`${g.datadir}/site/build/${code.id}`)
),
};
} }
return result;
} }
return { id: site_id, snapshot: null }; return { id: site_id, snapshot: null };
}; };
const loadFolderAsDCode = (path: string) => {
const doc = new Y.Doc() as DCode;
const dirs = readDirectoryRecursively(path);
return doc;
};

View File

@ -23,19 +23,19 @@ export const yjs_diff_local: SAction["yjs"]["diff_local"] = async function (
const root = doc.getMap("map").get("root") as any; const root = doc.getMap("map").get("root") as any;
if (root) { if (root) {
if (mode === "page") { if (mode === "page") {
await db.page.update({ // await db.page.update({
where: { id }, // where: { id },
data: { // data: {
content_tree: root.toJSON(), // content_tree: root.toJSON(),
}, // },
}); // });
} else if (mode === "comp") { } else if (mode === "comp") {
await db.component.update({ // await db.component.update({
where: { id }, // where: { id },
data: { // data: {
content_tree: root.toJSON(), // content_tree: root.toJSON(),
}, // },
}); // });
} }
} }
} }

View File

@ -1,6 +1,12 @@
import { dir } from "dir"; import { dir } from "dir";
import { dirAsync } from "fs-jetpack"; import { dirAsync } from "fs-jetpack";
import { g } from "utils/global"; import { g } from "utils/global";
import { Doc } from "yjs";
import { DCode } from "../../../../../web/src/utils/types/root";
import { readDirectoryRecursively } from "../../../../api/site-export";
import { docs } from "../../entity/docs";
import { existsAsync } from "fs-jetpack";
import { snapshot } from "../../entity/snapshot";
export type DBCode = Exclude<Awaited<ReturnType<typeof getCode>>, null>; export type DBCode = Exclude<Awaited<ReturnType<typeof getCode>>, null>;
export const prepCode = async (site_id: string, name: string) => { export const prepCode = async (site_id: string, name: string) => {
@ -26,6 +32,8 @@ export const prepCode = async (site_id: string, name: string) => {
if (code) { if (code) {
await dirAsync(dir.path(`${g.datadir}/site/code/${site_id}/${code.id}`)); await dirAsync(dir.path(`${g.datadir}/site/code/${site_id}/${code.id}`));
await prepDCode(site_id);
return code; return code;
} }
let new_code = await db.code.create({ let new_code = await db.code.create({
@ -62,6 +70,8 @@ export const hello_world = () => {
code = await getCode(site_id); code = await getCode(site_id);
await prepDCode(site_id);
return code as DBCode; return code as DBCode;
}; };
@ -80,3 +90,73 @@ export const getCode = async (site_id: string, name?: string) => {
}, },
}); });
}; };
export const prepDCode = async (site_id: string) => {
let exists = false;
if (!docs.code[site_id]) {
const code = await getCode(site_id, "site");
if (code) {
const path = {
src: dir.path(`${g.datadir}/site/code/${site_id}/${code.id}`),
build: dir.path(`${g.datadir}/site/build/${code.id}`),
};
if ((await existsAsync(path.src)) && (await existsAsync(path.build))) {
docs.code[site_id] = {
id: site_id,
src: loadFolderAsDCode(code.id, path.src),
build: loadFolderAsDCode(code.id, path.build),
};
exists = true;
}
}
}
if (exists) {
const src_bin = Y.encodeStateAsUpdate(docs.code[site_id].src as Doc);
const build_bin = Y.encodeStateAsUpdate(docs.code[site_id].build as Doc);
let snap = await snapshot.getOrCreate({
type: "site",
id: site_id,
name: "",
src: {
bin: src_bin,
id_doc: docs.code[site_id].src.clientID,
},
build: {
bin: build_bin,
id_doc: docs.code[site_id].build.clientID,
},
});
if (snap && snap.type === "site") {
return {
bin: {
src: snap.src.bin,
build: snap.build.bin,
},
};
}
}
};
const loadFolderAsDCode = (id: string, path: string) => {
const doc = new Y.Doc() as DCode;
const map = doc.getMap("map");
const files = new Y.Map();
const dirs = readDirectoryRecursively(path);
for (const [k, v] of Object.entries(dirs)) {
files.set(k, new Y.Text(v));
}
doc.transact(() => {
map.set("files", files as any);
map.set("id", id);
});
return doc;
};

View File

@ -32,10 +32,9 @@ type PageSnapshot = {
type SiteSnapshot = { type SiteSnapshot = {
type: "site"; type: "site";
id: string; id: string;
id_doc: number;
name: string; name: string;
src_bin: Uint8Array; src: { bin: Uint8Array; id_doc: number };
build_bin: Uint8Array; build: { bin: Uint8Array; id_doc: number };
}; };
type DocSnapshotMap = { type DocSnapshotMap = {
@ -45,10 +44,10 @@ type DocSnapshotMap = {
"": EmptySnapshot; "": EmptySnapshot;
}; };
export type DocSnapshot = export type DocSnapshot =
| EmptySnapshot
| CompSnapshot
| PageSnapshot | PageSnapshot
| SiteSnapshot; | SiteSnapshot
| CompSnapshot
| EmptySnapshot;
const emptySnapshot: DocSnapshot = { const emptySnapshot: DocSnapshot = {
type: "", type: "",
@ -69,12 +68,14 @@ export const snapshot = {
}); });
return this._db; return this._db;
}, },
get db() { get db() {
if (!this._db) { if (!this._db) {
this._db = this.init(); this._db = this.init();
} }
return this._db; return this._db;
}, },
async getOrCreate(data: DocSnapshot) { async getOrCreate(data: DocSnapshot) {
const id = `${data.type}-${data.id}`; const id = `${data.type}-${data.id}`;
let res = this.db.get(id); let res = this.db.get(id);
@ -84,19 +85,22 @@ export const snapshot = {
} }
return res as DocSnapshot; return res as DocSnapshot;
}, },
get<K extends DocSnapshot["type"]>(type: K, id: string) { get<K extends DocSnapshot["type"]>(type: K, id: string) {
return this.db.get(`${type}-${id}`) as DocSnapshotMap[K] | null; return this.db.get(`${type}-${id}`) as DocSnapshotMap[K] | null;
}, },
async update(data: DocSnapshot) { async update(data: DocSnapshot) {
const id = `${data.type}-${data.id}`; const id = `${data.type}-${data.id}`;
await this.db.put(id, data); await this.db.put(id, data);
return true; return true;
}, },
async set<T extends keyof DocSnapshot>(
type: keyof DocSnapshotMap, async set<K extends keyof DocSnapshotMap, T extends keyof DocSnapshotMap[K]>(
type: K,
id: string, id: string,
key: T, key: T,
value: DocSnapshot[T] value: DocSnapshotMap[K][T]
) { ) {
const item = this.get(type, id); const item = this.get(type, id);
if (item) { if (item) {