diff --git a/app/web/src/nova/vi/render/comp.tsx b/app/web/src/nova/vi/render/comp.tsx index e70758b1..56a7ba5d 100644 --- a/app/web/src/nova/vi/render/comp.tsx +++ b/app/web/src/nova/vi/render/comp.tsx @@ -1,7 +1,7 @@ import { IMeta } from "../../ed/logic/ed-global"; -import { ViContext } from "./parts"; +import { VG } from "./global"; -export const viEvalProps = async (ctx: ViContext, meta: IMeta) => { +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/global.tsx b/app/web/src/nova/vi/render/global.tsx new file mode 100644 index 00000000..b92efd06 --- /dev/null +++ b/app/web/src/nova/vi/render/global.tsx @@ -0,0 +1,8 @@ +import { IMeta } from "../../ed/logic/ed-global"; + +export const ViGlobal = { + meta: {} as Record, + tick: 0, +}; + +export type VG = typeof ViGlobal; diff --git a/app/web/src/nova/vi/render/parts.tsx b/app/web/src/nova/vi/render/parts.tsx index c118883b..e9a79021 100644 --- a/app/web/src/nova/vi/render/parts.tsx +++ b/app/web/src/nova/vi/render/parts.tsx @@ -2,10 +2,6 @@ import { produceCSS } from "../../../utils/css/gen"; import { IContent } from "../../../utils/types/general"; import { IMeta } from "../../ed/logic/ed-global"; -export type ViContext = { - meta: Record; - tick: number; -}; export type ViParts = { mode: "mobile" | "desktop"; hover?: boolean; diff --git a/app/web/src/nova/vi/render/render.tsx b/app/web/src/nova/vi/render/render.tsx index 58289695..e942f946 100644 --- a/app/web/src/nova/vi/render/render.tsx +++ b/app/web/src/nova/vi/render/render.tsx @@ -1,18 +1,20 @@ import { FC, ReactNode, Suspense } from "react"; +import { useGlobal } from "web-utils"; import { IMeta } from "../../ed/logic/ed-global"; -import { ViContext, viParts } from "./parts"; -import { ViScript } from "./script"; import { ErrorBox } from "../utils/error-box"; +import { ViGlobal } from "./global"; +import { viParts } from "./parts"; +import { ViScript } from "./script"; export const ViRender: FC<{ - ctx: ViContext; meta: IMeta; children?: ReactNode; -}> = ({ meta, children, ctx }) => { +}> = ({ meta, children }) => { + const vi = useGlobal(ViGlobal, "VI"); if (!meta) return null; if (meta.item.adv?.js || meta.item.component?.id) { - return ; + return ; } const parts = viParts(meta); @@ -28,7 +30,7 @@ export const ViRender: FC<{ return ( - + ); diff --git a/app/web/src/nova/vi/render/script.tsx b/app/web/src/nova/vi/render/script.tsx index af5b0fa5..4393782d 100644 --- a/app/web/src/nova/vi/render/script.tsx +++ b/app/web/src/nova/vi/render/script.tsx @@ -1,23 +1,24 @@ import { FC, ReactNode } from "react"; +import { useGlobal } from "web-utils"; import { IMeta } from "../../ed/logic/ed-global"; -import { ViContext, viParts } from "./parts"; -import { ViRender } from "./render"; -import { ViLocal } from "./script/local"; -import { ViPassProp } from "./script/passprop"; -import { viScopeUpward } from "./script/upward"; import { ErrorBox } from "../utils/error-box"; +import { VG, ViGlobal } from "./global"; +import { viParts } from "./parts"; +import { ViRender } from "./render"; +import { createViLocal } from "./script/local"; +import { createViPassProp } from "./script/passprop"; +import { getScope } from "./script/scope-meta"; -export const ViScript: FC<{ ctx: ViContext; meta: IMeta }> = ({ - ctx, - meta, -}) => { - viEvalScript(ctx, meta); +export const ViScript: FC<{ meta: IMeta }> = ({ meta }) => { + const vi = useGlobal(ViGlobal, "VI"); - if (meta.script) return meta.script.el; + viEvalScript(vi, meta); + + if (meta.script) return meta.script.result; return null; }; -export const viEvalScript = (ctx: ViContext, meta: IMeta) => { +export const viEvalScript = (vi: VG, meta: IMeta) => { const childs = meta.item.childs; const parts = viParts(meta); @@ -26,24 +27,30 @@ export const viEvalScript = (ctx: ViContext, meta: IMeta) => { children = Array.isArray(childs) && childs.map(({ id }) => { - return ; + return ; }); } - const scope = viScopeUpward(ctx, meta); + const scope = getScope(vi, meta); + if (!meta.script) { + meta.script = { + result: null, + Local: createViLocal(meta), + PassProp: createViPassProp(meta), + }; + } + const script = meta.script; const arg = { ...scope, children, props: parts.props, - Local: ViLocal, - PassProp: ViPassProp, + Local: script.Local, + PassProp: script?.PassProp, ErrorBox: ErrorBox, newElement: () => {}, render: (jsx: ReactNode) => { - meta.script = { - el: jsx, - }; + script.result = jsx; }, }; diff --git a/app/web/src/nova/vi/render/script/local.tsx b/app/web/src/nova/vi/render/script/local.tsx index 8414487d..320b6026 100644 --- a/app/web/src/nova/vi/render/script/local.tsx +++ b/app/web/src/nova/vi/render/script/local.tsx @@ -1,13 +1,26 @@ import { ReactNode } from "react"; +import { useGlobal } from "web-utils"; +import { ViGlobal } from "../global"; +import { IMeta } from "../../../ed/logic/ed-global"; -export const ViLocal = >(arg: { - children: ReactNode; - name: string; - value: T; - hook: (local: T) => void; - effect: (local: T) => void | Promise; -}) => { - const { children } = arg; +export const createViLocal = (meta: IMeta) => { + return >(arg: { + children: ReactNode; + name: string; + value: T; + hook: (local: T) => void; + effect: (local: T) => void | Promise; + }) => { + // const vi = useGlobal(ViGlobal, "VI"); + const { children } = arg; - return children; + if (!meta.scope.val) { + meta.scope.val = {}; + } + const val = meta.scope.val; + + val[arg.name] = arg.value; + + return children; + }; }; diff --git a/app/web/src/nova/vi/render/script/passprop.tsx b/app/web/src/nova/vi/render/script/passprop.tsx index bd07e765..326468f5 100644 --- a/app/web/src/nova/vi/render/script/passprop.tsx +++ b/app/web/src/nova/vi/render/script/passprop.tsx @@ -1,5 +1,8 @@ import { FC, ReactNode } from "react"; +import { IMeta } from "../../../ed/logic/ed-global"; -export const ViPassProp: FC<{ children: ReactNode }> = ({ children }) => { - return children; +export const createViPassProp = (meta: IMeta) => { + return (arg: { children: ReactNode }) => { + return arg.children; + }; }; diff --git a/app/web/src/nova/vi/render/script/scope-meta.ts b/app/web/src/nova/vi/render/script/scope-meta.ts new file mode 100644 index 00000000..348f8dd3 --- /dev/null +++ b/app/web/src/nova/vi/render/script/scope-meta.ts @@ -0,0 +1,58 @@ +import { IMeta } from "../../../ed/logic/ed-global"; +import { VG } from "../global"; + +const getScopeMeta = (vi: VG, meta: IMeta) => { + let cur = meta; + + const scopes_meta: IMeta[] = []; + const scope_meta: Record< + string, + { type: "local" | "passprop" | "jsxprop"; meta: IMeta } + > = {}; + if (cur && cur.parent) { + while (cur.parent) { + scopes_meta.unshift(cur); + if (!vi.meta[cur.parent.id]) break; + cur = vi.meta[cur.parent.id]; + } + } + + for (const meta of scopes_meta) { + const def = meta.scope.def; + if (def) { + if (def.passprop) { + for (const p of Object.keys(def.passprop)) { + scope_meta[p] = { type: "passprop", meta }; + } + } + if (def.props) { + for (const p of Object.keys(def.props)) { + scope_meta[p] = { type: "jsxprop", meta }; + } + } + if (def.local) { + scope_meta[def.local.name] = { type: "local", meta }; + } + } + } + + return scope_meta; +}; + +const getScopeValue = (scope_meta: ReturnType) => { + const scope: any = {}; + + for (const [varname, s] of Object.entries(scope_meta)) { + if (s.meta.scope.val) { + scope[varname] = s.meta.scope.val[varname]; + } + } + + return scope; +}; + +export const getScope = (vi: VG, meta: IMeta) => { + const scope_meta = getScopeMeta(vi, meta); + + return getScopeValue(scope_meta); +}; diff --git a/app/web/src/nova/vi/render/script/upward.ts b/app/web/src/nova/vi/render/script/upward.ts deleted file mode 100644 index 1533e327..00000000 --- a/app/web/src/nova/vi/render/script/upward.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { IMeta } from "../../../ed/logic/ed-global"; -import { ViContext } from "../parts"; - -export const viScopeUpward = (ctx: ViContext, meta: IMeta) => { - let cur = meta; - - if (cur && cur.parent) { - while (cur.parent) { - console.log(cur.scope); - - if (!ctx.meta[cur.parent.id]) break; - cur = ctx.meta[cur.parent.id]; - } - } - - return {}; -}; diff --git a/app/web/src/nova/vi/root.tsx b/app/web/src/nova/vi/root.tsx index cec02634..00686dd6 100644 --- a/app/web/src/nova/vi/root.tsx +++ b/app/web/src/nova/vi/root.tsx @@ -1,14 +1,19 @@ import { FC } from "react"; -import { ViContext } from "./render/parts"; +import { useGlobal, useLocal } from "web-utils"; +import { ViGlobal } from "./render/global"; import { ViRender } from "./render/render"; -import { useLocal } from "web-utils"; import { ErrorBox } from "./utils/error-box"; export const ViRoot: FC<{ - ctx: ViContext; + ctx: typeof ViGlobal; entry: string[]; }> = ({ ctx, entry }) => { + const vi = useGlobal(ViGlobal, "VI"); const local = useLocal({ tick: Date.now() }); + + if (ctx.meta !== vi.meta) { + vi.meta = ctx.meta; + } ctx.tick = local.tick; return ( @@ -19,7 +24,7 @@ export const ViRoot: FC<{ if (Element) { return ( - + ); } diff --git a/app/web/src/nova/view/logic/meta/types.ts b/app/web/src/nova/view/logic/meta/types.ts index 79daf031..42a9be71 100644 --- a/app/web/src/nova/view/logic/meta/types.ts +++ b/app/web/src/nova/view/logic/meta/types.ts @@ -2,6 +2,8 @@ import { ReactNode } from "react"; import { parseJs } from "../../../../../../srv/ws/sync/editor/parser/parse-js"; import { IContent } from "../../../../utils/types/general"; import { IItem, MItem } from "../../../../utils/types/item"; +import { createViLocal } from "../../../vi/render/script/local"; +import { createViPassProp } from "../../../vi/render/script/passprop"; export type GenMetaP = { meta: Record; @@ -55,7 +57,9 @@ export type IMeta = { is_root: boolean; }; script?: { - el: ReactNode; + result: ReactNode; + Local: ReturnType; + PassProp: ReturnType; }; scope: { val?: any;