From 7724d7696db759d813b2fd26aee6a6e24683aae5 Mon Sep 17 00:00:00 2001 From: Rizky Date: Fri, 1 Dec 2023 23:03:41 +0700 Subject: [PATCH] wip fix component_not_found --- app/srv/ws/sync/actions/comp_load.ts | 2 +- app/srv/ws/sync/actions/page_load.ts | 6 ++-- app/srv/ws/sync/editor/load-page.ts | 25 +++++++------- .../src/nova/ed/logic/tree/sync-walk-comp.tsx | 33 +++++++++++++++---- app/web/src/nova/ed/logic/tree/sync-walk.tsx | 27 ++++++++++----- .../src/nova/ed/panel/popup/script/scope.tsx | 10 ++++-- 6 files changed, 70 insertions(+), 33 deletions(-) diff --git a/app/srv/ws/sync/actions/comp_load.ts b/app/srv/ws/sync/actions/comp_load.ts index a3939c7a..ea9972e2 100644 --- a/app/srv/ws/sync/actions/comp_load.ts +++ b/app/srv/ws/sync/actions/comp_load.ts @@ -32,7 +32,7 @@ const scanMeta = async (id: string, doc: DComp, sync: SyncConnection) => { const name = mitem.get("name") || ""; await serverWalkLoad(mitem, scope_comps, sync, loaded); serverWalkMap( - { sync, scope, scope_comps }, + { sync, scope, scope_comps, note: "comp-load" }, { mitem, parent_item: { id: "root" }, diff --git a/app/srv/ws/sync/actions/page_load.ts b/app/srv/ws/sync/actions/page_load.ts index c0d44c99..860e0163 100644 --- a/app/srv/ws/sync/actions/page_load.ts +++ b/app/srv/ws/sync/actions/page_load.ts @@ -63,8 +63,8 @@ export const page_load: SAction["page"]["load"] = async function ( data.page_id = id_page; return data; }); - }; - + }; + if (!snap && !ydoc) { const page = await db.page.findFirst({ where: { id } }); @@ -184,7 +184,7 @@ const scanMeta = async (doc: DPage, sync: SyncConnection) => { ); childs.map((m, i) => { serverWalkMap( - { sync, scope, scope_comps }, + { sync, scope, scope_comps, note: "page-load" }, { mitem: m, parent_item: { id: "root" }, diff --git a/app/srv/ws/sync/editor/load-page.ts b/app/srv/ws/sync/editor/load-page.ts index c075bc48..79a554fa 100644 --- a/app/srv/ws/sync/editor/load-page.ts +++ b/app/srv/ws/sync/editor/load-page.ts @@ -22,8 +22,7 @@ export const serverWalkLoad = async ( sync: SyncConnection, loaded: Set ) => { - - if (typeof mitem.get !== 'function') { + if (typeof mitem.get !== "function") { return; } @@ -96,6 +95,7 @@ export const serverWalkMap = ( sync: SyncConnection; scope: IScope; scope_comps: IScopeComp; + note: string; }, arg: { mitem: MItem; @@ -146,7 +146,7 @@ export const serverWalkMap = ( mitem, mcomp: mitem, scope, - mcontent(mcontent) { }, + mcontent(mcontent) {}, }); p.scope[item.id] = { p: arg.parent_ids, @@ -287,12 +287,12 @@ export const serverWalkMap = ( parent_item: { id: item.id, mitem: mitem as MItem }, parent_mcomp: jsx.parent_mcomp ? { - ...jsx.parent_mcomp, - parent_ids: [ - ...(arg.parent_ids || []), - mitem.get("id") || "", - ], - } + ...jsx.parent_mcomp, + parent_ids: [ + ...(arg.parent_ids || []), + mitem.get("id") || "", + ], + } : undefined, parent_ids: [...arg.parent_ids, mitem.get("id") || ""], }); @@ -311,15 +311,16 @@ export const serverWalkMap = ( } const childs = mitem.get("childs")?.map((e) => e) || []; + for (const e of childs) { serverWalkMap(p, { mitem: e, parent_item: { id: item.id, mitem: mitem as MItem }, parent_mcomp: !!arg.parent_mcomp ? { - ...arg.parent_mcomp, - parent_ids: [...(arg.parent_mcomp?.parent_ids || []), item.id], - } + ...arg.parent_mcomp, + parent_ids: [...(arg.parent_mcomp?.parent_ids || []), item.id], + } : undefined, parent_ids: [...arg.parent_ids, item.id], }); 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 c091f203..00ed4a9f 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 @@ -1,10 +1,16 @@ 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 { EdMeta, IScope, PG, active } from "../ed-global"; import { treeRebuild } from "./build"; -import { loadComponent, syncWalkLoad, syncWalkMap } from "./sync-walk"; -import { MItem } from "../../../../utils/types/item"; +import { + loadComponent, + loadcomp, + syncWalkLoad, + syncWalkMap, +} from "./sync-walk"; +import { waitUntil } from "web-utils"; export const loadCompSnapshot = async ( p: PG, @@ -26,7 +32,7 @@ export const loadCompSnapshot = async ( scope: scope, } as any; - const { tree, meta } = await walkCompTree(p, mitem); + const { tree, meta } = await walkCompTree(p, mitem, id_comp); p.comp.list[id_comp] = { ...p.comp.list[id_comp], meta, @@ -48,7 +54,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); + 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); @@ -71,14 +77,14 @@ export const loadCompSnapshot = async ( } }; -const walkCompTree = async (p: PG, mitem: MItem) => { +const walkCompTree = async (p: PG, mitem: MItem, comp_id: string) => { const tree: NodeModel[] = []; const meta = {}; const portal = { in: {} as Record, out: {} as Record, }; - await syncWalkLoad(p, mitem, (id) => loadComponent(p, id)); + syncWalkLoad(p, mitem, (id) => loadComponent(p, id)); syncWalkMap( { @@ -87,7 +93,20 @@ const walkCompTree = async (p: PG, mitem: MItem) => { item_loading: p.ui.tree.item_loading, meta, tree, - warn_component_loaded: false, + 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, 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 d9c98176..1ae559a9 100644 --- a/app/web/src/nova/ed/logic/tree/sync-walk.tsx +++ b/app/web/src/nova/ed/logic/tree/sync-walk.tsx @@ -12,6 +12,8 @@ import { ensureMProp, ensurePropContent, } from "./sync-walk-utils"; +import { treeRebuild } from "./build"; +import { waitUntil } from "web-utils"; const comp_added = new Set(); @@ -63,7 +65,7 @@ export const syncWalkMap = ( tree?: NodeModel[]; comps: PG["comp"]["list"]; meta: Record; - warn_component_loaded?: boolean; + component_not_found?: (comp_id: string) => void; }, arg: { is_layout: boolean; @@ -81,7 +83,9 @@ export const syncWalkMap = ( } ) => { const { mitem, parent_item, parent_mcomp } = arg; - if (typeof mitem.get !== "function") { return } + if (typeof mitem.get !== "function") { + return; + } const item = {} as unknown as IItem; @@ -118,7 +122,7 @@ export const syncWalkMap = ( mapItem(mitem, item); } - if (typeof item.name !== 'string') return; + if (typeof item.name !== "string") return; if (override_id) { if (!item.originalId) item.originalId = item.id; @@ -138,11 +142,13 @@ export const syncWalkMap = ( }; if (item_comp && item_comp.id && parent_item.id !== "root") { - if (!p.comps[item_comp.id] && p.warn_component_loaded !== false) { - throw new Error("Component failed to load: " + item_comp.id); + if (!p.comps[item_comp.id]) { + if (p.component_not_found) { + p.component_not_found(item_comp.id); + } } - const ref_comp = p.comps[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"); @@ -153,6 +159,7 @@ export const syncWalkMap = ( mitem_comp.set("ref_ids", new Y.Map() as any); ref_ids = {}; } + const old_id = item.id; mapItem(mcomp, item, ref_ids); @@ -300,7 +307,10 @@ export const syncWalkMap = ( } }; -export const loadcomp = { timeout: 0 as any, pending: new Set() }; +export const loadcomp = { + timeout: 0 as any, + pending: new Set(), +}; export const loadComponent = async (p: PG, id_comp: string) => { return new Promise((resolve) => { @@ -308,6 +318,7 @@ export const loadComponent = async (p: PG, id_comp: string) => { resolve(true); return; } + loadcomp.pending.add(id_comp); clearTimeout(loadcomp.timeout); loadcomp.timeout = setTimeout(async () => { @@ -345,7 +356,7 @@ const mapItem = ( item[k] = []; const childs = e as unknown as TypedArray<{}>; childs.forEach((c) => { - if (typeof c.get === 'function') { + if (typeof c.get === "function") { if (ref_ids) { const id = ref_ids[c.get("id")]; if (id) { diff --git a/app/web/src/nova/ed/panel/popup/script/scope.tsx b/app/web/src/nova/ed/panel/popup/script/scope.tsx index 9a9f28ba..a8482d7f 100644 --- a/app/web/src/nova/ed/panel/popup/script/scope.tsx +++ b/app/web/src/nova/ed/panel/popup/script/scope.tsx @@ -1,6 +1,7 @@ import type { OnMount } from "@monaco-editor/react"; import { deepClone } from "web-utils"; import { EPage, ISingleScope, PG, active } from "../../../logic/ed-global"; +import { getMetaById } from "../../../logic/tree/build"; type Monaco = Parameters[1]; export type MonacoEditor = Parameters[0]; @@ -10,6 +11,9 @@ export const declareScope = async ( monaco: Monaco ) => { let active_id = active.item_id; + const meta = getMetaById(p, active_id); + const parent = getMetaById(p, meta?.parent_item.id); + let s = deepClone(p.page.scope[active_id]); if (active.comp_id && p.comp.list[active.comp_id]) { @@ -49,7 +53,8 @@ export const declareScope = async ( if (arg.type !== "local") { addScope( monaco, - `${arg.comp_id || ""}~${prev?.comp_id || ""}~${prev?.item_id || ""}__${arg.type + `${arg.comp_id || ""}~${prev?.comp_id || ""}~${prev?.item_id || ""}__${ + arg.type }~${arg.name}~${arg.id}`, `\ export const {}; @@ -60,7 +65,8 @@ declare global { } else { addScope( monaco, - `${arg.comp_id || ""}~${prev?.comp_id || ""}~${prev?.item_id || ""}__${arg.type + `${arg.comp_id || ""}~${prev?.comp_id || ""}~${prev?.item_id || ""}__${ + arg.type }~${arg.id}`, `\ export const {};