From 348266be66d4ba3cdff60c14ae9ab54c9105c6cf Mon Sep 17 00:00:00 2001 From: Rizky Date: Mon, 6 Nov 2023 17:59:22 +0700 Subject: [PATCH] fix rendering props --- .../editor/panel/script/monaco/types/base.ts | 1 + app/web/src/render/live/elements/l-render.tsx | 11 +- app/web/src/render/live/logic/global.ts | 4 +- app/web/src/render/live/logic/tree-prop.tsx | 1 + app/web/src/render/live/logic/tree-scope.tsx | 106 ++++++++++-------- app/web/src/utils/script/types/base.ts | 1 + pkgs/web-utils/src/client-db.ts | 11 +- 7 files changed, 79 insertions(+), 56 deletions(-) diff --git a/app/web/src/render/editor/panel/script/monaco/types/base.ts b/app/web/src/render/editor/panel/script/monaco/types/base.ts index 77d39f08..4c6595e1 100644 --- a/app/web/src/render/editor/panel/script/monaco/types/base.ts +++ b/app/web/src/render/editor/panel/script/monaco/types/base.ts @@ -60,6 +60,7 @@ const newElement: (gen?: (item: ITEM) => ITEM | ITEM[]) => React.ReactNode; const Local: >(arg: { name: string; value: T; + idx?: any; children: ((local: T & { render: () => void }) => any); deps?: any[]; effect?: ( diff --git a/app/web/src/render/live/elements/l-render.tsx b/app/web/src/render/live/elements/l-render.tsx index 5fc738c3..46c075d0 100644 --- a/app/web/src/render/live/elements/l-render.tsx +++ b/app/web/src/render/live/elements/l-render.tsx @@ -94,7 +94,7 @@ export const LRenderInternal: FC<{ let props = {} as Record; let cprops = {} as [string, FNCompDef][]; - + props = deepClone( p.comps.all[meta.comp.id]?.content_tree.component?.props || {} ); @@ -207,10 +207,11 @@ export const LRenderInternal: FC<{ return (
- {/*
-        {item.id}-{item.name}
-        {item.name === "coba" && JSON.stringify(item.childs)}
-      
*/} + {/* {isComponent && ( +
+          {item.id}-{item.name}
+        
+ )} */} {_children}
); diff --git a/app/web/src/render/live/logic/global.ts b/app/web/src/render/live/logic/global.ts index 48aaa3a5..abebb7a2 100644 --- a/app/web/src/render/live/logic/global.ts +++ b/app/web/src/render/live/logic/global.ts @@ -21,10 +21,10 @@ export type ItemMeta = { className?: string; parent_id: string; parent_comp?: WithRequired & { item: IItem }; - memoize?: { + memoize?: Record; PassProp: FC; - }; + }>; isLayout: boolean; render?: () => void; mounted?: boolean; diff --git a/app/web/src/render/live/logic/tree-prop.tsx b/app/web/src/render/live/logic/tree-prop.tsx index 8d2b2de8..1575c37c 100644 --- a/app/web/src/render/live/logic/tree-prop.tsx +++ b/app/web/src/render/live/logic/tree-prop.tsx @@ -16,6 +16,7 @@ export const treePropEval = ( _scopeIndex?: Record ) => { const meta = p.treeMeta[id]; + if (meta.item.type === "item" && meta.item.component) { if (p.site.api_url) { if (!p.script.db) p.script.db = createDB(p.site.api_url); diff --git a/app/web/src/render/live/logic/tree-scope.tsx b/app/web/src/render/live/logic/tree-scope.tsx index 10607f36..5d95f107 100644 --- a/app/web/src/render/live/logic/tree-scope.tsx +++ b/app/web/src/render/live/logic/tree-scope.tsx @@ -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 { createAPI, createDB } from "../../../utils/script/init-api"; import { ErrorBox } from "../../editor/elements/e-error"; import { ItemMeta, PG } from "./global"; import { extractNavigate, preload } from "./route"; +import hash_sum from "hash-sum"; export const JS_DEBUG = false; @@ -23,8 +24,12 @@ export const treeScopeEval = ( let args = {}; try { if (!meta.memoize) { - meta.memoize = { - Local: createLocal(p, id), + meta.memoize = {}; + } + const memoizeKey = hash_sum(_scopeIndex) || "default"; + if (!meta.memoize[memoizeKey]) { + meta.memoize[memoizeKey] = { + Local: createLocal(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 }; args = { ...w.exports, ...finalScope, - ...meta.memoize, + ...meta.memoize[memoizeKey], db: p.script.db, api: p.script.api, children, @@ -137,8 +133,10 @@ export const mergeScopeUpwards = ( let scope = null; let indexedScope = null; + if (cur.indexedScope && opt?._scopeIndex) { const idx = opt._scopeIndex[cur.item.id]; + if (typeof idx !== "undefined" && cur.indexedScope[idx]) { indexedScope = cur.indexedScope[idx]; } @@ -160,7 +158,6 @@ export const mergeScopeUpwards = ( cur = p.treeMeta[cur.parent_id]; } - return finalScope; }; @@ -226,9 +223,14 @@ const createPassProp = ( const cachedLocal = {} as Record>; const cachedPath = {} as Record>; const cachedLayout = {} as Record; -const createLocal = (p: PG, id: string) => { +const createLocal = ( + p: PG, + id: string, + _existingScopeIndex?: Record +) => { const Local = ({ name, + idx: local_id, value, effect, children, @@ -238,6 +240,7 @@ const createLocal = (p: PG, id: string) => { }: { name: string; value: any; + idx?: string; effect?: (value: any) => void | Promise; children: ReactNode; hook?: (value: any) => void; @@ -245,27 +248,45 @@ const createLocal = (p: PG, id: string) => { cache?: boolean; }) => { const meta = p.treeMeta[id]; + const [_, set] = useState({}); - if (!meta.scope) { - meta.scope = {}; + let scope = null as any; + 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 = () => { try { const nval = deepClone(value); - const render = () => { - if (meta.render) meta.render(); - else p.render(); - }; - if (!meta.scope[name]) { - meta.scope[name] = { + + if (!scope[name]) { + scope[name] = { ...nval, render, }; } else { 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) { console.warn(e); @@ -273,16 +294,13 @@ const createLocal = (p: PG, id: string) => { }; let page_id = p.page?.id || ""; - const itemid = meta.item.id; + const itemid = meta.item.id + (local_id ? `_${local_id}` : ""); if (meta.isLayout) { page_id = "layout"; if (cachedLayout[meta.item.id]) { - meta.scope[name] = cachedLocal[page_id][itemid]; - meta.scope[name].render = () => { - if (meta.render) meta.render(); - else p.render(); - }; + scope[name] = cachedLocal[page_id][itemid]; + scope[name].render = render; } } @@ -301,31 +319,25 @@ const createLocal = (p: PG, id: string) => { if (cachedPath[page_id][itemid] !== location.href) { cachedPath[page_id][itemid] = location.href; genScope(); - cachedLocal[page_id][itemid] = meta.scope[name]; + cachedLocal[page_id][itemid] = scope[name]; } else { - meta.scope[name] = cachedLocal[page_id][itemid]; - meta.scope[name].render = () => { - if (meta.render) meta.render(); - else p.render(); - }; + scope[name] = cachedLocal[page_id][itemid]; + scope[name].render = render; } } else { - meta.scope[name] = cachedLocal[page_id][itemid]; - meta.scope[name].render = () => { - if (meta.render) meta.render(); - else p.render(); - }; + scope[name] = cachedLocal[page_id][itemid]; + scope[name].render = render; } } else { genScope(); - cachedLocal[page_id][itemid] = meta.scope[name]; + cachedLocal[page_id][itemid] = scope[name]; cachedPath[page_id][itemid] = location.href; } } if (typeof hook === "function") { try { - hook(meta.scope[name]); + hook(scope[name]); } catch (e) { console.warn(e); } @@ -340,13 +352,17 @@ const createLocal = (p: PG, id: string) => { cachedLayout[meta.item.id] = true; } try { - effect(meta.scope[name]); + effect(scope[name]); } catch (e) { console.warn(e); } } }, [...(deps || []), location.href]); + if (local_id) { + const scopeIndex = { ..._existingScopeIndex, [meta.item.id]: local_id }; + return modifyChildIndex(children, scopeIndex); + } return children; }; diff --git a/app/web/src/utils/script/types/base.ts b/app/web/src/utils/script/types/base.ts index 77d39f08..a981ad7e 100644 --- a/app/web/src/utils/script/types/base.ts +++ b/app/web/src/utils/script/types/base.ts @@ -59,6 +59,7 @@ type ITEM = { const newElement: (gen?: (item: ITEM) => ITEM | ITEM[]) => React.ReactNode; const Local: >(arg: { name: string; + idx?: any; value: T; children: ((local: T & { render: () => void }) => any); deps?: any[]; diff --git a/pkgs/web-utils/src/client-db.ts b/pkgs/web-utils/src/client-db.ts index 7be56acb..832511a7 100644 --- a/pkgs/web-utils/src/client-db.ts +++ b/pkgs/web-utils/src/client-db.ts @@ -78,8 +78,10 @@ export const dbClient = (name: string, dburl?: string) => { ); }; -const cachedQueryResult: Record = - {}; +const cachedQueryResult: Record< + string, + { timestamp: number; result: any; promise: Promise } +> = {}; export const fetchSendDb = async ( name: string, @@ -119,13 +121,14 @@ export const fetchSendDb = async ( if (!cached || (cached && Date.now() - cached.timestamp > 1000)) { cachedQueryResult[hsum] = { timestamp: Date.now(), + promise: frm.send(url, params, w.apiHeaders), result: null, }; - const result = await frm.send(url, params, w.apiHeaders); + const result = await cachedQueryResult[hsum].promise; cachedQueryResult[hsum].result = result; return result; } - return cached.result; + return await cached.promise; };