From 9bbc3a3d8fc00db702c695a0f8fbdf04d4a01375 Mon Sep 17 00:00:00 2001 From: Rizky Date: Wed, 13 Dec 2023 09:48:04 +0700 Subject: [PATCH] wip fix --- app/srv/ws/sync/actions/page_load.ts | 2 +- app/srv/ws/sync/editor/parser/parse-js.ts | 11 ++-- app/web/src/nova/ed/logic/ed-init.ts | 3 + app/web/src/nova/ed/logic/ed-route.ts | 1 + app/web/src/nova/ed/logic/tree/build.tsx | 11 ++-- .../ed/panel/side/prop-master/prop-form.tsx | 5 +- app/web/src/nova/vi/load/load-legacy.tsx | 7 ++- app/web/src/nova/vi/render/comp.tsx | 9 --- app/web/src/nova/vi/render/script.tsx | 23 +++++-- .../src/nova/vi/render/script/eval-prop.tsx | 63 +++++++++++++++++++ .../src/nova/vi/render/script/scope-meta.ts | 14 +++-- app/web/src/nova/view/logic/meta/comp.tsx | 9 ++- .../nova/view/logic/meta/comp/instantiate.tsx | 8 ++- app/web/src/nova/view/logic/meta/meta.tsx | 6 -- 14 files changed, 128 insertions(+), 44 deletions(-) delete mode 100644 app/web/src/nova/vi/render/comp.tsx create mode 100644 app/web/src/nova/vi/render/script/eval-prop.tsx diff --git a/app/srv/ws/sync/actions/page_load.ts b/app/srv/ws/sync/actions/page_load.ts index 309afde0..450443af 100644 --- a/app/srv/ws/sync/actions/page_load.ts +++ b/app/srv/ws/sync/actions/page_load.ts @@ -222,7 +222,7 @@ const scanMeta = async (doc: DPage, sync: SyncConnection) => { on: { visit(meta) { if (typeof meta.item.adv?.js === "string") { - meta.scope.def = parseJs(meta.item.adv.js); + meta.scope.def = parseJs(meta); } }, }, diff --git a/app/srv/ws/sync/editor/parser/parse-js.ts b/app/srv/ws/sync/editor/parser/parse-js.ts index 12898f14..4dc21c9f 100644 --- a/app/srv/ws/sync/editor/parser/parse-js.ts +++ b/app/srv/ws/sync/editor/parser/parse-js.ts @@ -1,13 +1,16 @@ import recast from "recast"; import babel from "recast/parsers/babel-ts"; +import { IMeta } from "../../../../../web/src/nova/ed/logic/ed-global"; -export const parseJs = (code: string) => { +export const parseJs = (meta: IMeta) => { + const code = meta.item.adv?.js; + if (!code) return undefined; const local = { name: "", value: "", index: 0 }; const passprop: Record = {}; const result = {} as { - local: typeof local | undefined; - passprop: typeof passprop | undefined; - props: Record; + local?: typeof local | undefined; + passprop?: typeof passprop | undefined; + props?: Record; }; try { diff --git a/app/web/src/nova/ed/logic/ed-init.ts b/app/web/src/nova/ed/logic/ed-init.ts index 65dc435d..41ef0662 100644 --- a/app/web/src/nova/ed/logic/ed-init.ts +++ b/app/web/src/nova/ed/logic/ed-init.ts @@ -2,6 +2,7 @@ import init from "wasm-gzip"; import { PG } from "./ed-global"; import { jscript } from "../../../utils/script/jscript"; import { viLoadLegacy } from "../../vi/load/load-legacy"; +import { treeRebuild } from "./tree/build"; export const edInit = async (p: PG) => { p.status = "ready"; @@ -34,5 +35,7 @@ export const edInit = async (p: PG) => { }); p.script.loaded = true; + + treeRebuild(p); p.render(); }; diff --git a/app/web/src/nova/ed/logic/ed-route.ts b/app/web/src/nova/ed/logic/ed-route.ts index 50a61372..c63aeb18 100644 --- a/app/web/src/nova/ed/logic/ed-route.ts +++ b/app/web/src/nova/ed/logic/ed-route.ts @@ -56,6 +56,7 @@ export const reloadPage = async (p: PG, page_id: string, note: string) => { } p.page.entry = remotePage.entry; + p.page.smeta = remotePage.meta; p.page.cur = remotePage; diff --git a/app/web/src/nova/ed/logic/tree/build.tsx b/app/web/src/nova/ed/logic/tree/build.tsx index 114c9b79..640f7c49 100644 --- a/app/web/src/nova/ed/logic/tree/build.tsx +++ b/app/web/src/nova/ed/logic/tree/build.tsx @@ -1,4 +1,10 @@ import { IItem, MItem } from "../../../../utils/types/item"; +import { viEvalScript } from "../../../vi/render/script"; +import { viEvalProps } from "../../../vi/render/script/eval-prop"; +import { + getScopeMeta, + getScopeValue, +} from "../../../vi/render/script/scope-meta"; import { genMeta } from "../../../view/logic/meta/meta"; import { IMeta, PG, active } from "../ed-global"; import { pushTreeNode } from "./build/push-tree"; @@ -27,6 +33,7 @@ export const treeRebuild = async (p: PG, arg?: { note?: string }) => { const meta: Record = {}; p.page.tree = []; + for (const mitem of mitems) { const item = mitem.toJSON() as IItem; if (item) { @@ -40,10 +47,6 @@ export const treeRebuild = async (p: PG, arg?: { note?: string }) => { if (!is_layout) { pushTreeNode(p, m, meta); } - - // if (m.item.adv?.jsBuilt) { - // viEvalScript({ meta: p.page.meta }, m); - // } }, }, }, diff --git a/app/web/src/nova/ed/panel/side/prop-master/prop-form.tsx b/app/web/src/nova/ed/panel/side/prop-master/prop-form.tsx index e7902e29..fbdee116 100644 --- a/app/web/src/nova/ed/panel/side/prop-master/prop-form.tsx +++ b/app/web/src/nova/ed/panel/side/prop-master/prop-form.tsx @@ -93,7 +93,7 @@ export const EdPropPopoverForm: FC<{ mprop: FMCompDef; name: string }> = ({ onBlur={() => { if (local.name !== name) { const keys = Object.keys(mprop.parent?.toJSON()); - if ([...keys, ...keywords].includes(local.name)) { + if ([...keys, ...invalidKeyword].includes(local.name)) { alert(`Cannot use "${local.name}" as name`); local.name = name; local.render(); @@ -226,7 +226,7 @@ export const EdPropPopoverForm: FC<{ mprop: FMCompDef; name: string }> = ({ ); }; -const keywords = [ +export const invalidKeyword = [ "await", "break", "case", @@ -273,4 +273,5 @@ const keywords = [ "while", "with", "yield", + "key", ]; diff --git a/app/web/src/nova/vi/load/load-legacy.tsx b/app/web/src/nova/vi/load/load-legacy.tsx index 5fe6511d..66896705 100644 --- a/app/web/src/nova/vi/load/load-legacy.tsx +++ b/app/web/src/nova/vi/load/load-legacy.tsx @@ -35,15 +35,18 @@ export const viLoadLegacy = async (vi: { } } + let api_url = vi.site.api_url; + if (!api_url) api_url = ((site.config as any) || {}).api_url || ""; + await initApi(site.config); const path = `/npm/site/${vi.site.id}/site.js`; await importModule(path); if (!vi.site.db.get()) { - vi.site.db.set(createDB(vi.site.api_url)); + vi.site.db.set(createDB(api_url)); } if (!vi.site.api.get()) { - vi.site.api.set(createAPI(vi.site.api_url)); + vi.site.api.set(createAPI(api_url)); } const w = window as any; diff --git a/app/web/src/nova/vi/render/comp.tsx b/app/web/src/nova/vi/render/comp.tsx deleted file mode 100644 index 56a7ba5d..00000000 --- a/app/web/src/nova/vi/render/comp.tsx +++ /dev/null @@ -1,9 +0,0 @@ -import { IMeta } from "../../ed/logic/ed-global"; -import { VG } from "./global"; - -export const viEvalProps = async (ctx: VG, meta: IMeta) => { - if (meta.item.component?.props) { - for (const [k, v] of Object.entries(meta.item.component.props)) { - } - } -}; diff --git a/app/web/src/nova/vi/render/script.tsx b/app/web/src/nova/vi/render/script.tsx index 2b9627af..b62836b9 100644 --- a/app/web/src/nova/vi/render/script.tsx +++ b/app/web/src/nova/vi/render/script.tsx @@ -7,18 +7,30 @@ import { viParts } from "./parts"; import { ViRender } from "./render"; import { createViLocal } from "./script/local"; import { createViPassProp } from "./script/passprop"; -import { getScope } from "./script/scope-meta"; +import { getScopeMeta, getScopeValue } from "./script/scope-meta"; +import { viEvalProps } from "./script/eval-prop"; export const ViScript: FC<{ meta: IMeta }> = ({ meta }) => { const vi = useGlobal(ViGlobal, "VI"); - viEvalScript(vi, meta); + const scope_meta = getScopeMeta(vi, meta); + const scope = getScopeValue(scope_meta); + + if (meta.item.component?.id) { + viEvalProps(vi, meta, scope); + } + + viEvalScript(vi, meta, scope); if (meta.script) return meta.script.result; return null; }; -export const viEvalScript = (vi: { meta: VG["meta"] }, meta: IMeta) => { +export const viEvalScript = ( + vi: { meta: VG["meta"] }, + meta: IMeta, + scope: any +) => { const childs = meta.item.childs; const parts = viParts(meta); @@ -31,8 +43,6 @@ export const viEvalScript = (vi: { meta: VG["meta"] }, meta: IMeta) => { }); } - const scope = getScope(vi, meta); - if (!meta.script) { meta.script = { result: null, @@ -47,6 +57,7 @@ export const viEvalScript = (vi: { meta: VG["meta"] }, meta: IMeta) => { useEffect, children, props: parts.props, + isEditor: true, Local: script.Local, PassProp: script?.PassProp, ErrorBox: ErrorBox, @@ -60,7 +71,7 @@ export const viEvalScript = (vi: { meta: VG["meta"] }, meta: IMeta) => { const fn = new Function( ...Object.keys(arg), - `// [${meta.item.type}] ${meta.item.name}: ${meta.item.id} + `// ${meta.item.name}: ${meta.item.id} ${meta.item.adv?.jsBuilt || ""} ` ); diff --git a/app/web/src/nova/vi/render/script/eval-prop.tsx b/app/web/src/nova/vi/render/script/eval-prop.tsx new file mode 100644 index 00000000..4f4ca09a --- /dev/null +++ b/app/web/src/nova/vi/render/script/eval-prop.tsx @@ -0,0 +1,63 @@ +import { IMeta } from "../../../ed/logic/ed-global"; +import { invalidKeyword } from "../../../ed/panel/side/prop-master/prop-form"; +import { VG } from "../global"; +import { getScopeMeta, getScopeValue } from "./scope-meta"; + +export const viEvalProps = ( + vi: { meta: VG["meta"] }, + meta: IMeta, + scope: any +) => { + if (meta.item.component?.id) { + if (!meta.scope.def) { + meta.scope.def = {}; + } + + if (!meta.scope.val) { + meta.scope.val = {}; + } + + const exports = (window as any).exports; + const arg = { + ...exports, + ...scope, + isEditor: true, + }; + + meta.scope.def.props = {}; + let fails = new Set(); + for (const [name, prop] of Object.entries(meta.item.component.props)) { + try { + const fn = new Function( + ...Object.keys(arg), + `// [${meta.item.name}] ${name}: ${meta.item.id} + return ${prop.valueBuilt || ""} + ` + ); + meta.scope.def.props[name] = prop.value; + meta.scope.val[name] = fn(...Object.values(arg)); + scope[name] = meta.scope.val[name]; + arg[name] = scope[name]; + } catch (e) { + fails.add(name); + } + } + + if (fails.size > 0) { + for (const [name, prop] of Object.entries(meta.item.component.props)) { + if (fails.has(name) && !invalidKeyword.includes(name)) { + const fn = new Function( + ...Object.keys(arg), + `// [${meta.item.name}] ${name}: ${meta.item.id} + return ${prop.valueBuilt || ""} + ` + ); + meta.scope.def.props[name] = prop.value; + meta.scope.val[name] = fn(...Object.values(arg)); + scope[name] = meta.scope.val[name]; + arg[name] = scope[name]; + } + } + } + } +}; diff --git a/app/web/src/nova/vi/render/script/scope-meta.ts b/app/web/src/nova/vi/render/script/scope-meta.ts index 816f5413..73696e78 100644 --- a/app/web/src/nova/vi/render/script/scope-meta.ts +++ b/app/web/src/nova/vi/render/script/scope-meta.ts @@ -1,7 +1,11 @@ import { IMeta } from "../../../ed/logic/ed-global"; import { VG } from "../global"; -const getScopeMeta = (vi: { meta: VG["meta"] }, meta: IMeta) => { +export const getScopeMeta = ( + vi: { meta: VG["meta"] }, + meta: IMeta, + debug?: boolean +) => { let cur = meta; const scopes_meta: IMeta[] = []; @@ -39,7 +43,7 @@ const getScopeMeta = (vi: { meta: VG["meta"] }, meta: IMeta) => { return scope_meta; }; -const getScopeValue = (scope_meta: ReturnType) => { +export const getScopeValue = (scope_meta: ReturnType) => { const scope: any = {}; for (const [varname, s] of Object.entries(scope_meta)) { @@ -51,8 +55,6 @@ const getScopeValue = (scope_meta: ReturnType) => { return scope; }; -export const getScope = (vi: { meta: VG["meta"] }, meta: IMeta) => { - const scope_meta = getScopeMeta(vi, meta); +// export const getScope = (vi: { meta: VG["meta"] }, meta: IMeta) => { - return getScopeValue(scope_meta); -}; +// }; diff --git a/app/web/src/nova/view/logic/meta/comp.tsx b/app/web/src/nova/view/logic/meta/comp.tsx index b9480745..58982109 100644 --- a/app/web/src/nova/view/logic/meta/comp.tsx +++ b/app/web/src/nova/view/logic/meta/comp.tsx @@ -47,12 +47,17 @@ export const genComp = (p: GenMetaP, arg: GenMetaArg) => { item: simplifyItemChild(item), parent: { id: arg.parent.item.id, - comp_id: arg.parent?.comp?.id, + comp_id: arg.parent?.comp?.component?.id, + instance_id: arg.parent?.instance_id, }, instances, scope: {}, }; + if (p.smeta?.[item.id]) { + meta.scope.def = p.smeta[item.id].scope; + } + if (item.id) { if (p.set_meta !== false) { p.meta[item.id] = meta; @@ -102,7 +107,7 @@ export const genComp = (p: GenMetaP, arg: GenMetaArg) => { } for (const child of Object.values(item.childs)) { - if (child.name.startsWith('jsx:')) continue; + if (child.name.startsWith("jsx:")) continue; genMeta(p, { item: child, is_root: false, diff --git a/app/web/src/nova/view/logic/meta/comp/instantiate.tsx b/app/web/src/nova/view/logic/meta/comp/instantiate.tsx index 80262328..9a154d2a 100644 --- a/app/web/src/nova/view/logic/meta/comp/instantiate.tsx +++ b/app/web/src/nova/view/logic/meta/comp/instantiate.tsx @@ -17,8 +17,12 @@ export const instantiate = (arg: { newitem.id = item.id; } - if (item.component) { - newitem.component = item.component; + if (newitem.component && item.component) { + for (const k of Object.keys(newitem.component.props)) { + if (item.component.props[k]) { + newitem.component.props[k] = item.component.props[k]; + } + } } for (const key of Object.keys(item)) { diff --git a/app/web/src/nova/view/logic/meta/meta.tsx b/app/web/src/nova/view/logic/meta/meta.tsx index aa8cdc01..a4848508 100644 --- a/app/web/src/nova/view/logic/meta/meta.tsx +++ b/app/web/src/nova/view/logic/meta/meta.tsx @@ -4,11 +4,6 @@ import { simplifyItemChild } from "./simplify"; import { GenMetaArg, GenMetaP, IMeta } from "./types"; export const genMeta = (p: GenMetaP, arg: GenMetaArg) => { - // let wrapper = (fn: any) => { - // fn(); - // }; - - // wrapper(() => { const item = arg.item as IItem; if (item.type === "item" && item.component?.id) { @@ -64,5 +59,4 @@ export const genMeta = (p: GenMetaP, arg: GenMetaArg) => { }); } } - // }); };