diff --git a/app/web/src/nova/ed/logic/ed-route.ts b/app/web/src/nova/ed/logic/ed-route.ts index 63ab72ce..47f4eb91 100644 --- a/app/web/src/nova/ed/logic/ed-route.ts +++ b/app/web/src/nova/ed/logic/ed-route.ts @@ -2,7 +2,6 @@ import { compress, decompress } from "wasm-gzip"; import { PG } from "./ed-global"; import { loadSite } from "./ed-site"; import { treeRebuild } from "./tree/build"; -import { loadCompSnapshot } from "./tree/sync-walk-comp"; export const edRoute = async (p: PG) => { if (p.status === "ready" || p.status === "init") { @@ -50,7 +49,7 @@ export const reloadPage = async (p: PG, page_id: string, note: string) => { if (remotePage.comps) { for (const [id_comp, c] of Object.entries(remotePage.comps)) { if (c && c.snapshot) { - await loadCompSnapshot(p, id_comp, c.snapshot); + // await loadCompSnapshot(p, id_comp, c.snapshot); } } } diff --git a/app/web/src/nova/ed/logic/tree/load-walk.tsx b/app/web/src/nova/ed/logic/tree/load-walk.tsx deleted file mode 100644 index 3ed99d98..00000000 --- a/app/web/src/nova/ed/logic/tree/load-walk.tsx +++ /dev/null @@ -1,189 +0,0 @@ -// import { createId } from "@paralleldrive/cuid2"; -// import { deepClone } from "web-utils"; -// import { IContent } from "../../../../utils/types/general"; -// import { IItem } from "../../../../utils/types/item"; -// import { FNComponent } from "../../../../utils/types/meta-fn"; -// import { IMeta, PG } from "../ed-global"; - -// export const walkLoad = async ( -// p: { map: PG["comp"]["map"] }, -// item: IContent, -// loaded: Set, -// loadComponent: (id: string) => Promise -// ) => { -// if (item.type === "item" && item.component?.id) { -// const id = item.component?.id; -// const comp = item.component as FNComponent; - -// if (id && comp) { -// const isFirstLoaded = !loaded.has(id); -// loaded.add(id); -// if (!p.map[id]) { -// await loadComponent(comp.id); -// } -// if (p.map[id] && isFirstLoaded) { -// await walkLoad(p, p.map[id].item, loaded, loadComponent); -// } -// } - -// for (const [propName, prop] of Object.entries(comp.props || {})) { -// if (prop.meta?.type === "content-element") { -// const mprop = comp.props[propName]; -// if (mprop) { -// const mcontent = mprop.content; -// if (mcontent) { -// await walkLoad(p, mcontent, loaded, loadComponent); -// } -// } -// } -// } -// } - -// if (item.type !== "text") { -// await Promise.all( -// item.childs.map((e) => walkLoad(p, e, loaded, loadComponent)) -// ); -// } -// }; - -// export const walkMap = ( -// p: { -// meta: Record; -// comps: Record; -// }, -// arg: { -// isLayout: boolean; -// item: IContent; -// parent_item: { id: string }; -// portal: { -// in: Record; -// out: Record; -// }; -// each?: (meta: IMeta) => void; -// parent_comp?: { id: string; comp_id: string }; -// } -// ) => { -// const { parent_item, parent_comp } = arg; - -// let override_id = ""; -// const id = arg.item.id; - -// if (parent_comp && id) { -// const cmeta = p.meta[parent_comp.id]; -// if (cmeta && cmeta.item.type === "item") { -// const comp = cmeta.item.component; -// if (comp) { -// const ref_ids = comp.ref_ids; -// if (ref_ids) { -// let ref_id = ref_ids[id]; -// if (!ref_id) { -// ref_id = createId(); -// ref_ids[id] = ref_id; -// } -// override_id = ref_id; -// } -// } -// } -// } - -// let item = arg.item; -// if (override_id) { -// item.id = override_id; -// } - -// const item_comp = item.type === "item" ? item.component : null; - -// if (item_comp && item_comp.id && parent_item.id !== "root") { -// const comp_ref = p.comps[item_comp.id]; - -// if (!comp_ref) { -// console.error("Component failed to load: ", item_comp.id); -// return; -// } -// const mcomp = comp_ref.item; - -// if (mcomp) { -// let ref_ids: Record = item_comp.ref_ids; -// if (!ref_ids) { -// ref_ids = {}; -// item_comp.ref_ids = ref_ids; -// } -// const original_id = item.id; -// item = deepClone(mcomp); -// item.id = original_id; - -// const meta: IMeta = { -// item, -// parent_item, -// idexed_scope: {}, -// is_layout: arg.isLayout, -// }; -// if (item.name.startsWith("⬅")) { -// arg.portal.in[item.name] = meta; -// } -// if (item.name.startsWith("⮕")) { -// arg.portal.out[item.name] = meta; -// } -// if (arg.each) arg.each(meta); -// p.meta[item.id] = meta; - -// if (item_comp.props) { -// for (const [k, mprop] of Object.entries(item_comp.props)) { -// if (mprop.meta?.type === "content-element" && mprop.content) { -// walkMap(p, { -// isLayout: arg.isLayout, -// item: mprop.content, -// parent_item: { id: item.id }, -// portal: arg.portal, -// parent_comp: { id: item.id, comp_id: item_comp.id }, -// each: arg.each, -// }); -// } -// } -// } - -// for (const c of mcomp.childs) { -// walkMap(p, { -// isLayout: arg.isLayout, -// item: c, -// parent_item: { id: item.id }, -// portal: arg.portal, -// parent_comp: { id: item.id, comp_id: item_comp.id }, -// each: arg.each, -// }); -// } -// } -// return; -// } - -// const meta: IMeta = { -// item, -// parent_item, -// idexed_scope: {}, -// parent_comp, -// is_layout: arg.isLayout, -// }; -// if (item.name.startsWith("⬅")) { -// arg.portal.in[item.name] = meta; -// } -// if (item.name.startsWith("⮕")) { -// arg.portal.out[item.name] = meta; -// } -// if (arg.each) arg.each(meta); -// p.meta[item.id] = meta; - -// if (item.type !== "text") { -// for (const c of item.childs) { -// if (c) { -// walkMap(p, { -// isLayout: arg.isLayout, -// item: c, -// parent_item: { id: item.id }, -// portal: arg.portal, -// parent_comp, -// each: arg.each, -// }); -// } -// } -// } -// }; diff --git a/app/web/src/nova/ed/logic/tree/sync-walk-comp.tsx b/app/web/src/nova/ed/logic/tree/sync-walk-comp.tsx deleted file mode 100644 index d82726e2..00000000 --- a/app/web/src/nova/ed/logic/tree/sync-walk-comp.tsx +++ /dev/null @@ -1,122 +0,0 @@ -import { NodeModel } from "@minoru/react-dnd-treeview"; -import { compress, decompress } from "wasm-gzip"; -import { MItem } from "../../../../utils/types/item"; -import { DComp } from "../../../../utils/types/root"; -import { IMeta, IScope, PG, active } from "../ed-global"; -import { treeRebuild } from "./build"; -import { - loadComponent, - loadcomp, - syncWalkLoad, - syncWalkMap, -} from "./sync-walk"; -import { waitUntil } from "web-utils"; - -export const loadCompSnapshot = async ( - p: PG, - id_comp: string, - snapshot: Uint8Array -) => { - const doc = new Y.Doc() as DComp; - Y.applyUpdate(doc as any, decompress(snapshot)); - const mitem = doc.getMap("map").get("root"); - if (mitem) { - if (typeof p.comp.list[id_comp]?.on_update === "function") { - doc.off("update", p.comp.list[id_comp].on_update); - } - - p.comp.list[id_comp] = { - comp: { id: id_comp, snapshot }, - doc, - } as any; - - const { tree, meta } = await walkCompTree(p, mitem, id_comp); - p.comp.list[id_comp] = { - ...p.comp.list[id_comp], - meta, - tree, - async on_update(bin, origin) { - if (origin === "sv_remote" || origin === "local") { - return; - } - - const res = await p.sync.yjs.sv_local( - "comp", - id_comp, - Buffer.from(compress(bin)) - ); - - if (res) { - const diff_local = Y.encodeStateAsUpdate( - doc as any, - decompress(res.sv) - ); - Y.applyUpdate(doc as any, decompress(res.diff), "local"); - const mitem = doc.getMap("map").get("root"); - if (mitem) { - const { tree, meta } = await walkCompTree(p, mitem, id_comp); - p.comp.list[id_comp].tree = tree; - p.comp.list[id_comp].meta = meta; - await treeRebuild(p); - - if (active.comp_id === id_comp) { - p.comp.tree = tree; - } - } - await p.sync.yjs.diff_local( - "comp", - id_comp, - Buffer.from(compress(diff_local)) - ); - p.render(); - } - }, - }; - - doc.on("update", p.comp.list[id_comp].on_update); - } -}; - -const walkCompTree = async (p: PG, mitem: MItem, comp_id: string) => { - const tree: NodeModel[] = []; - const meta = {}; - const portal = { - in: {} as Record, - out: {} as Record, - }; - syncWalkLoad(p, mitem, (id) => loadComponent(p, id)); - mitem.doc?.transact(() => { - syncWalkMap( - { - note: "walk-comp", - comps: p.comp.list, - item_loading: p.ui.tree.item_loading, - meta, - tree, - component_not_found(id) { - setTimeout(() => { - if (loadcomp.pending.has(id) || p.comp.list[id]) { - waitUntil(() => !loadcomp.pending.has(id)).then(async () => { - walkCompTree(p, mitem, comp_id); - - const { tree, meta } = await walkCompTree(p, mitem, comp_id); - p.comp.list[comp_id].tree = tree; - p.comp.list[comp_id].meta = meta; - p.render(); - }); - } - }, 100); - }, - }, - { - mitem, - is_layout: false, - parent_item: { id: "root" }, - portal, - tree_root_id: "root", - } - ); - }); - - return { tree, meta }; -}; diff --git a/app/web/src/nova/ed/logic/tree/sync-walk-utils.tsx b/app/web/src/nova/ed/logic/tree/sync-walk-utils.tsx deleted file mode 100644 index 22b56b15..00000000 --- a/app/web/src/nova/ed/logic/tree/sync-walk-utils.tsx +++ /dev/null @@ -1,59 +0,0 @@ -import { createId } from "@paralleldrive/cuid2"; -import { TypedMap } from "yjs-types"; -import { MItem } from "../../../../utils/types/item"; -import { - FMCompDef, - FMComponent, - FNCompDef, - FNComponent, -} from "../../../../utils/types/meta-fn"; - -export const ensurePropContent = (mprop: FMCompDef, k: string) => { - let mcontent = mprop.get("content"); - if (!mcontent) { - const newcontent = new Y.Map(); - syncronize(newcontent, { - id: createId(), - name: k, - type: "item", - dim: { w: "full", h: "full" }, - childs: [], - adv: { - css: "", - }, - }); - mprop.set("content", newcontent as MItem); - mcontent = mprop.get("content"); - } - return mcontent; -}; - -export const ensureMItemProps = ( - mitem_comp: FMComponent, - item_comp: FNComponent -) => { - let mitem_props = mitem_comp.get("props"); - if (!mitem_props) { - mitem_comp.set("props", new Y.Map() as any); - mitem_props = mitem_comp.get("props"); - } - if (!item_comp.props) { - item_comp.props = {}; - } - return mitem_props; -}; - -export const ensureMProp = ( - mitem_props: TypedMap>, - k: string, - v: FNCompDef -) => { - let mprop = mitem_props.get(k); - if (!mprop) { - const newprop = new Y.Map(); - syncronize(newprop, v); - mitem_props.set(k, newprop as FMCompDef); - mprop = mitem_props.get(k); - } - return mprop; -}; diff --git a/app/web/src/nova/ed/logic/tree/sync-walk.tsx b/app/web/src/nova/ed/logic/tree/sync-walk.tsx deleted file mode 100644 index b87a424f..00000000 --- a/app/web/src/nova/ed/logic/tree/sync-walk.tsx +++ /dev/null @@ -1,389 +0,0 @@ -import { NodeModel } from "@minoru/react-dnd-treeview"; -import { createId } from "@paralleldrive/cuid2"; -import { TypedArray } from "yjs-types"; -import { MContent } from "../../../../utils/types/general"; -import { IItem, MItem } from "../../../../utils/types/item"; -import { FNCompDef, FNComponent } from "../../../../utils/types/meta-fn"; -import { MSection } from "../../../../utils/types/section"; -import { IMeta, IScope, PG } from "../ed-global"; -import { loadCompSnapshot } from "./sync-walk-comp"; -import { - ensureMItemProps, - ensureMProp, - ensurePropContent, -} from "./sync-walk-utils"; - -const comp_added = new Set(); - -export const syncWalkLoad = async ( - p: PG, - mitem: MItem, - loadComponent: (id: string) => Promise -) => { - const mcomp = mitem.get("component"); - if (mcomp) { - const id = mcomp.get("id"); - if (id && !comp_added.has(id)) { - comp_added.add(id); - const comp = mcomp.toJSON() as FNComponent; - if (!p.comp.list[id]) { - loadComponent(comp.id); - } - - const pcomp = p.comp.list[id]; - if (pcomp) { - const pitem = pcomp.doc.getMap("map").get("root"); - if (pitem) { - await syncWalkLoad(p, pitem, loadComponent); - } - } - 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 syncWalkLoad(p, mcontent, loadComponent); - } - } - } - } - } - } - - for (const e of mitem.get("childs")?.map((e) => e) || []) { - await syncWalkLoad(p, e, loadComponent); - } -}; - -export const syncWalkMap = ( - p: { - note?: string; - item_loading: PG["ui"]["tree"]["item_loading"]; - tree?: NodeModel[]; - comps: PG["comp"]["list"]; - meta: Record; - component_not_found?: (comp_id: string) => void; - scope?: null | IScope; - }, - arg: { - is_layout: boolean; - mitem: MItem | MSection; - portal: { - in: Record; - out: Record; - }; - parent_item: IMeta["parent_item"]; - parent_mcomp?: IMeta["parent_mcomp"]; - jsx_prop_name?: string; - jsx_prop_root?: boolean; - skip_add_tree?: boolean; - tree_root_id: string; - each?: (meta: IMeta) => void; - } -) => { - const { mitem, parent_item } = arg; - if (typeof mitem.get !== "function") { - return; - } - - const item = {} as unknown as IItem; - - let override_id = ""; - const id = mitem.get("id"); - - let skip_tree = arg.skip_add_tree; - let skip_tree_child = skip_tree; - if (id && p.item_loading.includes(id)) { - skip_tree_child = true; - } - - let mapped = false; - if (arg.parent_mcomp && id) { - const fcomp = arg.parent_mcomp.minstance.get("component"); - if (fcomp) { - const ref_ids = fcomp.get("ref_ids"); - - if (ref_ids) { - let ref_id = ref_ids.get(id); - - if (!ref_id) { - ref_id = createId(); - ref_ids.set(id, ref_id); - } - override_id = ref_id; - mapItem(mitem, item, ref_ids.toJSON()); - mapped = true; - } - } - } - - if (!mapped) { - mapItem(mitem, item); - } - - if (typeof item.name !== "string") return; - - if (override_id) { - if (!item.originalId) item.originalId = item.id; - item.id = override_id; - } - - if (arg.jsx_prop_name) { - const pitem = p.meta[arg.parent_item.id].item; - if (pitem.type === "item" && pitem.component) { - const pprop = pitem.component.props[arg.jsx_prop_name]; - if (pprop.content) { - pprop.content.id = item.id; - } - } - } - - const item_comp = item.component; - const mitem_comp = mitem.get("component"); - const metaNotFound = () => { - if (!skip_tree && p.tree) { - p.tree.push({ - id: item.id, - parent: arg.tree_root_id === parent_item.id ? "root" : parent_item.id, - text: item.name, - }); - } - }; - - if (item_comp && item_comp.id && parent_item.id !== "root") { - if (!p.comps[item_comp.id]) { - if (p.component_not_found) { - p.component_not_found(item_comp.id); - } - } - - let ref_comp = p.comps[item_comp.id]; - - if (ref_comp && mitem_comp) { - const mcomp = ref_comp.doc.getMap("map").get("root"); - - const minstance = arg.parent_mcomp - ? arg.parent_mcomp.minstance - : (mitem as MItem); - - let mref_ids = minstance.get("component")?.get("ref_ids"); - - if (!mref_ids) { - minstance.get("component")?.set("ref_ids", new Y.Map() as any); - mref_ids = minstance.get("component")?.get("ref_ids"); - } - - if (mcomp) { - const old_id = item.id; - const ref_ids = mref_ids?.toJSON() || {}; - mapItem(mcomp, item, ref_ids); - item.id = old_id; - - const meta: IMeta = { - item, - mitem: mitem as MItem, - parent_item, - parent_mcomp: arg.parent_mcomp, - indexed_scope: {}, - is_layout: arg.is_layout, - }; - - if (item.name.startsWith("⬅")) { - arg.portal.in[item.name] = meta; - } - if (item.name.startsWith("⮕")) { - arg.portal.out[item.name] = meta; - } - if (arg.each) arg.each(meta); - p.meta[item.id] = meta; - - if (!skip_tree && p.tree) { - p.tree.push({ - id: item.id, - parent: - arg.tree_root_id === parent_item.id ? "root" : parent_item.id, - text: item.name, - data: meta, - }); - } - - const mprops = mcomp.get("component")?.get("props")?.toJSON() as Record< - string, - FNCompDef - >; - const propvis = {}; - if (mprops) { - const mitem_comp = mitem.get("component"); - if (mitem_comp) { - const mitem_props = ensureMItemProps(mitem_comp, item_comp); - if (mitem_props) { - for (const [k, v] of Object.entries(mprops)) { - const mprop = ensureMProp(mitem_props, k, v); - if (mprop) { - item_comp.props[k] = mprop.toJSON() as FNCompDef; - if (meta.item.type === "item" && meta.item.component) { - meta.item.component.props[k] = item_comp.props[k]; - } - - if (mprop && v.meta?.type === "content-element") { - const mcontent = ensurePropContent(mprop, k); - item_comp.props[k].content = mcontent?.toJSON() as IItem; - if (meta.item.type === "item" && meta.item.component) { - meta.item.component.props[k].content = - item_comp.props[k].content; - } - - if (mcontent) { - syncWalkMap(p, { - is_layout: arg.is_layout, - tree_root_id: arg.tree_root_id, - mitem: mcontent, - jsx_prop_name: k, - jsx_prop_root: true, - parent_mcomp: { minstance, meta, mcomp }, - parent_item: { id: item.id, mitem: mitem as MItem }, - portal: arg.portal, - skip_add_tree: skip_tree_child, - each: arg.each, - }); - } - } - } - } - } - } - } - - const childs = mcomp.get("childs")?.map((e) => e) || []; - - for (const e of childs) { - syncWalkMap(p, { - is_layout: arg.is_layout, - tree_root_id: arg.tree_root_id, - mitem: e, - parent_item: { id: item.id, mitem: mitem as MItem }, - parent_mcomp: { minstance, meta, mcomp }, - skip_add_tree: true, - portal: arg.portal, - each: arg.each, - }); - } - return; - } - } - - metaNotFound(); - return; - } - - const meta: IMeta = { - is_layout: arg.is_layout, - item, - jsx_prop_name: arg.jsx_prop_name, - jsx_prop_root: arg.jsx_prop_root, - mitem: mitem as MItem, - parent_item, - parent_mcomp: arg.parent_mcomp, - indexed_scope: {}, - }; - - if (item.name.startsWith("⬅")) { - arg.portal.in[item.name] = meta; - } - if (item.name.startsWith("⮕")) { - arg.portal.out[item.name] = meta; - } - - if (arg.each) arg.each(meta); - p.meta[item.id] = meta; - - if (!skip_tree && p.tree) { - p.tree.push({ - id: item.id, - parent: arg.tree_root_id === parent_item.id ? "root" : parent_item.id, - text: item.name, - data: meta, - }); - } - - const childs = mitem.get("childs")?.map((e) => e) || []; - - for (const e of childs) { - syncWalkMap(p, { - is_layout: arg.is_layout, - tree_root_id: arg.tree_root_id, - mitem: e, - jsx_prop_name: arg.jsx_prop_name, - parent_item: { id: item.id, mitem: mitem as MItem }, - parent_mcomp: arg.parent_mcomp, - portal: arg.portal, - skip_add_tree: skip_tree_child, - each: arg.each, - }); - } -}; - -export const loadcomp = { - timeout: 0 as any, - pending: new Set(), -}; - -export const loadComponent = async (p: PG, id_comp: string) => { - return new Promise((resolve) => { - if (p.comp.list[id_comp]) { - resolve(true); - return; - } - - loadcomp.pending.add(id_comp); - clearTimeout(loadcomp.timeout); - loadcomp.timeout = setTimeout(async () => { - const comps = await p.sync.comp.load([...loadcomp.pending]); - let result = Object.entries(comps); - - for (const [id_comp, comp] of result) { - for (const cur of Object.values(comp)) { - if (cur && cur.snapshot) { - await loadCompSnapshot(p, id_comp, cur.snapshot, cur.scope); - } - } - } - loadcomp.pending.clear(); - resolve(result.length > 0); - }, 150); - }); -}; - -const mapItem = ( - mitem: MContent, - item: any, - ref_ids?: Record -) => { - mitem.forEach((e, k) => { - if (k !== "childs") { - let val = e; - if (typeof e === "object" && e) { - if ((e as any).toJSON) { - val = e.toJSON() as any; - } - } - if (k !== "originalId") item[k] = val; - } else { - item[k] = []; - const childs = e as unknown as TypedArray<{}>; - childs.forEach((c) => { - if (typeof c.get === "function") { - if (ref_ids) { - const id = ref_ids[c.get("id")]; - if (id) { - item[k].push({ id }); - } - } else { - item[k].push({ id: c.get("id") }); - } - } - }); - } - }); -}; diff --git a/app/web/src/nova/ed/panel/header/mid/comp-picker.tsx b/app/web/src/nova/ed/panel/header/mid/comp-picker.tsx index d76e8dc8..8197776a 100644 --- a/app/web/src/nova/ed/panel/header/mid/comp-picker.tsx +++ b/app/web/src/nova/ed/panel/header/mid/comp-picker.tsx @@ -7,7 +7,6 @@ import { ISection, MSection } from "../../../../../utils/types/section"; import { EDGlobal, active } from "../../../logic/ed-global"; import { getMetaById } from "../../../logic/tree/build"; import { fillID } from "../../../logic/tree/fill-id"; -import { loadComponent } from "../../../logic/tree/sync-walk"; import { TopBtn } from "../top-btn"; export const EdCompPicker = () => { @@ -19,7 +18,7 @@ export const EdCompPicker = () => { p.ui.popup.comp.open = async (comp_id) => { let comp_ref = p.comp.list[comp_id]; if (!comp_ref) { - await loadComponent(p, comp_id); + // await loadComponent(p, comp_id); comp_ref = p.comp.list[comp_id]; } diff --git a/app/web/src/nova/ed/panel/popup/comp/comp-preview.tsx b/app/web/src/nova/ed/panel/popup/comp/comp-preview.tsx index ceff1456..8f9d24db 100644 --- a/app/web/src/nova/ed/panel/popup/comp/comp-preview.tsx +++ b/app/web/src/nova/ed/panel/popup/comp/comp-preview.tsx @@ -4,7 +4,7 @@ import { produceCSS } from "../../../../../utils/css/gen"; import { IItem } from "../../../../../utils/types/item"; import { IText } from "../../../../../utils/types/text"; import { EDGlobal, PG, active } from "../../../logic/ed-global"; -import { loadComponent } from "../../../logic/tree/sync-walk"; +// import { loadComponent } from "../../../logic/tree/sync-walk"; import { EdCompPreviewTree } from "./comp-preview-tree"; import { compPicker, reloadCompPicker } from "./comp-reload"; @@ -19,9 +19,9 @@ export const EdCompPreview = () => { useEffect(() => { if (!p.comp.list[comp_id] && !!comp_id) { - loadComponent(p, comp_id).then(() => { - p.render(); - }); + // loadComponent(p, comp_id).then(() => { + // p.render(); + // }); } }, [comp_id]);