fix rendering props

This commit is contained in:
Rizky 2023-11-06 17:59:22 +07:00
parent 6154d13202
commit 348266be66
7 changed files with 79 additions and 56 deletions

View File

@ -60,6 +60,7 @@ const newElement: (gen?: (item: ITEM) => ITEM | ITEM[]) => React.ReactNode;
const Local: <T extends Record<string, any>>(arg: { const Local: <T extends Record<string, any>>(arg: {
name: string; name: string;
value: T; value: T;
idx?: any;
children: ((local: T & { render: () => void }) => any); children: ((local: T & { render: () => void }) => any);
deps?: any[]; deps?: any[];
effect?: ( effect?: (

View File

@ -94,7 +94,7 @@ export const LRenderInternal: FC<{
let props = {} as Record<string, FNCompDef>; let props = {} as Record<string, FNCompDef>;
let cprops = {} as [string, FNCompDef][]; let cprops = {} as [string, FNCompDef][];
props = deepClone( props = deepClone(
p.comps.all[meta.comp.id]?.content_tree.component?.props || {} p.comps.all[meta.comp.id]?.content_tree.component?.props || {}
); );
@ -207,10 +207,11 @@ export const LRenderInternal: FC<{
return ( return (
<div className={className}> <div className={className}>
{/* <pre className={"text-[9px] font-mono text-black"}> {/* {isComponent && (
{item.id}-{item.name} <pre className={"text-[9px] font-mono text-black"}>
{item.name === "coba" && JSON.stringify(item.childs)} {item.id}-{item.name}
</pre> */} </pre>
)} */}
{_children} {_children}
</div> </div>
); );

View File

@ -21,10 +21,10 @@ export type ItemMeta = {
className?: string; className?: string;
parent_id: string; parent_id: string;
parent_comp?: WithRequired<ItemMeta, "comp"> & { item: IItem }; parent_comp?: WithRequired<ItemMeta, "comp"> & { item: IItem };
memoize?: { memoize?: Record<string, {
Local: FC<any>; Local: FC<any>;
PassProp: FC<any>; PassProp: FC<any>;
}; }>;
isLayout: boolean; isLayout: boolean;
render?: () => void; render?: () => void;
mounted?: boolean; mounted?: boolean;

View File

@ -16,6 +16,7 @@ export const treePropEval = (
_scopeIndex?: Record<string, string> _scopeIndex?: Record<string, string>
) => { ) => {
const meta = p.treeMeta[id]; const meta = p.treeMeta[id];
if (meta.item.type === "item" && meta.item.component) { if (meta.item.type === "item" && meta.item.component) {
if (p.site.api_url) { if (p.site.api_url) {
if (!p.script.db) p.script.db = createDB(p.site.api_url); if (!p.script.db) p.script.db = createDB(p.site.api_url);

View File

@ -1,9 +1,10 @@
import { FC, ReactNode, Suspense, useEffect } from "react"; import { FC, ReactNode, Suspense, useEffect, useState } from "react";
import { deepClone } from "web-utils"; import { deepClone } from "web-utils";
import { createAPI, createDB } from "../../../utils/script/init-api"; import { createAPI, createDB } from "../../../utils/script/init-api";
import { ErrorBox } from "../../editor/elements/e-error"; import { ErrorBox } from "../../editor/elements/e-error";
import { ItemMeta, PG } from "./global"; import { ItemMeta, PG } from "./global";
import { extractNavigate, preload } from "./route"; import { extractNavigate, preload } from "./route";
import hash_sum from "hash-sum";
export const JS_DEBUG = false; export const JS_DEBUG = false;
@ -23,8 +24,12 @@ export const treeScopeEval = (
let args = {}; let args = {};
try { try {
if (!meta.memoize) { if (!meta.memoize) {
meta.memoize = { meta.memoize = {};
Local: createLocal(p, id), }
const memoizeKey = hash_sum(_scopeIndex) || "default";
if (!meta.memoize[memoizeKey]) {
meta.memoize[memoizeKey] = {
Local: createLocal(p, id, _scopeIndex),
PassProp: createPassProp(p, id, _scopeIndex), PassProp: createPassProp(p, id, _scopeIndex),
}; };
} }
@ -59,20 +64,11 @@ export const treeScopeEval = (
} }
} }
if (
meta.item.name === "label" &&
p.treeMeta[meta.parent_id].item.name === "tree_lv_2" &&
!finalScope.lv2_item
) {
const parent = p.treeMeta[meta.parent_id];
console.log("final_scope", meta, p.treeMeta[parent.parent_id]);
}
const output = { jsx: null as any }; const output = { jsx: null as any };
args = { args = {
...w.exports, ...w.exports,
...finalScope, ...finalScope,
...meta.memoize, ...meta.memoize[memoizeKey],
db: p.script.db, db: p.script.db,
api: p.script.api, api: p.script.api,
children, children,
@ -137,8 +133,10 @@ export const mergeScopeUpwards = (
let scope = null; let scope = null;
let indexedScope = null; let indexedScope = null;
if (cur.indexedScope && opt?._scopeIndex) { if (cur.indexedScope && opt?._scopeIndex) {
const idx = opt._scopeIndex[cur.item.id]; const idx = opt._scopeIndex[cur.item.id];
if (typeof idx !== "undefined" && cur.indexedScope[idx]) { if (typeof idx !== "undefined" && cur.indexedScope[idx]) {
indexedScope = cur.indexedScope[idx]; indexedScope = cur.indexedScope[idx];
} }
@ -160,7 +158,6 @@ export const mergeScopeUpwards = (
cur = p.treeMeta[cur.parent_id]; cur = p.treeMeta[cur.parent_id];
} }
return finalScope; return finalScope;
}; };
@ -226,9 +223,14 @@ const createPassProp = (
const cachedLocal = {} as Record<string, Record<string, any>>; const cachedLocal = {} as Record<string, Record<string, any>>;
const cachedPath = {} as Record<string, Record<string, any>>; const cachedPath = {} as Record<string, Record<string, any>>;
const cachedLayout = {} as Record<string, true>; const cachedLayout = {} as Record<string, true>;
const createLocal = (p: PG, id: string) => { const createLocal = (
p: PG,
id: string,
_existingScopeIndex?: Record<string, any>
) => {
const Local = ({ const Local = ({
name, name,
idx: local_id,
value, value,
effect, effect,
children, children,
@ -238,6 +240,7 @@ const createLocal = (p: PG, id: string) => {
}: { }: {
name: string; name: string;
value: any; value: any;
idx?: string;
effect?: (value: any) => void | Promise<void>; effect?: (value: any) => void | Promise<void>;
children: ReactNode; children: ReactNode;
hook?: (value: any) => void; hook?: (value: any) => void;
@ -245,27 +248,45 @@ const createLocal = (p: PG, id: string) => {
cache?: boolean; cache?: boolean;
}) => { }) => {
const meta = p.treeMeta[id]; const meta = p.treeMeta[id];
const [_, set] = useState({});
if (!meta.scope) { let scope = null as any;
meta.scope = {}; if (!local_id) {
if (!meta.scope) {
meta.scope = {};
}
scope = meta.scope;
} else {
if (!meta.indexedScope) {
meta.indexedScope = {};
}
if (!meta.indexedScope[local_id]) meta.indexedScope[local_id] = {};
scope = meta.indexedScope[local_id];
} }
const render = () => {
if (!local_id) {
if (meta.render) meta.render();
else p.render();
} else {
set({});
}
};
const genScope = () => { const genScope = () => {
try { try {
const nval = deepClone(value); const nval = deepClone(value);
const render = () => {
if (meta.render) meta.render(); if (!scope[name]) {
else p.render(); scope[name] = {
};
if (!meta.scope[name]) {
meta.scope[name] = {
...nval, ...nval,
render, render,
}; };
} else { } else {
for (const [k, v] of Object.entries(nval)) { for (const [k, v] of Object.entries(nval)) {
meta.scope[name][k] = v; scope[name][k] = v;
} }
meta.scope[name].render = render; scope[name].render = render;
} }
} catch (e) { } catch (e) {
console.warn(e); console.warn(e);
@ -273,16 +294,13 @@ const createLocal = (p: PG, id: string) => {
}; };
let page_id = p.page?.id || ""; let page_id = p.page?.id || "";
const itemid = meta.item.id; const itemid = meta.item.id + (local_id ? `_${local_id}` : "");
if (meta.isLayout) { if (meta.isLayout) {
page_id = "layout"; page_id = "layout";
if (cachedLayout[meta.item.id]) { if (cachedLayout[meta.item.id]) {
meta.scope[name] = cachedLocal[page_id][itemid]; scope[name] = cachedLocal[page_id][itemid];
meta.scope[name].render = () => { scope[name].render = render;
if (meta.render) meta.render();
else p.render();
};
} }
} }
@ -301,31 +319,25 @@ const createLocal = (p: PG, id: string) => {
if (cachedPath[page_id][itemid] !== location.href) { if (cachedPath[page_id][itemid] !== location.href) {
cachedPath[page_id][itemid] = location.href; cachedPath[page_id][itemid] = location.href;
genScope(); genScope();
cachedLocal[page_id][itemid] = meta.scope[name]; cachedLocal[page_id][itemid] = scope[name];
} else { } else {
meta.scope[name] = cachedLocal[page_id][itemid]; scope[name] = cachedLocal[page_id][itemid];
meta.scope[name].render = () => { scope[name].render = render;
if (meta.render) meta.render();
else p.render();
};
} }
} else { } else {
meta.scope[name] = cachedLocal[page_id][itemid]; scope[name] = cachedLocal[page_id][itemid];
meta.scope[name].render = () => { scope[name].render = render;
if (meta.render) meta.render();
else p.render();
};
} }
} else { } else {
genScope(); genScope();
cachedLocal[page_id][itemid] = meta.scope[name]; cachedLocal[page_id][itemid] = scope[name];
cachedPath[page_id][itemid] = location.href; cachedPath[page_id][itemid] = location.href;
} }
} }
if (typeof hook === "function") { if (typeof hook === "function") {
try { try {
hook(meta.scope[name]); hook(scope[name]);
} catch (e) { } catch (e) {
console.warn(e); console.warn(e);
} }
@ -340,13 +352,17 @@ const createLocal = (p: PG, id: string) => {
cachedLayout[meta.item.id] = true; cachedLayout[meta.item.id] = true;
} }
try { try {
effect(meta.scope[name]); effect(scope[name]);
} catch (e) { } catch (e) {
console.warn(e); console.warn(e);
} }
} }
}, [...(deps || []), location.href]); }, [...(deps || []), location.href]);
if (local_id) {
const scopeIndex = { ..._existingScopeIndex, [meta.item.id]: local_id };
return modifyChildIndex(children, scopeIndex);
}
return children; return children;
}; };

View File

@ -59,6 +59,7 @@ type ITEM = {
const newElement: (gen?: (item: ITEM) => ITEM | ITEM[]) => React.ReactNode; const newElement: (gen?: (item: ITEM) => ITEM | ITEM[]) => React.ReactNode;
const Local: <T extends Record<string, any>>(arg: { const Local: <T extends Record<string, any>>(arg: {
name: string; name: string;
idx?: any;
value: T; value: T;
children: ((local: T & { render: () => void }) => any); children: ((local: T & { render: () => void }) => any);
deps?: any[]; deps?: any[];

View File

@ -78,8 +78,10 @@ export const dbClient = (name: string, dburl?: string) => {
); );
}; };
const cachedQueryResult: Record<string, { timestamp: number; result: any }> = const cachedQueryResult: Record<
{}; string,
{ timestamp: number; result: any; promise: Promise<any> }
> = {};
export const fetchSendDb = async ( export const fetchSendDb = async (
name: string, name: string,
@ -119,13 +121,14 @@ export const fetchSendDb = async (
if (!cached || (cached && Date.now() - cached.timestamp > 1000)) { if (!cached || (cached && Date.now() - cached.timestamp > 1000)) {
cachedQueryResult[hsum] = { cachedQueryResult[hsum] = {
timestamp: Date.now(), timestamp: Date.now(),
promise: frm.send(url, params, w.apiHeaders),
result: null, result: null,
}; };
const result = await frm.send(url, params, w.apiHeaders); const result = await cachedQueryResult[hsum].promise;
cachedQueryResult[hsum].result = result; cachedQueryResult[hsum].result = result;
return result; return result;
} }
return cached.result; return await cached.promise;
}; };