From 374ee6a49c0ca9b7fcb3174ab43787c89d0f557f Mon Sep 17 00:00:00 2001 From: Rizky Date: Fri, 24 Nov 2023 22:12:17 +0700 Subject: [PATCH] wip fix content --- app/srv/ws/sync/actions/comp_load.ts | 32 +-- app/srv/ws/sync/editor/load-page-comp.ts | 45 ++++ app/srv/ws/sync/editor/load-page.ts | 241 +++++++++--------- .../src/nova/ed/panel/popup/script/monaco.tsx | 6 +- .../src/nova/ed/panel/popup/script/scope.tsx | 44 +++- 5 files changed, 221 insertions(+), 147 deletions(-) create mode 100644 app/srv/ws/sync/editor/load-page-comp.ts diff --git a/app/srv/ws/sync/actions/comp_load.ts b/app/srv/ws/sync/actions/comp_load.ts index 5efd76b2..89e0d50e 100644 --- a/app/srv/ws/sync/actions/comp_load.ts +++ b/app/srv/ws/sync/actions/comp_load.ts @@ -27,28 +27,22 @@ const scanMeta = async (id: string, doc: DComp, sync: SyncConnection) => { const scope = {}; const scope_comps: IScopeComp = {}; const loaded = new Set(); - const root = doc.getMap("map").get("root"); - if (root) { - const name = root.get("name") || ""; - const childs = root.get("childs"); - if (childs) { - await Promise.all( - childs.map((m) => serverWalkLoad(m, scope_comps, sync, loaded)) - ); - childs.map((m, i) => { - serverWalkMap( - { sync, scope, scope_comps }, - { - mitem: m, - parent_item: { id: "root" }, - parent_ids: ["root"], - } - ); - }); - } + const mitem = doc.getMap("map").get("root"); + if (mitem) { + const name = mitem.get("name") || ""; + await serverWalkLoad(mitem, scope_comps, sync, loaded); + serverWalkMap( + { sync, scope, scope_comps }, + { + mitem, + parent_item: { id: "root" }, + parent_ids: ["root"], + } + ); const bin = Y.encodeStateAsUpdate(doc as any); const snapshot = await gzipAsync(bin); + scope_comps[id] = { id, name, scope, snapshot }; } diff --git a/app/srv/ws/sync/editor/load-page-comp.ts b/app/srv/ws/sync/editor/load-page-comp.ts new file mode 100644 index 00000000..38e11635 --- /dev/null +++ b/app/srv/ws/sync/editor/load-page-comp.ts @@ -0,0 +1,45 @@ +import { + ensureMItemProps, + ensureMProp, + ensurePropContent, +} from "../../../../web/src/nova/ed/logic/tree/sync-walk-utils"; +import { MItem } from "../../../../web/src/utils/types/item"; +import { + FNCompDef, + FNComponent, +} from "../../../../web/src/utils/types/meta-fn"; +import { parseJs } from "./parser/parse-js"; + +export const extractMItemProps = (arg: { + mitem: MItem; + item_comp: FNComponent; + mcomp: MItem; + scope: Exclude, undefined>; + mcontent: (mcontent: MItem) => void; +}) => { + const { mitem, item_comp, mcomp, scope } = arg; + + const mitem_comp = mitem.get("component"); + + const mprops = mcomp.get("component")?.get("props")?.toJSON() as Record< + string, + FNCompDef + >; + if (mitem_comp) { + const mitem_props = ensureMItemProps(mitem_comp, item_comp); + if (mitem_props) { + for (const [k, v] of Object.entries(mprops)) { + scope.props[k] = { name: k, value: `null as any` }; + const mprop = ensureMProp(mitem_props, k, v); + item_comp.props[k] = v; + if (mprop && v.meta?.type === "content-element") { + scope.props[k].value = "null as ReactElement"; + const mcontent = ensurePropContent(mprop, k); + if (mcontent) { + arg.mcontent(mcontent); + } + } + } + } + } +}; diff --git a/app/srv/ws/sync/editor/load-page.ts b/app/srv/ws/sync/editor/load-page.ts index 5e7ab225..ba8a9662 100644 --- a/app/srv/ws/sync/editor/load-page.ts +++ b/app/srv/ws/sync/editor/load-page.ts @@ -6,20 +6,18 @@ import { IScopeComp, } from "../../../../web/src/nova/ed/logic/ed-global"; import { - ensureMItemProps, - ensureMProp, - ensurePropContent, + ensurePropContent } from "../../../../web/src/nova/ed/logic/tree/sync-walk-utils"; import { MContent } from "../../../../web/src/utils/types/general"; import { IItem, MItem } from "../../../../web/src/utils/types/item"; import { - FNCompDef, - FNComponent, + FNComponent } from "../../../../web/src/utils/types/meta-fn"; import { docs } from "../entity/docs"; import { gzipAsync } from "../entity/zlib"; import { SyncConnection } from "../type"; import { loadComponent } from "./load-component"; +import { extractMItemProps } from "./load-page-comp"; import { parseJs } from "./parser/parse-js"; export const serverWalkLoad = async ( @@ -123,113 +121,126 @@ export const serverWalkMap = ( const item_comp = item.component; const mitem_comp = mitem.get("component"); - if (item_comp && item_comp.id && parent_item.id !== "root") { - if (!docs.comp[item_comp.id]) { - console.error("Component failed to load:", item_comp.id); - return; - } - - if (!p.scope_comps[item_comp.id]) { - console.error("Failed to assign component:", item_comp.id); - return; - } - - const ref_comp = docs.comp[item_comp.id]; - - if (ref_comp && mitem_comp) { - const mcomp = ref_comp.doc.getMap("map").get("root"); - - if (mcomp) { - let ref_ids: Record = item_comp.ref_ids; - if (!ref_ids) { - mitem_comp.set("ref_ids", new Y.Map() as any); - ref_ids = {}; - } - const original_id = item.id; - mapItem(mcomp, item); - item.id = original_id; - - const mprops = mcomp.get("component")?.get("props")?.toJSON() as Record< - string, - FNCompDef - >; - - const scope = { props: {} } as Exclude< - ReturnType, - undefined - >; - - 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)) { - scope.props[k] = { name: k, value: `null as any` }; - const mprop = ensureMProp(mitem_props, k, v); - item_comp.props[k] = v; - if (mprop && v.meta?.type === "content-element") { - scope.props[k].value = "null as ReactElement"; - const mcontent = ensurePropContent(mprop, k); - if (mcontent) { - serverWalkMap(p, { - parent_ids: [...arg.parent_ids, item.id], - mitem: mcontent, - parent_item: { id: item.id, mitem: mitem as MItem }, - is_prop: true, - parent_mcomp: { - id: item_comp.id, - mitem: mitem as MItem, - mcomp, - }, - }); - } - } - } - } - } - } - - const pcomp = p.scope_comps[item_comp.id]; - pcomp.scope[item.id] = { p: arg.parent_ids, n: item.name, s: null }; - const js = item.adv?.js; - if (typeof js === "string") { - const res = parseJs(js); - if (res) { - scope.local = res.local; - scope.passprop = res.passprop; - } - } - - if (scope) pcomp.scope[item.id].s = scope; - if (!parent_mcomp) { - p.scope[item.id] = { - p: arg.parent_ids, - n: item.name, - s: null, - }; - if (scope) p.scope[item.id].s = scope; - } - - const childs = mcomp.get("childs")?.map((e) => e) || []; - for (const e of childs) { - serverWalkMap(p, { - mitem: e, - parent_ids: [...arg.parent_ids, item.id], - parent_item: { - id: item.id, - mitem: mitem as MItem, - }, - parent_mcomp: { - id: item_comp.id, - mitem: mitem as MItem, - mcomp, - }, - }); + if (item_comp && item_comp.id) { + if (parent_item.id === "root") { + const scope = { props: {} } as Exclude< + ReturnType, + undefined + >; + extractMItemProps({ + item_comp, + mitem, + mcomp: mitem, + scope, + mcontent(mcontent) {}, + }); + p.scope[item.id] = { + p: arg.parent_ids, + n: item.name, + s: scope, + }; + const js = item.adv?.js; + if (typeof js === "string") { + const s = parseJs(js); + const ps = p.scope[item.id].s; + if (ps) { + if (s?.local) ps.local = s.local; + if (s?.passprop) ps.passprop = s.passprop; } } + } else { + if (!docs.comp[item_comp.id]) { + console.error("Component failed to load:", item_comp.id); + return; + } + + if (!p.scope_comps[item_comp.id]) { + console.error("Failed to assign component:", item_comp.id); + return; + } + + const ref_comp = docs.comp[item_comp.id]; + + if (ref_comp && mitem_comp) { + const mcomp = ref_comp.doc.getMap("map").get("root"); + + if (mcomp) { + let ref_ids: Record = item_comp.ref_ids; + if (!ref_ids) { + mitem_comp.set("ref_ids", new Y.Map() as any); + ref_ids = {}; + } + const original_id = item.id; + mapItem(mcomp, item); + item.id = original_id; + + const scope = { props: {} } as Exclude< + ReturnType, + undefined + >; + + extractMItemProps({ + item_comp, + mitem, + mcomp, + scope, + mcontent(mcontent) { + serverWalkMap(p, { + parent_ids: ["root", item.id], + mitem: mcontent, + parent_item: { id: item.id, mitem: mitem as MItem }, + is_prop: true, + parent_mcomp: { + id: item_comp.id, + mitem: mitem as MItem, + mcomp, + }, + }); + }, + }); + + const pcomp = p.scope_comps[item_comp.id]; + pcomp.scope[item.id] = { p: ["root"], n: item.name, s: null }; + + const js = item.adv?.js; + if (typeof js === "string") { + const res = parseJs(js); + if (res) { + scope.local = res.local; + scope.passprop = res.passprop; + } + } + + if (scope) pcomp.scope[item.id].s = scope; + if (!parent_mcomp) { + p.scope[item.id] = { + p: arg.parent_ids, + n: item.name, + s: null, + }; + if (scope) p.scope[item.id].s = scope; + } + + const childs = mcomp.get("childs")?.map((e) => e) || []; + for (const e of childs) { + serverWalkMap(p, { + mitem: e, + parent_ids: ["root", item.id], + parent_item: { + id: item.id, + mitem: mitem as MItem, + }, + parent_mcomp: { + id: item_comp.id, + mitem: mitem as MItem, + mcomp, + }, + }); + } + } + } + return; } - return; } if (arg.parent_mcomp && !arg.is_prop) { @@ -241,11 +252,13 @@ export const serverWalkMap = ( if (scope) pcomp.scope[item.id].s = scope; } } else { - p.scope[item.id] = { p: arg.parent_ids, n: item.name, s: null }; - const js = item.adv?.js; - if (typeof js === "string") { - const scope = parseJs(js); - if (scope) p.scope[item.id].s = scope; + if (!(item_comp && item_comp.id)) { + p.scope[item.id] = { p: arg.parent_ids, n: item.name, s: null }; + const js = item.adv?.js; + if (typeof js === "string") { + const scope = parseJs(js); + if (scope) p.scope[item.id].s = scope; + } } } diff --git a/app/web/src/nova/ed/panel/popup/script/monaco.tsx b/app/web/src/nova/ed/panel/popup/script/monaco.tsx index a5ba6fb7..8236d900 100644 --- a/app/web/src/nova/ed/panel/popup/script/monaco.tsx +++ b/app/web/src/nova/ed/panel/popup/script/monaco.tsx @@ -22,7 +22,11 @@ export const ScriptMonaco = () => { const Editor = jscript.editor; if (!Editor) return null; - const meta = p.page.meta[active.item_id]; + let meta = p.page.meta[active.item_id]; + if (active.comp_id) { + meta = p.comp.list[active.comp_id].meta[active.item_id]; + } + if (!meta) return null; const item = meta.item; 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 404f5897..893e7bec 100644 --- a/app/web/src/nova/ed/panel/popup/script/scope.tsx +++ b/app/web/src/nova/ed/panel/popup/script/scope.tsx @@ -9,8 +9,12 @@ export const declareScope = async ( editor: MonacoEditor, monaco: Monaco ) => { - const active_id = active.item_id; - const s = deepClone(p.page.scope[active_id]); + let active_id = active.item_id; + let s = deepClone(p.page.scope[active_id]); + + if (active.comp_id) { + s = deepClone(p.comp.list[active.comp_id].scope[active.item_id]); + } monaco.editor.getModels().forEach((model) => { if (model.uri.toString().startsWith("ts:scope~")) { @@ -37,18 +41,28 @@ export const declareScope = async ( }); spreadScope(p, s, (arg) => { - addScope( - monaco, - `${arg.type}~${arg.id}`, - `\ + if (arg.type !== "local") { + addScope( + monaco, + `${arg.type}~${arg.name}`, + `\ +export const {}; +declare global { + const ${arg.name} = ${arg.value}; +}` + ); + } else { + addScope( + monaco, + `${arg.type}~${arg.id}`, + `\ export const {}; const __val = ${arg.value}; declare global { - const ${arg.name}: typeof __val ${ - arg.type === "local" ? " & { render: ()=>void}" : "" - }; + const ${arg.name}: typeof __val & { render: ()=>void }; }` - ); + ); + } }); }; @@ -100,7 +114,11 @@ const spreadScope = ( } } if (!item) { - item = p.page.scope[parent_id]; + if (active.comp_id) { + item = p.comp.list[active.comp_id].scope[parent_id]; + } else { + item = p.page.scope[parent_id]; + } } if (item) { @@ -120,7 +138,7 @@ const spreadScope = ( for (const [k, v] of Object.entries(scope.passprop)) { each({ s, - type: "prop", + type: "passprop", id: parent_id, name: k, value: v.value, @@ -133,7 +151,7 @@ const spreadScope = ( for (const [k, v] of Object.entries(scope.props)) { each({ s, - type: "passprop", + type: "prop", id: parent_id, name: k, value: v.value,