async transact

This commit is contained in:
Rizky 2023-10-23 03:50:30 +07:00
parent 203702212a
commit 7a48796c10
5 changed files with 126 additions and 51 deletions

View File

@ -12,6 +12,9 @@ export const SyncActionDefinition = {
"page": { "page": {
"list": "6", "list": "6",
"load": "7" "load": "7"
},
"yjs": {
"sv_local": "8"
} }
}; };
export const SyncActionPaths = { export const SyncActionPaths = {
@ -22,5 +25,6 @@ export const SyncActionPaths = {
"4": "comp.group", "4": "comp.group",
"5": "comp.load", "5": "comp.load",
"6": "page.list", "6": "page.list",
"7": "page.load" "7": "page.load",
"8": "yjs.sv_local"
}; };

View File

@ -1,5 +1,9 @@
import { component, page } from "dbgen"; import { component, page } from "dbgen";
import { EComp, EPage, ESite } from "../../../web/src/render/ed/logic/ed-global"; import {
EComp,
EPage,
ESite,
} from "../../../web/src/render/ed/logic/ed-global";
/* /*
WARNING: WARNING:
@ -27,4 +31,7 @@ export const SyncActions = {
({}) as Record<string, Exclude<page, "content_tree">>, ({}) as Record<string, Exclude<page, "content_tree">>,
load: async (id: string) => ({}) as EPage | void, load: async (id: string) => ({}) as EPage | void,
}, },
yjs: {
sv_local: async (mode: "page" | "comp", id: string, bin: Uint8Array) => {},
},
}; };

View File

@ -1,6 +1,6 @@
import { decompress } from "wasm-gzip";
import { PG } from "./ed-global"; import { PG } from "./ed-global";
import { treeRebuild } from "./tree/build"; import { treeRebuild } from "./tree/build";
import { decompress } from "wasm-gzip";
export const edRoute = async (p: PG) => { export const edRoute = async (p: PG) => {
if (p.status === "ready") { if (p.status === "ready") {
@ -30,6 +30,10 @@ export const edRoute = async (p: PG) => {
if (page.snapshot) { if (page.snapshot) {
const doc = new Y.Doc(); const doc = new Y.Doc();
Y.applyUpdate(doc, decompress(page.snapshot)); Y.applyUpdate(doc, decompress(page.snapshot));
doc.on("update", (bin: Uint8Array, origin: any) => {
console.log(bin);
});
p.page.doc = doc as any; p.page.doc = doc as any;
if (p.page.doc) { if (p.page.doc) {

View File

@ -1,51 +1,64 @@
import { createId } from "@paralleldrive/cuid2"; import { createId } from "@paralleldrive/cuid2";
import { syncronize } from "y-pojo";
import { TypedMap } from "yjs-types";
import { MContent } from "../../../../utils/types/general"; import { MContent } from "../../../../utils/types/general";
import { IItem, MItem } from "../../../../utils/types/item"; import { IItem, MItem } from "../../../../utils/types/item";
import { DComp } from "../../../../utils/types/root";
import { MSection } from "../../../../utils/types/section";
import { EdMeta, PG } from "../ed-global";
import { import {
FMCompDef, FMCompDef,
FMComponent, FMComponent,
FNCompDef, FNCompDef,
FNComponent, FNComponent,
} from "../../../../utils/types/meta-fn"; } from "../../../../utils/types/meta-fn";
import { syncronize } from "y-pojo"; import { DComp } from "../../../../utils/types/root";
import { TypedMap } from "yjs-types"; import { MSection } from "../../../../utils/types/section";
import { EdMeta, PG } from "../ed-global";
export const treeRebuild = async (p: PG) => { export const treeRebuild = async (p: PG) => {
const root = p.page.doc?.getMap("map").get("root"); const doc = p.page.doc;
if (root) { if (!doc) return;
p.page.entry = [];
p.page.tree = [];
p.page.meta = {};
const portal = { const root = doc.getMap("map").get("root");
in: {} as Record<string, EdMeta>, if (root) {
out: {} as Record<string, EdMeta>,
};
const sections = root.get("childs"); const sections = root.get("childs");
if (sections) { if (sections) {
const loaded = new Set<string>();
await Promise.all( await Promise.all(
sections.map(async (e) => { sections.map((e) => {
p.page.entry.push(e.get("id")); p.page.entry.push(e.get("id"));
await walkMap(p, { mitem: e, parent_item: { id: "root" }, portal }); return walkLoad(p, e, loaded);
}) })
); );
}
doc.transact(async () => {
p.page.entry = [];
p.page.tree = [];
p.page.meta = {};
for (const [k, portal_out] of Object.entries(portal.out)) { const portal = {
const name = k.replace(/⮕/gi, "").trim(); in: {} as Record<string, EdMeta>,
const portal_in = portal.in[`${name}`]; out: {} as Record<string, EdMeta>,
if (portal_in) { };
for (const key of Object.keys(portal_in)) { const sections = root.get("childs");
delete (portal_in as any)[key]; if (sections) {
} sections.map((e) => {
for (const [k, v] of Object.entries(portal_out)) { p.page.entry.push(e.get("id"));
(portal_in as any)[k] = v; walkMap(p, { mitem: e, parent_item: { id: "root" }, portal });
});
for (const [k, portal_out] of Object.entries(portal.out)) {
const name = k.replace(/⮕/gi, "").trim();
const portal_in = portal.in[`${name}`];
if (portal_in) {
for (const key of Object.keys(portal_in)) {
delete (portal_in as any)[key];
}
for (const [k, v] of Object.entries(portal_out)) {
(portal_in as any)[k] = v;
}
} }
} }
} }
} });
p.render(); p.render();
} }
}; };
@ -66,7 +79,45 @@ const mapItem = (mitem: MContent, item: any) => {
}); });
}; };
const walkMap = async ( const walkLoad = async (p: PG, mitem: MItem, loaded: Set<string>) => {
const mcomp = mitem.get("component");
if (mcomp) {
const id = mcomp.get("id");
const comp = mcomp.toJSON() as FNComponent;
if (id) {
loaded.add(id);
if (!p.comp.list[id]) {
await loadComponent(p, comp);
}
const pcomp = p.comp.list[id];
if (pcomp) {
const pitem = pcomp.doc.getMap("map").get("item");
if (pitem && !loaded.has(id)) {
await walkLoad(p, pitem, loaded);
}
}
}
for (const [propName, prop] of Object.entries(comp.props || {})) {
if (prop.meta?.type === "content-element") {
const mprop = mcomp.get("props")?.get(propName);
if (mprop) {
const mcontent = ensurePropContent(mprop, propName);
if (mcontent) {
await walkLoad(p, mcontent, loaded);
}
}
}
}
}
for (const e of mitem.get("childs")?.map((e) => e) || []) {
await walkLoad(p, e, loaded);
}
};
const walkMap = (
p: PG, p: PG,
arg: { arg: {
mitem: MItem | MSection; mitem: MItem | MSection;
@ -96,7 +147,7 @@ const walkMap = async (
} }
const item_comp = item.component; const item_comp = item.component;
const mitem_comp = mitem.get("component");
const metaNotFound = () => { const metaNotFound = () => {
if (!arg.skip_add_tree) { if (!arg.skip_add_tree) {
p.page.tree.push({ p.page.tree.push({
@ -109,20 +160,19 @@ const walkMap = async (
if (item_comp && item_comp.id && parent_item.id !== "root") { if (item_comp && item_comp.id && parent_item.id !== "root") {
if (!p.comp.list[item_comp.id]) { if (!p.comp.list[item_comp.id]) {
if (!(await loadComponent(p, item_comp))) { return;
console.log("not found");
metaNotFound();
return;
}
} }
const ref_comp = p.comp.list[item_comp.id]; const ref_comp = p.comp.list[item_comp.id];
if (ref_comp) { if (ref_comp && mitem_comp) {
const mcomp = ref_comp.doc.getMap("map").get("item"); const mcomp = ref_comp.doc.getMap("map").get("item");
if (mcomp) { if (mcomp) {
const ref_ids: Record<string, string> = {}; let ref_ids: Record<string, string> = item_comp.ref_ids;
if (!ref_ids) {
mapItemComp({ parent_comp, item, mcomp, ref_ids }); mitem_comp.set("ref_ids", new Y.Map() as any);
ref_ids = {};
}
mapItemComp({ parent_comp, item, mcomp, mitem_comp, ref_ids });
const meta: EdMeta = { const meta: EdMeta = {
item, item,
@ -156,9 +206,7 @@ const walkMap = async (
if (mprop && v.meta?.type === "content-element") { if (mprop && v.meta?.type === "content-element") {
const mcontent = ensurePropContent(mprop, k); const mcontent = ensurePropContent(mprop, k);
if (mcontent) { if (mcontent) {
console.log(p.page.meta[item.id]); walkMap(p, {
await walkMap(p, {
mitem: mcontent, mitem: mcontent,
parent_item: { id: item.id, mitem: mitem as MItem }, parent_item: { id: item.id, mitem: mitem as MItem },
parent_comp: { ref_ids, mcomp }, parent_comp: { ref_ids, mcomp },
@ -173,7 +221,7 @@ const walkMap = async (
const childs = mcomp.get("childs")?.map((e) => e) || []; const childs = mcomp.get("childs")?.map((e) => e) || [];
for (const e of childs) { for (const e of childs) {
await walkMap(p, { walkMap(p, {
mitem: e, mitem: e,
parent_item: { id: item.id, mitem: mitem as MItem }, parent_item: { id: item.id, mitem: mitem as MItem },
parent_comp: { ref_ids, mcomp }, parent_comp: { ref_ids, mcomp },
@ -216,7 +264,7 @@ const walkMap = async (
const childs = mitem.get("childs")?.map((e) => e) || []; const childs = mitem.get("childs")?.map((e) => e) || [];
for (const e of childs) { for (const e of childs) {
await walkMap(p, { walkMap(p, {
mitem: e, mitem: e,
parent_item: { id: item.id, mitem: mitem as MItem }, parent_item: { id: item.id, mitem: mitem as MItem },
portal: arg.portal, portal: arg.portal,
@ -288,17 +336,27 @@ const mapItemComp = (arg: {
parent_comp: EdMeta["parent_comp"]; parent_comp: EdMeta["parent_comp"];
mcomp: MItem; mcomp: MItem;
item: IItem; item: IItem;
mitem_comp: FMComponent;
ref_ids: Record<string, string>; ref_ids: Record<string, string>;
}) => { }) => {
const { parent_comp, mcomp, item, ref_ids } = arg; const { parent_comp, mcomp, item, ref_ids, mitem_comp } = arg;
let ref_id = "";
if (parent_comp) { if (parent_comp) {
let old_id = item.id; ref_id = item.id;
mapItem(mcomp, item); mapItem(mcomp, item);
ref_ids[item.id] = old_id;
item.id = old_id;
} else { } else {
mapItem(mcomp, item); mapItem(mcomp, item);
ref_ids[item.id] = createId(); if (ref_ids[item.id]) {
item.id = ref_ids[item.id]; ref_id = ref_ids[item.id];
} else {
ref_id = createId();
const mref = mitem_comp.get("ref_ids");
if (mref) {
mref.set(item.id, ref_id);
}
}
} }
ref_ids[item.id] = ref_id;
item.id = ref_ids[item.id];
}; };

View File

@ -24,6 +24,7 @@ export type FNComponent = {
name: string; name: string;
updated_at?: number; updated_at?: number;
props: Record<string, FNCompDef>; props: Record<string, FNCompDef>;
ref_ids: Record<string, string>;
}; };
export type FNCompDef = { export type FNCompDef = {
@ -54,6 +55,7 @@ export type FMCompDef = TypedMap<
export type FMComponent = TypedMap< export type FMComponent = TypedMap<
Omit<FNComponent, "group" | "props"> & { Omit<FNComponent, "group" | "props"> & {
props: TypedMap<Record<string, FMCompDef>>; props: TypedMap<Record<string, FMCompDef>>;
ref_ids: TypedMap<Record<string, string>>;
} }
>; >;