This commit is contained in:
Rizky 2023-12-12 09:59:46 +07:00
parent 6a5619d322
commit 4db6b11edf
11 changed files with 143 additions and 64 deletions

View File

@ -1,7 +1,7 @@
import { IMeta } from "../../ed/logic/ed-global"; 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) { if (meta.item.component?.props) {
for (const [k, v] of Object.entries(meta.item.component.props)) { for (const [k, v] of Object.entries(meta.item.component.props)) {
} }

View File

@ -0,0 +1,8 @@
import { IMeta } from "../../ed/logic/ed-global";
export const ViGlobal = {
meta: {} as Record<string, IMeta>,
tick: 0,
};
export type VG = typeof ViGlobal;

View File

@ -2,10 +2,6 @@ import { produceCSS } from "../../../utils/css/gen";
import { IContent } from "../../../utils/types/general"; import { IContent } from "../../../utils/types/general";
import { IMeta } from "../../ed/logic/ed-global"; import { IMeta } from "../../ed/logic/ed-global";
export type ViContext = {
meta: Record<string, IMeta>;
tick: number;
};
export type ViParts = { export type ViParts = {
mode: "mobile" | "desktop"; mode: "mobile" | "desktop";
hover?: boolean; hover?: boolean;

View File

@ -1,18 +1,20 @@
import { FC, ReactNode, Suspense } from "react"; import { FC, ReactNode, Suspense } from "react";
import { useGlobal } from "web-utils";
import { IMeta } from "../../ed/logic/ed-global"; import { IMeta } from "../../ed/logic/ed-global";
import { ViContext, viParts } from "./parts";
import { ViScript } from "./script";
import { ErrorBox } from "../utils/error-box"; import { ErrorBox } from "../utils/error-box";
import { ViGlobal } from "./global";
import { viParts } from "./parts";
import { ViScript } from "./script";
export const ViRender: FC<{ export const ViRender: FC<{
ctx: ViContext;
meta: IMeta; meta: IMeta;
children?: ReactNode; children?: ReactNode;
}> = ({ meta, children, ctx }) => { }> = ({ meta, children }) => {
const vi = useGlobal(ViGlobal, "VI");
if (!meta) return null; if (!meta) return null;
if (meta.item.adv?.js || meta.item.component?.id) { if (meta.item.adv?.js || meta.item.component?.id) {
return <ViScript ctx={ctx} meta={meta} />; return <ViScript meta={meta} />;
} }
const parts = viParts(meta); const parts = viParts(meta);
@ -28,7 +30,7 @@ export const ViRender: FC<{
return ( return (
<ErrorBox key={id}> <ErrorBox key={id}>
<Suspense> <Suspense>
<ViRender ctx={ctx} meta={ctx.meta[id]} /> <ViRender meta={vi.meta[id]} />
</Suspense> </Suspense>
</ErrorBox> </ErrorBox>
); );

View File

@ -1,23 +1,24 @@
import { FC, ReactNode } from "react"; import { FC, ReactNode } from "react";
import { useGlobal } from "web-utils";
import { IMeta } from "../../ed/logic/ed-global"; 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 { 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 }> = ({ export const ViScript: FC<{ meta: IMeta }> = ({ meta }) => {
ctx, const vi = useGlobal(ViGlobal, "VI");
meta,
}) => {
viEvalScript(ctx, meta);
if (meta.script) return meta.script.el; viEvalScript(vi, meta);
if (meta.script) return meta.script.result;
return null; return null;
}; };
export const viEvalScript = (ctx: ViContext, meta: IMeta) => { export const viEvalScript = (vi: VG, meta: IMeta) => {
const childs = meta.item.childs; const childs = meta.item.childs;
const parts = viParts(meta); const parts = viParts(meta);
@ -26,24 +27,30 @@ export const viEvalScript = (ctx: ViContext, meta: IMeta) => {
children = children =
Array.isArray(childs) && Array.isArray(childs) &&
childs.map(({ id }) => { childs.map(({ id }) => {
return <ViRender key={id} ctx={ctx} meta={ctx.meta[id]} />; return <ViRender key={id} meta={vi.meta[id]} />;
}); });
} }
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 = { const arg = {
...scope, ...scope,
children, children,
props: parts.props, props: parts.props,
Local: ViLocal, Local: script.Local,
PassProp: ViPassProp, PassProp: script?.PassProp,
ErrorBox: ErrorBox, ErrorBox: ErrorBox,
newElement: () => {}, newElement: () => {},
render: (jsx: ReactNode) => { render: (jsx: ReactNode) => {
meta.script = { script.result = jsx;
el: jsx,
};
}, },
}; };

View File

@ -1,13 +1,26 @@
import { ReactNode } from "react"; import { ReactNode } from "react";
import { useGlobal } from "web-utils";
import { ViGlobal } from "../global";
import { IMeta } from "../../../ed/logic/ed-global";
export const ViLocal = <T extends Record<string, any>>(arg: { export const createViLocal = (meta: IMeta) => {
return <T extends Record<string, any>>(arg: {
children: ReactNode; children: ReactNode;
name: string; name: string;
value: T; value: T;
hook: (local: T) => void; hook: (local: T) => void;
effect: (local: T) => void | Promise<void>; effect: (local: T) => void | Promise<void>;
}) => { }) => {
// const vi = useGlobal(ViGlobal, "VI");
const { children } = arg; const { children } = arg;
if (!meta.scope.val) {
meta.scope.val = {};
}
const val = meta.scope.val;
val[arg.name] = arg.value;
return children; return children;
};
}; };

View File

@ -1,5 +1,8 @@
import { FC, ReactNode } from "react"; import { FC, ReactNode } from "react";
import { IMeta } from "../../../ed/logic/ed-global";
export const ViPassProp: FC<{ children: ReactNode }> = ({ children }) => { export const createViPassProp = (meta: IMeta) => {
return children; return (arg: { children: ReactNode }) => {
return arg.children;
};
}; };

View File

@ -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<typeof getScopeMeta>) => {
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);
};

View File

@ -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 {};
};

View File

@ -1,14 +1,19 @@
import { FC } from "react"; 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 { ViRender } from "./render/render";
import { useLocal } from "web-utils";
import { ErrorBox } from "./utils/error-box"; import { ErrorBox } from "./utils/error-box";
export const ViRoot: FC<{ export const ViRoot: FC<{
ctx: ViContext; ctx: typeof ViGlobal;
entry: string[]; entry: string[];
}> = ({ ctx, entry }) => { }> = ({ ctx, entry }) => {
const vi = useGlobal(ViGlobal, "VI");
const local = useLocal({ tick: Date.now() }); const local = useLocal({ tick: Date.now() });
if (ctx.meta !== vi.meta) {
vi.meta = ctx.meta;
}
ctx.tick = local.tick; ctx.tick = local.tick;
return ( return (
@ -19,7 +24,7 @@ export const ViRoot: FC<{
if (Element) { if (Element) {
return ( return (
<ErrorBox key={meta.item.id}> <ErrorBox key={meta.item.id}>
<ViRender ctx={ctx} meta={meta} /> <ViRender meta={meta} />
</ErrorBox> </ErrorBox>
); );
} }

View File

@ -2,6 +2,8 @@ import { ReactNode } from "react";
import { parseJs } from "../../../../../../srv/ws/sync/editor/parser/parse-js"; import { parseJs } from "../../../../../../srv/ws/sync/editor/parser/parse-js";
import { IContent } from "../../../../utils/types/general"; import { IContent } from "../../../../utils/types/general";
import { IItem, MItem } from "../../../../utils/types/item"; import { IItem, MItem } from "../../../../utils/types/item";
import { createViLocal } from "../../../vi/render/script/local";
import { createViPassProp } from "../../../vi/render/script/passprop";
export type GenMetaP = { export type GenMetaP = {
meta: Record<string, IMeta>; meta: Record<string, IMeta>;
@ -55,7 +57,9 @@ export type IMeta = {
is_root: boolean; is_root: boolean;
}; };
script?: { script?: {
el: ReactNode; result: ReactNode;
Local: ReturnType<typeof createViLocal>;
PassProp: ReturnType<typeof createViPassProp>;
}; };
scope: { scope: {
val?: any; val?: any;