wip fix component loading

This commit is contained in:
Rizky 2023-11-26 14:45:47 +07:00
parent 212c8686f1
commit 722ff572f2
6 changed files with 55 additions and 79 deletions

View File

@ -37,7 +37,6 @@ export const edRoute = async (p: PG) => {
}
};
const loaded = new Set<string>();
export const reloadPage = async (p: PG, page_id: string, note: string) => {
p.status = "loading";
const remotePage = await p.sync.page.load(page_id);
@ -52,7 +51,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, loaded, c.snapshot, c.scope);
await loadCompSnapshot(p, id_comp, c.snapshot, c.scope);
}
}
}

View File

@ -1,13 +1,12 @@
import { waitUntil } from "web-utils";
import { EdMeta, PG } from "../ed-global";
import {
component,
loadComponent,
loadcomp,
syncWalkLoad,
syncWalkMap,
} from "./sync-walk";
export const compLoaded = new Set<string>();
export const treeRebuild = async (p: PG, arg?: { note?: string }) => {
const doc = p.page.doc;
if (!doc) return;
@ -34,16 +33,17 @@ export const treeRebuild = async (p: PG, arg?: { note?: string }) => {
if (lroot) {
const sections = lroot.get("childs");
if (sections) {
const loaded = new Set<string>();
await Promise.all(
sections.map((e) => {
return syncWalkLoad(p, e, loaded, (id) => {
return loadComponent(p, id, loaded);
});
})
);
sections.map((e) => {
return syncWalkLoad(p, e, (id) => {
return loadComponent(p, id);
});
});
if (component.pending) await component.pending;
if (loadcomp.pending.size > 0) {
await waitUntil(() => {
return loadcomp.pending.size === 0;
});
}
sections.map((e) => {
if (p.page.root_id === "root") {
@ -98,15 +98,17 @@ export const treeRebuild = async (p: PG, arg?: { note?: string }) => {
const sections = root.get("childs");
if (sections) {
await Promise.all(
sections.map((e) => {
return syncWalkLoad(p, e, compLoaded, (id) => {
return loadComponent(p, id, compLoaded);
});
})
);
sections.map((e) => {
return syncWalkLoad(p, e, (id) => {
return loadComponent(p, id);
});
});
if (component.pending) await component.pending;
if (loadcomp.pending.size > 0) {
await waitUntil(() => {
return loadcomp.pending.size === 0;
});
}
}
doc.transact(async () => {

View File

@ -9,14 +9,9 @@ import { MItem } from "../../../../utils/types/item";
export const loadCompSnapshot = async (
p: PG,
id_comp: string,
loaded: Set<string>,
snapshot: Uint8Array,
scope: IScope
) => {
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,15 +19,14 @@ export const loadCompSnapshot = async (
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,
scope: scope,
} as any;
const { tree, meta } = await walkCompTree(p, mitem, loaded);
const { tree, meta } = await walkCompTree(p, mitem);
p.comp.list[id_comp] = {
...p.comp.list[id_comp],
meta,
@ -54,7 +48,7 @@ export const loadCompSnapshot = async (
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, loaded);
const { tree, meta } = await walkCompTree(p, mitem);
p.comp.list[id_comp].tree = tree;
p.comp.list[id_comp].meta = meta;
await treeRebuild(p);
@ -77,14 +71,14 @@ export const loadCompSnapshot = async (
}
};
const walkCompTree = async (p: PG, mitem: MItem, loaded: Set<string>) => {
const walkCompTree = async (p: PG, mitem: MItem) => {
const tree: NodeModel<EdMeta>[] = [];
const meta = {};
const portal = {
in: {} as Record<string, EdMeta>,
out: {} as Record<string, EdMeta>,
};
await syncWalkLoad(p, mitem, loaded, (id) => loadComponent(p, id, loaded));
await syncWalkLoad(p, mitem, (id) => loadComponent(p, id));
syncWalkMap(
{

View File

@ -13,39 +13,38 @@ import {
ensurePropContent,
} from "./sync-walk-utils";
const comp_added = new Set<string>();
export const syncWalkLoad = async (
p: PG,
mitem: MItem,
loaded: Set<string>,
loadComponent: (id: string) => Promise<boolean>
) => {
const mcomp = mitem.get("component");
if (mcomp) {
const id = mcomp.get("id");
const comp = mcomp.toJSON() as FNComponent;
if (id) {
const isFirstLoaded = !loaded.has(id);
loaded.add(id);
if (!p.comp.list[id] && isFirstLoaded) {
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 && isFirstLoaded) {
await syncWalkLoad(p, pitem, loaded, loadComponent);
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, loaded, 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);
}
}
}
}
@ -53,7 +52,7 @@ export const syncWalkLoad = async (
}
for (const e of mitem.get("childs")?.map((e) => e) || []) {
await syncWalkLoad(p, e, loaded, loadComponent);
await syncWalkLoad(p, e, loadComponent);
}
};
@ -130,8 +129,7 @@ export const syncWalkMap = (
if (item_comp && item_comp.id && parent_item.id !== "root") {
if (!p.comps[item_comp.id] && p.warn_component_loaded !== false) {
console.error("Component failed to load: ", item_comp.id);
return;
throw new Error("Component failed to load: " + item_comp.id);
}
const ref_comp = p.comps[item_comp.id];
@ -276,22 +274,9 @@ export const syncWalkMap = (
}
};
const loadcomp = { timeout: 0 as any, pending: new Set<string>() };
export const component = {
pending: null as null | Promise<void>,
resolve: null as null | (() => void),
};
export const loadComponent = async (
p: PG,
id_comp: string,
loaded: Set<string>
) => {
if (!component.pending) {
component.pending = new Promise((resolve) => {
component.resolve = resolve;
});
}
export const loadcomp = { timeout: 0 as any, pending: new Set<string>() };
export const loadComponent = async (p: PG, id_comp: string) => {
return new Promise<boolean>((resolve) => {
if (p.comp.list[id_comp]) {
resolve(true);
@ -302,21 +287,16 @@ export const loadComponent = async (
loadcomp.timeout = setTimeout(async () => {
const comps = await p.sync.comp.load([...loadcomp.pending]);
let result = Object.entries(comps);
loadcomp.pending.clear();
for (const [id_comp, comp] of result) {
for (const cur of Object.values(comp)) {
if (cur && cur.snapshot) {
await loadCompSnapshot(p, id_comp, loaded, cur.snapshot, cur.scope);
await loadCompSnapshot(p, id_comp, cur.snapshot, cur.scope);
}
}
}
loadcomp.pending.clear();
resolve(result.length > 0);
if (component.resolve) {
component.resolve();
component.pending = null;
component.resolve = null;
}
}, 150);
});
};

View File

@ -2,7 +2,6 @@ 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";
import { code } from "../popup/code/code";
@ -17,7 +16,7 @@ export const EdMain = () => {
`
)}
>
<div className="absolute overflow-auto inset-0">
<div className="absolute overflow-auto inset-0 flex">
{!!p.page.building && <Loading backdrop={false} />}
{!p.page.building && code.mode !== "" && (
<View
@ -28,7 +27,7 @@ export const EdMain = () => {
api_url={p.site.config.api_url}
component={{
async load(id_comp) {
await loadComponent(p, id_comp, compLoaded);
await loadComponent(p, id_comp);
},
}}
load={{

View File

@ -1,3 +1,5 @@
import { VG } from "./global";
export const oldLoadCode = (v: VG) => {};
export const oldLoadCode = (v: VG) => {
v.status = "ready";
};