diff --git a/app/srv/ws/sync/actions/comp_load.ts b/app/srv/ws/sync/actions/comp_load.ts index 89e0d50e..a3939c7a 100644 --- a/app/srv/ws/sync/actions/comp_load.ts +++ b/app/srv/ws/sync/actions/comp_load.ts @@ -37,6 +37,13 @@ const scanMeta = async (id: string, doc: DComp, sync: SyncConnection) => { mitem, parent_item: { id: "root" }, parent_ids: ["root"], + parent_mcomp: { + id, + jsx_props: {}, + mcomp: mitem, + mitem, + parent_ids: [], + }, } ); diff --git a/app/srv/ws/sync/editor/load-page-comp.ts b/app/srv/ws/sync/editor/load-page-comp.ts index 0f5a5a1f..d282fe8f 100644 --- a/app/srv/ws/sync/editor/load-page-comp.ts +++ b/app/srv/ws/sync/editor/load-page-comp.ts @@ -15,7 +15,7 @@ export const extractMItemProps = (arg: { item_comp: FNComponent; mcomp: MItem; scope: Exclude, undefined>; - mcontent: (mcontent: MItem) => void; + mcontent: (mcontent: MItem, prop_name: string) => void; }) => { const { mitem, item_comp, mcomp, scope } = arg; @@ -35,7 +35,7 @@ export const extractMItemProps = (arg: { scope.props[k].value = "null as ReactElement"; const mcontent = ensurePropContent(mprop, k); if (mcontent) { - arg.mcontent(mcontent); + arg.mcontent(mcontent, k); } } } diff --git a/app/srv/ws/sync/editor/load-page.ts b/app/srv/ws/sync/editor/load-page.ts index 1c9440a0..8e27d967 100644 --- a/app/srv/ws/sync/editor/load-page.ts +++ b/app/srv/ws/sync/editor/load-page.ts @@ -73,6 +73,11 @@ export const serverWalkLoad = async ( } }; +type ArgParentMComp = EdMeta["parent_mcomp"] & { + id: string; + parent_ids: string[]; + jsx_props: Record; +}; export const serverWalkMap = ( p: { sync: SyncConnection; @@ -83,11 +88,8 @@ export const serverWalkMap = ( mitem: MItem; parent_ids: string[]; parent_item: EdMeta["parent_item"]; - is_prop?: boolean; - parent_mcomp?: EdMeta["parent_mcomp"] & { - id: string; - parent_ids: string[]; - }; + is_jsx_prop?: boolean; + parent_mcomp?: ArgParentMComp; } ) => { const { mitem, parent_item, parent_mcomp } = arg; @@ -180,23 +182,33 @@ export const serverWalkMap = ( undefined >; + const parent_mcomp: ArgParentMComp = { + parent_ids: ["root", item.id], + id: item_comp.id, + mitem: mitem as MItem, + mcomp, + jsx_props: {}, + }; extractMItemProps({ item_comp, mitem, mcomp, scope, - mcontent(mcontent) { + mcontent(mcontent, prop_name) { + const parent_ids = [...arg.parent_ids, item.id]; + const id = mcontent.get("id"); + if (id) { + parent_mcomp.jsx_props[prop_name] = { + id, + parent_ids, + }; + } serverWalkMap(p, { - parent_ids: [...arg.parent_ids, item.id], + parent_ids, mitem: mcontent, parent_item: { id: item.id, mitem: mitem as MItem }, - is_prop: true, - parent_mcomp: { - parent_ids: ["root", item.id], - id: item_comp.id, - mitem: mitem as MItem, - mcomp, - }, + is_jsx_prop: true, + parent_mcomp, }); }, }); @@ -234,12 +246,7 @@ export const serverWalkMap = ( id: item.id, mitem: mitem as MItem, }, - parent_mcomp: { - parent_ids: ["root", item.id], - id: item_comp.id, - mitem: mitem as MItem, - mcomp, - }, + parent_mcomp, }); } } @@ -248,14 +255,25 @@ export const serverWalkMap = ( } } - if (arg.parent_mcomp && !arg.is_prop) { + if (item.name.startsWith("jsx=")) { + console.log( + item.name, + !!arg.parent_mcomp, + !arg.is_jsx_prop, + arg.parent_item.mitem?.get("name") + ); + } + + if (arg.parent_mcomp && !arg.is_jsx_prop) { let id = item.originalId || item.id; const pcomp = p.scope_comps[arg.parent_mcomp.id]; + pcomp.scope[id] = { p: arg.parent_mcomp.parent_ids, n: item.name, s: null, }; + const js = item.adv?.js; if (typeof js === "string") { const scope = parseJs(js); @@ -276,9 +294,9 @@ export const serverWalkMap = ( for (const e of childs) { serverWalkMap(p, { mitem: e, - is_prop: arg.is_prop, + is_jsx_prop: arg.is_jsx_prop, parent_item: { id: item.id, mitem: mitem as MItem }, - parent_mcomp: arg.parent_mcomp + parent_mcomp: !!arg.parent_mcomp ? { ...arg.parent_mcomp, parent_ids: [...(arg.parent_mcomp?.parent_ids || []), item.id], diff --git a/app/web/src/nova/ed/logic/ed-route.ts b/app/web/src/nova/ed/logic/ed-route.ts index 24cffea1..81fbbe88 100644 --- a/app/web/src/nova/ed/logic/ed-route.ts +++ b/app/web/src/nova/ed/logic/ed-route.ts @@ -37,6 +37,7 @@ export const edRoute = async (p: PG) => { } }; +const loaded = new Set(); export const reloadPage = async (p: PG, page_id: string, note: string) => { p.status = "loading"; const remotePage = await p.sync.page.load(page_id); @@ -51,13 +52,7 @@ export const reloadPage = async (p: PG, page_id: string, note: string) => { if (remotePage.scope_comps) { for (const [id_comp, c] of Object.entries(remotePage.scope_comps)) { if (c && c.snapshot) { - await loadCompSnapshot( - p, - id_comp, - new Set(), - c.snapshot, - c.scope - ); + await loadCompSnapshot(p, id_comp, loaded, c.snapshot, c.scope); } } } 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 index a97aa1b3..13dfb60b 100644 --- a/app/web/src/nova/ed/logic/tree/sync-walk-comp.tsx +++ b/app/web/src/nova/ed/logic/tree/sync-walk-comp.tsx @@ -16,6 +16,7 @@ export const loadCompSnapshot = async ( if (loaded.has(id_comp)) { return; } + loaded.add(id_comp); const doc = new Y.Doc() as DComp; Y.applyUpdate(doc as any, decompress(snapshot)); const mitem = doc.getMap("map").get("root"); @@ -24,12 +25,16 @@ export const loadCompSnapshot = async ( doc.off("update", p.comp.list[id_comp].on_update); } - const { tree, meta } = await walkCompTree(p, mitem, loaded); - p.comp.list[id_comp] = { comp: { id: id_comp, snapshot }, doc, scope: scope, + } as any; + + const { tree, meta } = await walkCompTree(p, mitem, loaded); + + p.comp.list[id_comp] = { + ...p.comp.list[id_comp], meta, tree, async on_update(bin, origin) { 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 5bd1b657..7ec9217d 100644 --- a/app/web/src/nova/ed/logic/tree/sync-walk.tsx +++ b/app/web/src/nova/ed/logic/tree/sync-walk.tsx @@ -295,6 +295,11 @@ export const loadComponent = async ( } return new Promise((resolve) => { + if (p.comp.list[id_comp]) { + resolve(true); + return; + } + console.log("loading", id_comp); loadcomp.pending.add(id_comp); clearTimeout(loadcomp.timeout); loadcomp.timeout = setTimeout(async () => {