diff --git a/app/web/src/nova/ed/panel/main/main.tsx b/app/web/src/nova/ed/panel/main/main.tsx index 039062a0..61633a2c 100644 --- a/app/web/src/nova/ed/panel/main/main.tsx +++ b/app/web/src/nova/ed/panel/main/main.tsx @@ -11,9 +11,17 @@ export const EdMain = () => { first_load: false, }); - const meta = active.comp_id - ? p.comp.list[active.comp_id].meta[active.item_id] - : p.page.meta[active.item_id]; + let meta: undefined | IMeta = undefined; + + if (active.comp_id) { + if (p.comp.list[active.comp_id]) { + meta = p.comp.list[active.comp_id].meta[active.item_id]; + } else { + active.comp_id = ""; + } + } else { + meta = p.page.meta[active.item_id]; + } if (active.should_render_main) { local.cache = ( diff --git a/app/web/src/nova/ed/panel/popup/script/monaco.tsx b/app/web/src/nova/ed/panel/popup/script/monaco.tsx index 44b00d6c..975eb325 100644 --- a/app/web/src/nova/ed/panel/popup/script/monaco.tsx +++ b/app/web/src/nova/ed/panel/popup/script/monaco.tsx @@ -142,10 +142,11 @@ export const EdScriptMonaco: FC<{}> = () => { if (imports) { local.imports = imports; end_hide = imports.split("\n").length + 1; - const range = new monaco.Range(1, 0, end_hide, 0); - (editor as any).setHiddenAreas([range]); + // const range = new monaco.Range(1, 0, end_hide, 0); + // (editor as any).setHiddenAreas([range]); } } + editor.trigger("fold", "editor.foldAllMarkerRegions", {}); await jsMount(editor, monaco, p); if (type === "prop-instance") { diff --git a/app/web/src/nova/ed/panel/popup/script/scope/add-scope.tsx b/app/web/src/nova/ed/panel/popup/script/scope/add-scope.tsx index 5037f026..cfd7c98e 100644 --- a/app/web/src/nova/ed/panel/popup/script/scope/add-scope.tsx +++ b/app/web/src/nova/ed/panel/popup/script/scope/add-scope.tsx @@ -13,18 +13,18 @@ export const addScope = ( }); if (model) { - model.setValue(source); + if (model.getValue() !== source) { + model.setValue(source); + } } else { const uri = monaco.Uri.parse(filename); const model = monaco.editor.createModel(source, "typescript", uri); const arg = extractLoc(uri.path.split("_"), p); model.onDidChangeContent((e) => { - if (arg.id !== active.item_id) { - const text = model.getValue(); - console.log(arg); - console.warn(text); - } + // if (arg.id !== active.item_id && arg.type === "src") { + // console.log("changed", arg.id, e.changes); + // } }); } }; diff --git a/app/web/src/nova/ed/panel/popup/script/scope/extract-export.tsx b/app/web/src/nova/ed/panel/popup/script/scope/extract-export.tsx index 882fd3c5..ca9908a9 100644 --- a/app/web/src/nova/ed/panel/popup/script/scope/extract-export.tsx +++ b/app/web/src/nova/ed/panel/popup/script/scope/extract-export.tsx @@ -37,6 +37,19 @@ export const extractExport = (p: PG, m: IMeta) => { } } + if (m.script?.passprop) { + for (const [k, v] of Object.entries(m.script.passprop)) { + if (k === "key") continue; + result[k] = { + type: "passprop", + id: m.item.id, + start: 0, + end: 0, + val: "null as any", + }; + } + } + if (script?.props) { for (const [k, v] of Object.entries(script.props)) { result[k] = { 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 5d719c6a..223f72ab 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 @@ -34,6 +34,7 @@ export const declareScope = (p: PG, meta: IMeta, monaco: Monaco) => { paths, meta, p, + false, monaco ); @@ -94,17 +95,28 @@ const extract_import_map = ( paths: IMeta[][], meta: IMeta, p: PG, + include_cur?: boolean, monaco?: Monaco ) => { const added = new Set(); let parent_id = ""; const import_map = {} as Record; - const cur_id = meta.item.id; + let cur_id = meta.item.id; + if (cur_id) { for (const path of paths) { - const imports = new Set(); + const import_exists = {} as Record< + string, + { type: "prop" | "local" | "passprop"; str: string } + >; - if (path.map((e) => e.item.id).includes(cur_id)) { + if ( + path + .map((e) => { + return e.item.id; + }) + .includes(cur_id) + ) { let i = 0; let prev_m = null as any; @@ -113,7 +125,7 @@ const extract_import_map = ( if (prev_m) parent_id = prev_m.item.id; } prev_m = m; - if (!added.has(m.item.id)) { + if (include_cur || (!include_cur && !added.has(m.item.id))) { added.add(m.item.id); const ex = extractExport(p, m); @@ -127,13 +139,14 @@ export const ${k}: typeof _local & { render: ()=>void } = _local; } else { src = `export const ${k} = ${v.val}`; } + if (src && monaco) { addScope( p, monaco, `file:///${cur}_${v.id}_${v.type}_${k}.tsx`, `\ -${[...imports].join("\n")} +${[...Object.values(import_exists).map((e) => e.str)].join("\n")} /** IMPORT MODULE **/ ${src}` ); @@ -142,18 +155,22 @@ ${src}` for (const [k, v] of Object.entries(ex)) { if ( + !include_cur && m.item.id === cur_id && ["local", "passprop"].includes(v.type) ) { continue; } - imports.add( - `import { ${k} } from './${cur}_${v.id}_${v.type}_${k}';` - ); + import_exists[k] = { + type: v.type, + str: `import { ${k} } from './${cur}_${v.id}_${v.type}_${k}';`, + }; } - import_map[m.item.id] = [...imports].join("\n"); + import_map[m.item.id] = [ + ...Object.values(import_exists).map((e) => e.str), + ].join("\n"); } i++; } @@ -185,100 +202,105 @@ const map_childs = ( const meta = metas[m.id]; if (meta) { paths.push([...(curpath || []), meta]); - if ( - meta.item.type === "item" && - meta.item.component?.id && - !skip_comp_id.includes(meta.item.component?.id) - ) { - const comp_id = meta.item.component.id; - let jprop = comp_map[comp_id]; - if (!jprop) { - const comp_metas = p.comp.list[comp_id].meta; - comp_map[meta.item.component.id] = { - paths: [], - exports: {}, - }; - const id = p.comp.list[comp_id].doc - .getMap("map") - .get("root") - ?.get("id"); + // if ( + // meta.item.type === "item" && + // meta.item.component?.id && + // !skip_comp_id.includes(meta.item.component?.id) + // ) { + // const comp_id = meta.item.component.id; + // let jprop = comp_map[comp_id]; + // // if (!jprop) { + // // const comp_metas = p.comp.list[comp_id].meta; + // // comp_map[meta.item.component.id] = { + // // paths: [], + // // exports: {}, + // // }; + // // const id = p.comp.list[comp_id].doc + // // .getMap("map") + // // .get("root") + // // ?.get("id"); - if (id) { - map_childs( - monaco, - p, - comp_metas, - [comp_metas[id].item], - comp_map[meta.item.component.id].paths, - [...skip_comp_id, comp_id] - ); + // // if (id) { + // // map_childs( + // // monaco, + // // p, + // // comp_metas, + // // [comp_metas[id].item], + // // comp_map[meta.item.component.id].paths, + // // [...skip_comp_id, comp_id] + // // ); - jprop = comp_map[meta.item.component.id]; - for (const path of jprop.paths) { - for (const m of path) { - if (!jprop.exports[m.item.id]) { - jprop.exports[m.item.id] = extractExport(p, m); - } - } - } - } - } + // // jprop = comp_map[meta.item.component.id]; + // // for (const path of jprop.paths) { + // // for (const m of path) { + // // if (!jprop.exports[m.item.id]) { + // // jprop.exports[m.item.id] = extractExport(p, m); + // // } + // // } + // // } + // // } + // // } - if (jprop) { - for (const [name, prop] of Object.entries( - meta.item.component.props - )) { - if ( - prop.meta?.type === "content-element" && - prop.content && - 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, - mjsx, - p, - monaco - ); + // if (jprop) { + // for (const [name, prop] of Object.entries( + // meta.item.component.props + // )) { + // if ( + // prop.meta?.type === "content-element" && + // prop.content && + // prop.jsxCalledBy + // ) { + // const m = metas[prop.jsxCalledBy[0]]; + // if (m && m.instances) { + // const instances = m.instances[prop.jsxCalledBy[0]]; + // if (instances) { + // const instance_id = instances[prop.jsxCalledBy[1]]; + // if (instance_id) { + // const mjsx = metas[instance_id]; - gen_content( - meta.item.component.id, - p, - jprop.paths, - import_map, - monaco - ); + // const { import_map, parent_id } = extract_import_map( + // "page", + // jprop.paths, + // mjsx, + // p, + // true, + // monaco + // ); - jsxprop_import_map[prop.content.id] = import_map[parent_id]; - const prop_meta = metas[prop.content.id]; - map_childs( - monaco, - p, - metas, - prop.content.childs, - paths, - [...skip_comp_id, comp_id], - jsxprop_import_map, - [...(curpath || []), prop_meta] - ); - } - } - } - } else { - if (Array.isArray(meta.item.childs)) { - map_childs( - monaco, - p, - metas, - meta.item.childs, - paths, - [...skip_comp_id], - jsxprop_import_map, - [...(curpath || []), meta] - ); - } + // gen_content("page", p, jprop.paths, import_map, monaco); + + // jsxprop_import_map[prop.content.id] = import_map[parent_id]; + // const prop_meta = metas[prop.content.id]; + // map_childs( + // monaco, + // p, + // metas, + // prop.content.childs, + // paths, + // [...skip_comp_id, comp_id], + // jsxprop_import_map, + // [...(curpath || []), prop_meta] + // ); + // } + // } + // } + // } + // } + // } + // } else { + if (Array.isArray(meta.item.childs)) { + map_childs( + monaco, + p, + metas, + meta.item.childs, + paths, + [...skip_comp_id], + jsxprop_import_map, + [...(curpath || []), meta] + ); } + // } } } }; diff --git a/app/web/src/nova/vi/meta/comp.tsx b/app/web/src/nova/vi/meta/comp.tsx index eb1d5d0a..3d9ecf31 100644 --- a/app/web/src/nova/vi/meta/comp.tsx +++ b/app/web/src/nova/vi/meta/comp.tsx @@ -34,7 +34,7 @@ export const genComp = (p: GenMetaP, arg: GenMetaArg) => { if (!instances[item.id]) { instances[item.id] = {}; instance = instances[item.id]; - } + } instantiate({ item, @@ -49,6 +49,7 @@ export const genComp = (p: GenMetaP, arg: GenMetaArg) => { comp_id: arg.parent?.comp?.component?.id, instance_id: arg.parent?.instance_id, }, + instances, }; if (p.on?.visit) { 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 2072a1ef..72e1033a 100644 --- a/app/web/src/nova/vi/render/script/eval-prop.tsx +++ b/app/web/src/nova/vi/render/script/eval-prop.tsx @@ -35,11 +35,21 @@ export const viEvalProps = ( const id = prop.content?.id; if (id) { const m = vi.meta[id]; + + const instances = meta.instances; + if (!arg.meta.item.originalId || !instances) { + return null; + } + + const instance = instances[meta.item.id]; + if (!instance) return null; + const original_id = arg.meta.item.originalId; if ( m.mitem && - prop.jsxCalledBy?.includes( - arg.meta.item.originalId || arg.meta.item.id - ) + ((prop.jsxCalledBy && + (!prop.jsxCalledBy.includes(original_id) || + prop.jsxCalledBy.length !== 2)) || + !prop.jsxCalledBy) ) { const mprop = meta.mitem ?.get("component") @@ -48,19 +58,15 @@ export const viEvalProps = ( if (mprop) { let mjby = mprop.get("jsxCalledBy"); if (!mjby || typeof mjby !== "object") { - mprop.set("jsxCalledBy", [ - arg.meta.item.originalId || arg.meta.item.id, - ]); + mprop.set("jsxCalledBy", [meta.item.id, original_id]); } else { if ( - !mjby.includes( - arg.meta.item.originalId || arg.meta.item.id - ) + !mjby.includes(original_id) || + mjby.length !== 2 || + mjby[0] !== meta.item.id || + mjby[1] !== original_id ) { - mjby.push( - arg.meta.item.originalId || arg.meta.item.id - ); - mprop.set("jsxCalledBy", mjby); + mprop.set("jsxCalledBy", [meta.item.id, original_id]); } } } diff --git a/pkgs/core/server/serve-static.ts b/pkgs/core/server/serve-static.ts index b45acf64..42eca787 100644 --- a/pkgs/core/server/serve-static.ts +++ b/pkgs/core/server/serve-static.ts @@ -7,14 +7,22 @@ import { watch } from "fs"; import mime from "mime"; import { g } from "utils/global"; -const webPath = "app/static"; +const web = { + get path() { + if (g.mode === "dev") return "static"; + return "static-br"; + }, +}; const cache = { - static: {} as Record, + static: {} as Record< + string, + { type: string; content: any; compression: "" | "br" } + >, }; export const serveStatic = { init: async () => { - const list = await inspectTreeAsync(dir.path(`${webPath}`)); + const list = await inspectTreeAsync(dir.path(`app/${web.path}`)); const walk = async ( list: InspectTreeResult, parent?: InspectTreeResult[] @@ -27,12 +35,13 @@ export const serveStatic = { const path = join(...(parent || []).map((e) => e.name), list.name); const file = Bun.file(dir.path(`app/${path}`)); if (await file.exists()) { - cache.static[path.substring("static".length)] = { + cache.static[path.substring(web.path.length)] = { type: mime.getType(path) || "application/octet-stream", + compression: g.mode === "prod" ? "br" : "", content: await file.arrayBuffer(), }; } - } + } }; if (list) { await walk(list); @@ -46,6 +55,7 @@ export const serveStatic = { if (await file.exists()) { cache.static[`/${filename}`] = { type: mime.getType(path) || "application/octet-stream", + compression: g.mode === "prod" ? "br" : "", content: await file.arrayBuffer(), }; } @@ -57,17 +67,23 @@ export const serveStatic = { return !!cache.static[url.pathname]; }, serve: (url: URL) => { - const file = cache.static[url.pathname]; + let file = cache.static[url.pathname]; if (file) { return new Response(file.content, { - headers: { "content-type": file.type }, + headers: { + ...{ "content-type": file.type }, + ...(file.compression ? { "content-encoding": file.compression } : {}), + }, }); } - const index = cache.static["/index.html"]; - if (index) { - return new Response(index.content, { - headers: { "content-type": index.type }, + file = cache.static["/index.html"]; + if (file) { + return new Response(file.content, { + headers: { + ...{ "content-type": file.type }, + ...(file.compression ? { "content-encoding": file.compression } : {}), + }, }); } },