diff --git a/app/web/src/nova/ed/ed-base.tsx b/app/web/src/nova/ed/ed-base.tsx index e72a918b..8de89007 100644 --- a/app/web/src/nova/ed/ed-base.tsx +++ b/app/web/src/nova/ed/ed-base.tsx @@ -26,7 +26,7 @@ export const EdBase = () => { edRoute(p); if (p.status === "loading") { - return ; + return ; } if (p.status === "site-not-found" || p.status === "page-not-found") { return ( diff --git a/app/web/src/nova/ed/logic/ed-route.ts b/app/web/src/nova/ed/logic/ed-route.ts index 5758d78a..e9274c17 100644 --- a/app/web/src/nova/ed/logic/ed-route.ts +++ b/app/web/src/nova/ed/logic/ed-route.ts @@ -1,9 +1,8 @@ import { compress, decompress } from "wasm-gzip"; -import { IItem } from "../../../utils/types/item"; -import { DComp } from "../../../utils/types/root"; import { PG } from "./ed-global"; -import { treeRebuild } from "./tree/build"; import { loadSite } from "./ed-site"; +import { treeRebuild } from "./tree/build"; +import { loadCompSnapshot } from "./tree/sync-walk"; export const edRoute = async (p: PG) => { if (p.status === "ready" || p.status === "init") { @@ -52,15 +51,14 @@ export const reloadPage = async (p: PG, page_id: string) => { if (remotePage.scope_comps) { for (const [id_comp, c] of Object.entries(remotePage.scope_comps)) { if (c && c.snapshot) { - const doc = new Y.Doc() as DComp; - if (c.snapshot) { - Y.applyUpdate(doc as any, decompress(c.snapshot)); - // p.comp.list[id_comp] = { - // id: id_comp, - // item: doc.getMap("map").get("root")?.toJSON() as IItem, - // }; - // p.comp.list[id_comp] = { comp: c, doc, scope: c.scope }; - } + + await loadCompSnapshot( + p, + id_comp, + new Set(), + c.snapshot, + c.scope + ); } } } diff --git a/app/web/src/nova/ed/logic/tree/build.tsx b/app/web/src/nova/ed/logic/tree/build.tsx index 4616a71d..1ac1a497 100644 --- a/app/web/src/nova/ed/logic/tree/build.tsx +++ b/app/web/src/nova/ed/logic/tree/build.tsx @@ -1,6 +1,8 @@ import { EdMeta, PG } from "../ed-global"; import { loadComponent, syncWalkLoad, syncWalkMap } from "./sync-walk"; +export const compLoaded = new Set(); + export const treeRebuild = async (p: PG, arg?: { note?: string }) => { const doc = p.page.doc; if (!doc) return; @@ -16,11 +18,10 @@ export const treeRebuild = async (p: PG, arg?: { note?: string }) => { const sections = root.get("childs"); if (sections) { - const loaded = new Set(); await Promise.all( sections.map((e) => { - return syncWalkLoad(p, e, loaded, (id) => { - return loadComponent(p, id, loaded); + return syncWalkLoad(p, e, compLoaded, (id) => { + return loadComponent(p, id, compLoaded); }); }) ); @@ -112,13 +113,15 @@ export const treeRebuild = async (p: PG, arg?: { note?: string }) => { item_loading: p.ui.tree.item_loading, meta: p.page.meta, tree: p.page.tree, - }, { - isLayout: false, - mitem: e, - parent_item: { id: root_id }, - tree_root_id: root_id, - portal, - }); + }, + { + isLayout: false, + mitem: e, + parent_item: { id: root_id }, + tree_root_id: root_id, + portal, + } + ); }); for (const [k, portal_out] of Object.entries(portal.out)) { diff --git a/app/web/src/nova/ed/logic/tree/sync-walk.tsx b/app/web/src/nova/ed/logic/tree/sync-walk.tsx index c6607dc6..ac3b04a3 100644 --- a/app/web/src/nova/ed/logic/tree/sync-walk.tsx +++ b/app/web/src/nova/ed/logic/tree/sync-walk.tsx @@ -7,12 +7,13 @@ import { IItem, MItem } from "../../../../utils/types/item"; import { FNCompDef, FNComponent } from "../../../../utils/types/meta-fn"; import { DComp } from "../../../../utils/types/root"; import { MSection } from "../../../../utils/types/section"; -import { EdMeta, PG } from "../ed-global"; +import { EdMeta, IScope, PG } from "../ed-global"; import { ensureMItemProps, ensureMProp, ensurePropContent, } from "./sync-walk-utils"; +import { waitUntil } from "web-utils"; export const syncWalkLoad = async ( p: PG, @@ -64,6 +65,7 @@ export const syncWalkMap = ( tree?: NodeModel[]; comps: PG["comp"]["list"]; meta: Record; + warn_component_loaded?: boolean; }, arg: { isLayout: boolean; @@ -127,7 +129,7 @@ export const syncWalkMap = ( }; if (item_comp && item_comp.id && parent_item.id !== "root") { - if (!p.comps[item_comp.id]) { + if (!p.comps[item_comp.id] && p.warn_component_loaded !== false) { console.error("Component failed to load: ", item_comp.id); return; } @@ -271,6 +273,53 @@ export const syncWalkMap = ( } }; +export const loadCompSnapshot = async ( + p: PG, + id_comp: string, + loaded: Set, + snapshot: Uint8Array, + scope: IScope +) => { + if (loaded.has(id_comp)) { + return; + } + const doc = new Y.Doc() as DComp; + Y.applyUpdate(doc as any, decompress(snapshot)); + const mitem = doc.getMap("map").get("root"); + if (mitem) { + await syncWalkLoad(p, mitem, loaded, (id) => loadComponent(p, id, loaded)); + const tree: NodeModel[] = []; + const meta = {}; + const portal = { + in: {} as Record, + out: {} as Record, + }; + syncWalkMap( + { + comps: p.comp.list, + item_loading: p.ui.tree.item_loading, + meta, + tree, + warn_component_loaded: false, + }, + { + mitem, + isLayout: false, + parent_item: { id: "root" }, + portal, + tree_root_id: "root", + } + ); + p.comp.list[id_comp] = { + comp: { id: id_comp, snapshot }, + doc, + scope: scope, + meta, + tree, + }; + } +}; + export const loadComponent = async ( p: PG, id_comp: string, @@ -281,19 +330,7 @@ export const loadComponent = async ( if (comps) { for (const cur of Object.values(comps)) { if (cur && cur.snapshot) { - const doc = new Y.Doc() as DComp; - if (cur.snapshot) { - Y.applyUpdate(doc as any, decompress(cur.snapshot)); - const mitem = doc.getMap("map").get("root"); - if (mitem) { - await syncWalkLoad(p, mitem, loaded, (id) => - loadComponent(p, id, loaded) - ); - - // syncWalkMap() - // p.comp.list[id_comp] = { comp: cur, doc, scope: cur.scope; }; - } - } + await loadCompSnapshot(p, id_comp, loaded, cur.snapshot, cur.scope); } } return true; diff --git a/app/web/src/nova/ed/panel/main/main.tsx b/app/web/src/nova/ed/panel/main/main.tsx index dab52240..82fc74b3 100644 --- a/app/web/src/nova/ed/panel/main/main.tsx +++ b/app/web/src/nova/ed/panel/main/main.tsx @@ -2,9 +2,9 @@ import { useGlobal } from "web-utils"; import { Loading } from "../../../../utils/ui/loading"; import { View } from "../../../view/view"; import { EDGlobal, active } from "../../logic/ed-global"; +import { compLoaded } from "../../logic/tree/build"; import { loadComponent } from "../../logic/tree/sync-walk"; -const compLoaded = new Set(); export const EdMain = () => { const p = useGlobal(EDGlobal, "EDITOR"); return ( diff --git a/app/web/src/nova/ed/panel/tree/node/item/action.tsx b/app/web/src/nova/ed/panel/tree/node/item/action.tsx index ca6c0b10..45c26c4e 100644 --- a/app/web/src/nova/ed/panel/tree/node/item/action.tsx +++ b/app/web/src/nova/ed/panel/tree/node/item/action.tsx @@ -27,6 +27,9 @@ export const EdTreeAction = ({ content="Edit Component" className="flex items-center border border-slate-500 bg-white rounded-sm text-[10px] px-[2px] cursor-pointer hover:bg-purple-100 hover:border-purple-600" onClick={(e) => { + e.stopPropagation(); + e.preventDefault(); + const comp_id = item.component?.id; if (comp_id) { active.comp_id = comp_id;