diff --git a/app/srv/ws/sync/actions/code_edit.ts b/app/srv/ws/sync/actions/code_edit.ts index fe8cf52d..8a58617c 100644 --- a/app/srv/ws/sync/actions/code_edit.ts +++ b/app/srv/ws/sync/actions/code_edit.ts @@ -45,8 +45,6 @@ export const code_edit: SAction["code"]["edit"] = async function ( jsx: "transform", format: "cjs", loader: "tsx", - minify: true, - sourcemap: "inline", }); doc?.transact(() => { const mode = arg.mode; diff --git a/app/web/src/nova/ed/logic/ed-global.ts b/app/web/src/nova/ed/logic/ed-global.ts index 677f7e89..d28787d6 100644 --- a/app/web/src/nova/ed/logic/ed-global.ts +++ b/app/web/src/nova/ed/logic/ed-global.ts @@ -20,6 +20,7 @@ export const EmptySite = { layout: { id: "--", snapshot: null as null | Uint8Array, + meta: undefined as void | Record, }, code: { snapshot: null as null | Uint8Array, @@ -66,7 +67,8 @@ const target = { instance_item_id: false as any, }; export const active = { - hover: { id: "", renderTree: () => {}, renderMain: () => {} }, + should_render_main: true, + hover: { id: "" }, text: { id: "", content: "", timeout: null as any, el: null as any }, get item_id() { if (target.active_id === false) { diff --git a/app/web/src/nova/ed/logic/tree/build.tsx b/app/web/src/nova/ed/logic/tree/build.tsx index 08b98b63..c338b442 100644 --- a/app/web/src/nova/ed/logic/tree/build.tsx +++ b/app/web/src/nova/ed/logic/tree/build.tsx @@ -13,6 +13,7 @@ export const treeRebuild = async (p: PG, arg?: { note?: string }) => { } } + active.should_render_main = true; const is_layout = p.site.layout && p.site.layout.id === p.page.cur.id && diff --git a/app/web/src/nova/ed/panel/main/main-per-item.tsx b/app/web/src/nova/ed/panel/main/main-per-item.tsx index c5bf95cf..22a24db7 100644 --- a/app/web/src/nova/ed/panel/main/main-per-item.tsx +++ b/app/web/src/nova/ed/panel/main/main-per-item.tsx @@ -134,14 +134,12 @@ export const mainPerItemVisit = ( parts.props.onPointerEnter = (e) => { e.stopPropagation(); active.hover.id = meta.item.id; - active.hover.renderMain(); - active.hover.renderTree(); + p.render(); }; parts.props.onPointerLeave = (e) => { e.stopPropagation(); active.hover.id = ""; - active.hover.renderMain(); - active.hover.renderTree(); + p.render(); }; parts.props.onPointerDown = (e) => { e.stopPropagation(); diff --git a/app/web/src/nova/ed/panel/main/main.tsx b/app/web/src/nova/ed/panel/main/main.tsx index 73964468..039062a0 100644 --- a/app/web/src/nova/ed/panel/main/main.tsx +++ b/app/web/src/nova/ed/panel/main/main.tsx @@ -6,13 +6,46 @@ import { mainPerItemVisit } from "./main-per-item"; export const EdMain = () => { const p = useGlobal(EDGlobal, "EDITOR"); - const local = useLocal({}); - active.hover.renderMain = local.render; + const local = useLocal({ + cache: null as any, + first_load: false, + }); const meta = active.comp_id ? p.comp.list[active.comp_id].meta[active.item_id] : p.page.meta[active.item_id]; + if (active.should_render_main) { + local.cache = ( + { + return mainPerItemVisit(p, meta, parts); + }} + onStatusChanged={(status) => { + if (status !== "ready") { + active.should_render_main = true; + local.render(); + } else { + if (!local.first_load) { + local.first_load = true; + active.should_render_main = true; + local.render(); + } + } + }} + /> + ); + active.should_render_main = false; + } + return (
{ ` )} > -
- { - return mainPerItemVisit(p, meta, parts); - }} - /> -
+
{local.cache}
); }; diff --git a/app/web/src/nova/ed/panel/popup/script/scope/scope.tsx b/app/web/src/nova/ed/panel/popup/script/scope/scope.tsx index 70d6be1b..970d93d3 100644 --- a/app/web/src/nova/ed/panel/popup/script/scope/scope.tsx +++ b/app/web/src/nova/ed/panel/popup/script/scope/scope.tsx @@ -221,7 +221,7 @@ const map_childs = ( prop.content && prop.jsxCalledBy ) { - const mjsx = p.comp.list[comp_id].meta[prop.jsxCalledBy]; + const mjsx = p.comp.list[comp_id].meta[prop.jsxCalledBy[0]]; const { import_map, parent_id } = extract_import_map( meta.item.component.id, jprop.paths, diff --git a/app/web/src/nova/ed/panel/tree/node/render.tsx b/app/web/src/nova/ed/panel/tree/node/render.tsx index 136f7826..7e13aa1b 100644 --- a/app/web/src/nova/ed/panel/tree/node/render.tsx +++ b/app/web/src/nova/ed/panel/tree/node/render.tsx @@ -139,8 +139,7 @@ export const nodeRender: NodeRender = (node, prm) => { }} onMouseEnter={() => { active.hover.id = item.id; - active.hover.renderMain(); - active.hover.renderTree(); + p.render(); }} > {active.hover.id === item.id && ( diff --git a/app/web/src/nova/vi/load/load.tsx b/app/web/src/nova/vi/load/load.tsx index 6de8c5e8..d822c492 100644 --- a/app/web/src/nova/vi/load/load.tsx +++ b/app/web/src/nova/vi/load/load.tsx @@ -3,6 +3,9 @@ import { viLoadLegacy } from "./load-legacy"; export const viLoad = (vi: VG, arg: { site_id: string; api_url: string }) => { vi.status = "loading"; + if (vi.on_status_changes) { + vi.on_status_changes(vi.status); + } vi.site.id = arg.site_id; vi.site.api_url = arg.api_url; @@ -31,9 +34,15 @@ export const viLoad = (vi: VG, arg: { site_id: string; api_url: string }) => { render: vi.render, }).then(() => { vi.status = "ready"; + if (vi.on_status_changes) { + vi.on_status_changes(vi.status); + } vi.render(); }); } else { vi.status = "ready"; + if (vi.on_status_changes) { + vi.on_status_changes(vi.status); + } } }; diff --git a/app/web/src/nova/vi/render/global.tsx b/app/web/src/nova/vi/render/global.tsx index 2730706e..24d8ef5b 100644 --- a/app/web/src/nova/vi/render/global.tsx +++ b/app/web/src/nova/vi/render/global.tsx @@ -2,9 +2,10 @@ import { IItem } from "../../../utils/types/item"; import { IMeta } from "../../ed/logic/ed-global"; import { viParts } from "./parts"; +type ViStatus = "init" | "loading" | "ready"; export const ViGlobal = { ts: 0, - status: "init" as "init" | "loading" | "ready", + status: "init" as ViStatus, meta: {} as Record, tick: 0, site: { @@ -19,6 +20,7 @@ export const ViGlobal = { visit: undefined as | undefined | ((meta: IMeta, parts: ReturnType) => void), + on_status_changes: undefined as void | ((status: ViStatus) => void), }; export type VG = typeof ViGlobal & { render: () => void }; diff --git a/app/web/src/nova/vi/render/script/eval-prop.tsx b/app/web/src/nova/vi/render/script/eval-prop.tsx index 60be4884..1c71257f 100644 --- a/app/web/src/nova/vi/render/script/eval-prop.tsx +++ b/app/web/src/nova/vi/render/script/eval-prop.tsx @@ -2,6 +2,7 @@ import { IMeta } from "../../../ed/logic/ed-global"; import { VG } from "../global"; import { ViRender } from "../render"; import { viScriptArg } from "./arg"; +import { replaceWithObject, replacement } from "./eval-script"; export const viEvalProps = ( vi: { meta: VG["meta"] }, @@ -34,18 +35,32 @@ export const viEvalProps = ( const m = vi.meta[id]; if ( m.mitem && - prop.jsxCalledBy !== - (arg.meta.item.originalId || arg.meta.item.id) + prop.jsxCalledBy?.includes( + arg.meta.item.originalId || arg.meta.item.id + ) ) { const mprop = meta.mitem ?.get("component") ?.get("props") ?.get(name); if (mprop) { - mprop.set( - "jsxCalledBy", - arg.meta.item.originalId || arg.meta.item.id - ); + let mjby = mprop.get("jsxCalledBy"); + if (!mjby || typeof mjby !== "object") { + mprop.set("jsxCalledBy", [ + arg.meta.item.originalId || arg.meta.item.id, + ]); + } else { + if ( + !mjby.includes( + arg.meta.item.originalId || arg.meta.item.id + ) + ) { + mjby.push( + arg.meta.item.originalId || arg.meta.item.id + ); + mprop.set("jsxCalledBy", mjby); + } + } } } return ; @@ -62,14 +77,16 @@ export const viEvalProps = ( continue; } + const js = prop.valueBuilt || ""; + const src = replaceWithObject(js, replacement) || ""; const fn = new Function( ...Object.keys(arg), `// [${meta.item.name}] ${name}: ${meta.item.id} - return ${prop.valueBuilt || ""} + return ${src} ` ); - meta.item.script.props[name] = { value: prop.valueBuilt }; + meta.item.script.props[name] = { value: src }; let val = fn(...Object.values(arg)); if (typeof val === "function") { @@ -96,14 +113,13 @@ export const updatePropScope = (meta: IMeta, scope: any) => { if (meta.item.script?.props) { for (const [name, prop] of Object.entries(meta.item.script.props)) { if (prop.fn) { - const all_scope = scope; const fn = new Function( - ...Object.keys(all_scope), + ...Object.keys(scope), `// [${meta.item.name}] ${name}: ${meta.item.id} return ${prop.value || ""} ` ); - prop.fn = fn(...Object.values(all_scope)); + prop.fn = fn(...Object.values(scope)); } } } diff --git a/app/web/src/nova/vi/render/script/eval-script.tsx b/app/web/src/nova/vi/render/script/eval-script.tsx index 4f18953a..e280489e 100644 --- a/app/web/src/nova/vi/render/script/eval-script.tsx +++ b/app/web/src/nova/vi/render/script/eval-script.tsx @@ -64,10 +64,13 @@ export const viEvalScript = ( } } + const js = meta.item.adv?.jsBuilt || ""; + const src = replaceWithObject(js, replacement) || ""; + const fn = new Function( ...Object.keys(arg), `// ${meta.item.name}: ${meta.item.id} -${replaceWithObject(meta.item.adv?.jsBuilt || "", replacement) || ""} +${src} ` ); fn(...Object.values(arg)); @@ -89,12 +92,16 @@ const JsxProp: FC<{ return local.result; }; -const replacement = { +export const replacement = { "stroke-width": "strokeWidth", + "fill-rule": "fillRule", + "clip-rule": "clipRule", }; -const replaceWithObject = (tpl: string, data: any) => { - return tpl.replace(/\$\(([^\)]+)?\)/g, function ($1, $2) { - return data[$2]; - }); +export const replaceWithObject = (tpl: string, data: any) => { + let res = tpl; + for (const [k, v] of Object.entries(data)) { + res = res.replaceAll(k, v as string); + } + return res; }; diff --git a/app/web/src/nova/vi/vi.tsx b/app/web/src/nova/vi/vi.tsx index c8f70553..1206aacd 100644 --- a/app/web/src/nova/vi/vi.tsx +++ b/app/web/src/nova/vi/vi.tsx @@ -19,6 +19,7 @@ export const Vi: FC<{ script?: { init_local_effect: Record }; visit?: VG["visit"]; render_stat?: "enabled" | "disabled"; + onStatusChanged?: (status: VG["status"]) => void; }> = ({ meta, entry, @@ -29,8 +30,10 @@ export const Vi: FC<{ visit, script, render_stat: rs, + onStatusChanged, }) => { const vi = useGlobal(ViGlobal, "VI"); + vi.on_status_changes = onStatusChanged; if (rs === "disabled") { render_stat.enabled = false; diff --git a/app/web/src/utils/types/meta-fn.ts b/app/web/src/utils/types/meta-fn.ts index c1510a11..a994a48a 100644 --- a/app/web/src/utils/types/meta-fn.ts +++ b/app/web/src/utils/types/meta-fn.ts @@ -30,7 +30,7 @@ export type FNCompDef = { valueBuilt: any; gen?: string; genBuilt?: string; - jsxCalledBy?: string; + jsxCalledBy?: string[]; content?: IItem; visible?: string; meta?: FNCompMeta;