This commit is contained in:
Rizky 2024-01-17 17:23:51 +07:00
parent ec85c9c981
commit 0f0576f638
8 changed files with 161 additions and 323 deletions

View File

@ -15,6 +15,7 @@ import { declareScope } from "./scope/scope";
import { Loading } from "../../../../../utils/ui/loading"; import { Loading } from "../../../../../utils/ui/loading";
// @ts-ignore // @ts-ignore
import { constrainedEditor } from "constrained-editor-plugin/dist/esm/constrainedEditor"; import { constrainedEditor } from "constrained-editor-plugin/dist/esm/constrainedEditor";
import { addScope } from "./scope/add-scope";
const scriptEdit = { const scriptEdit = {
timeout: null as any, timeout: null as any,
@ -110,41 +111,34 @@ export const EdScriptMonaco: FC<{}> = () => {
); );
editor.setModel(nmodel); editor.setModel(nmodel);
} else { } else {
const imports = declareScope(p, meta, monaco); const nmodel = monaco.editor.createModel(
let cur = active.comp_id ? active.comp_id : "page"; val,
monaco.editor.getModels().forEach((model) => { "typescript",
if ( monaco.Uri.parse("file:///active.tsx")
type === "item" && );
model.uri.path === `/${cur}_${active.item_id}_src_src.tsx` editor.setModel(nmodel);
) { const { exports, imports } = declareScope(p, meta, monaco);
editor.setModel(model); console.log(
} Object.keys(imports).map((e) => [
p.page.meta[e].item.name,
if ( exports[e],
type === "prop-instance" && ])
model.uri.path === );
`/${cur}_${active.item_id}_prop_${p.ui.popup.script.prop_name}.tsx` // const added = new Set<string>();
) { // const im = imports[active.item_id];
editor.setModel(model); // const im_flat = {} as Record<string, string[]>;
} // for (const [var_name, item] of Object.entries(im)) {
}); // const file_name = `${item.id}_${item.type}.tsx`;
const model = editor.getModel(); // if (!im_flat[file_name]) im_flat[file_name] = [];
if (!model) { // im_flat[file_name].push(var_name);
const nmodel = monaco.editor.createModel( // }
imports && imports.length > 0 // console.log(im_flat, exports);
? `${imports}\n/** IMPORT MODULE **/\n${val}` // if (active_src) {
: val, // const end_hide =
"typescript", // active_src.split("//!!start")[0].split("\n").length + 1;
monaco.Uri.parse("file:///active.tsx") // const range = new monaco.Range(1, 0, end_hide, 0);
); // (editor as any).setHiddenAreas([range]);
editor.setModel(nmodel); // }
}
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]);
}
} }
editor.trigger("fold", "editor.foldAllMarkerRegions", {}); editor.trigger("fold", "editor.foldAllMarkerRegions", {});
await jsMount(editor, monaco, p); await jsMount(editor, monaco, p);
@ -270,8 +264,8 @@ export const EdScriptMonaco: FC<{}> = () => {
} }
onChange={(value) => { onChange={(value) => {
const stype = p.ui.popup.script.type; const stype = p.ui.popup.script.type;
if ((value || "").includes("/** IMPORT MODULE **/")) { if ((value || "").includes("/** SOURCE START **/")) {
const valparts = (value || "").split("/** IMPORT MODULE **/\n"); const valparts = (value || "").split("/** SOURCE START **/\n");
if (valparts.length === 2) local.value = valparts[1]; if (valparts.length === 2) local.value = valparts[1];
if ( if (
stype === "prop-instance" && stype === "prop-instance" &&

View File

@ -8,23 +8,21 @@ export const addScope = (
filename: string, filename: string,
source: string source: string
) => { ) => {
const model = monaco.editor.getModels().find((e) => { // const model = monaco.editor.getModels().find((e) => {
return e.uri.toString() === filename; // return e.uri.toString() === filename;
}); // });
if (model) { // if (model) {
if (model.getValue() !== source) { // return model;
model.setValue(source); // } else {
} const uri = monaco.Uri.parse(filename);
} else { const model = monaco.editor.createModel(source, "typescript", uri);
const uri = monaco.Uri.parse(filename); return model;
const model = monaco.editor.createModel(source, "typescript", uri); // const arg = extractLoc(uri.path.split("_"), p);
// model.onDidChangeContent((e) => {
const arg = extractLoc(uri.path.split("_"), p); // // if (arg.id !== active.item_id && arg.type === "src") {
model.onDidChangeContent((e) => { // // console.log("changed", arg.id, e.changes);
// if (arg.id !== active.item_id && arg.type === "src") { // // }
// console.log("changed", arg.id, e.changes); // });
// } // }
});
}
}; };

View File

@ -4,7 +4,7 @@ export const extractExport = (p: PG, m: IMeta) => {
const result = {} as Record< const result = {} as Record<
string, string,
{ {
type: "local" | "passprop" | "prop"; type: "local" | "passprop" | "prop" | "scope";
id: string; id: string;
start: number; start: number;
end: number; end: number;
@ -37,11 +37,11 @@ export const extractExport = (p: PG, m: IMeta) => {
} }
} }
if (m.script?.passprop) { if (m.script?.scope) {
for (const [k, v] of Object.entries(m.script.passprop)) { for (const [k, v] of Object.entries(m.script.scope)) {
if (k === "key") continue; if (k === "key") continue;
result[k] = { result[k] = {
type: "passprop", type: "scope",
id: m.item.id, id: m.item.id,
start: 0, start: 0,
end: 0, end: 0,

View File

@ -1,7 +1,6 @@
import type { OnMount } from "@monaco-editor/react"; import type { OnMount } from "@monaco-editor/react";
import { IContent } from "../../../../../../utils/types/general"; import { IContent } from "../../../../../../utils/types/general";
import { IMeta, PG, active } from "../../../../logic/ed-global"; import { IMeta, PG, active } from "../../../../logic/ed-global";
import { addScope } from "./add-scope";
import { extractExport } from "./extract-export"; import { extractExport } from "./extract-export";
type Monaco = Parameters<OnMount>[1]; type Monaco = Parameters<OnMount>[1];
@ -16,177 +15,77 @@ export const declareScope = (p: PG, meta: IMeta, monaco: Monaco) => {
: p.page.entry.map((e) => p.page.meta[e].item); : p.page.entry.map((e) => p.page.meta[e].item);
const paths: IMeta[][] = []; const paths: IMeta[][] = [];
map_childs(monaco, p, metas, entry, paths);
const jsxprop_import_map: Record<string, string> = {}; const exports = {} as Record<string, string>;
map_childs( const extract_exports = {} as Record<
monaco, string,
p, ReturnType<typeof extractExport>
metas, >;
entry, const imports = {} as Record<
paths, string,
active.comp_id ? [active.comp_id] : [], Record<
jsxprop_import_map string,
); { id: string; type: "prop" | "passprop" | "local" | "scope" }
>
let cur = active.comp_id ? active.comp_id : "page"; >;
const { import_map, parent_id } = extract_import_map(
cur,
paths,
meta,
p,
false,
monaco
);
const merged_import_map = {
...import_map,
...jsxprop_import_map,
};
gen_content(cur, p, paths, merged_import_map, monaco);
if (cur !== "page" && !parent_id) {
return merged_import_map[paths[0][0].item.id];
}
return merged_import_map[parent_id];
};
const gen_content = (
cur: string,
p: PG,
paths: IMeta[][],
import_map: Record<string, string>,
monaco: Monaco
) => {
const added = new Set<string>();
const cur_path = [] as IMeta[];
for (const path of paths) { for (const path of paths) {
let idx = 0; if (path.includes(meta)) {
let last_import = cur !== "page" ? import_map[path[0].item.id] : ""; for (const m of path) {
if (m.instances) {
for (const m of path) { cur_path.length = 0;
if (!added.has(m.item.id) && m.item.adv?.js) {
added.add(m.item.id);
const content = last_import
? `\
${last_import}
/** IMPORT MODULE **/
${m.item.adv.js}`
: m.item.adv.js;
addScope(p, monaco, `file:///${cur}_${m.item.id}_src_src.tsx`, content);
}
if (!import_map[m.item.id]) {
if (idx === 0) {
break;
} }
} else { cur_path.push(m);
last_import = import_map[m.item.id];
} }
idx++; break;
} }
} }
};
const extract_import_map = ( let prev_m = null as null | IMeta;
cur: string, for (const m of cur_path) {
paths: IMeta[][], if (!exports[m.item.id]) {
meta: IMeta, const export_types = {
p: PG, local: [] as string[],
include_cur?: boolean, prop: [] as string[],
monaco?: Monaco passprop: [] as string[],
) => { scope: [] as string[],
const added = new Set<string>(); };
let parent_id = ""; extract_exports[m.item.id] = extractExport(p, m);
const import_map = {} as Record<string, string>;
let cur_id = meta.item.id;
if (cur_id) { for (const [k, v] of Object.entries(extract_exports[m.item.id])) {
for (const path of paths) { if (v.type !== "local") {
const import_exists = {} as Record< export_types[v.type].push(`export const ${k} = ${v.val};`);
string, } else {
{ type: "prop" | "local" | "passprop"; str: string } export_types[v.type].push(`\
>; const ${k}__local = ${v.val};
export const ${k}: typeof ${k}__local & { render: ()=>void } = ${k}__local as any;`);
if ( }
path }
.map((e) => { for (const [k, v] of Object.entries(export_types)) {
return e.item.id; if (v.length > 0) {
}) exports[`${m.item.id}_${k}.tsx`] = v.join("\n");
.includes(cur_id)
) {
let i = 0;
let prev_m = null as any;
for (const m of path) {
if (m.item.id === cur_id) {
if (prev_m) parent_id = prev_m.item.id;
}
prev_m = m;
if (include_cur || (!include_cur && !added.has(m.item.id))) {
added.add(m.item.id);
const ex = extractExport(p, m);
for (const [k, v] of Object.entries(ex)) {
let src = "";
if (v.type === "local") {
src = `\
const _local = ${v.val};
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`,
`\
${[...Object.values(import_exists).map((e) => e.str)].join("\n")}
/** IMPORT MODULE **/
${src}`
);
}
}
for (const [k, v] of Object.entries(ex)) {
if (
!include_cur &&
m.item.id === cur_id &&
["local", "passprop"].includes(v.type)
) {
continue;
}
import_exists[k] = {
type: v.type,
str: `import { ${k} } from './${cur}_${v.id}_${v.type}_${k}';`,
};
}
import_map[m.item.id] = [
...Object.values(import_exists).map((e) => e.str),
].join("\n");
}
i++;
} }
} }
} }
} if (prev_m && extract_exports[prev_m.item.id]) {
return { import_map, parent_id }; imports[m.item.id] = {};
}; if (imports[prev_m.item.id]) {
for (const [k, v] of Object.entries(imports[prev_m.item.id])) {
imports[m.item.id][k] = v;
}
}
const comp_map = {} as Record< for (const [k, v] of Object.entries(extract_exports[prev_m.item.id])) {
string, imports[m.item.id][k] = { id: v.id, type: v.type };
{ }
paths: IMeta[][]; }
exports: Record<string, ReturnType<typeof extractExport>>; prev_m = m;
} }
>;
return { exports, imports };
};
const map_childs = ( const map_childs = (
monaco: Monaco, monaco: Monaco,
@ -194,113 +93,44 @@ const map_childs = (
metas: Record<string, IMeta>, metas: Record<string, IMeta>,
childs: IContent[], childs: IContent[],
paths: IMeta[][], paths: IMeta[][],
skip_comp_id: string[],
jsxprop_import_map: Record<string, string> = {},
curpath?: IMeta[] curpath?: IMeta[]
) => { ) => {
for (const m of childs) { for (const m of childs) {
const meta = metas[m.id]; const meta = metas[m.id];
if (meta) { if (meta) {
paths.push([...(curpath || []), meta]); paths.push([...(curpath || []), meta]);
// if ( if (meta.item.component?.id && meta.item.component?.props) {
// meta.item.type === "item" && for (const [name, prop] of Object.entries(meta.item.component.props)) {
// meta.item.component?.id && if (
// !skip_comp_id.includes(meta.item.component?.id) prop.meta?.type === "content-element" &&
// ) { prop.content &&
// const comp_id = meta.item.component.id; prop.jsxCalledBy
// let jprop = comp_map[comp_id]; ) {
// // if (!jprop) { const m = metas[prop.jsxCalledBy[0]];
// // const comp_metas = p.comp.list[comp_id].meta; if (m && m.instances) {
// // comp_map[meta.item.component.id] = { const instances = m.instances[prop.jsxCalledBy[0]];
// // paths: [], if (instances) {
// // exports: {}, const instance_id = instances[prop.jsxCalledBy[1]];
// // }; if (instance_id) {
// // const id = p.comp.list[comp_id].doc const meta_parent = metas[instance_id];
// // .getMap("map") map_childs(monaco, p, metas, [prop.content], paths, [
// // .get("root") ...(curpath || []),
// // ?.get("id"); meta,
meta_parent,
// // 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 (Array.isArray(meta.item.childs)) {
map_childs(monaco, p, metas, meta.item.childs, paths, [
// // jprop = comp_map[meta.item.component.id]; ...(curpath || []),
// // for (const path of jprop.paths) { meta,
// // 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 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];
// const { import_map, parent_id } = extract_import_map(
// "page",
// jprop.paths,
// mjsx,
// p,
// true,
// monaco
// );
// 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]
);
} }
// }
} }
} }
}; };

View File

@ -25,13 +25,13 @@ export const viEvalScript = (
if (!meta.script) { if (!meta.script) {
meta.script = { meta.script = {
passprop, scope: passprop,
result: null, result: null,
Local: createViLocal(vi, meta), Local: createViLocal(vi, meta),
PassProp: createViPassProp(vi, meta), PassProp: createViPassProp(vi, meta),
}; };
} else { } else {
meta.script.passprop = passprop; meta.script.scope = passprop;
} }
const script = meta.script; const script = meta.script;

View File

@ -27,7 +27,7 @@ export const createViLocal = (
const local = ref.current; const local = ref.current;
local.render = meta.render; local.render = meta.render;
updatePropScope(vi, meta, meta.script?.passprop); updatePropScope(vi, meta, meta.script?.scope);
if (arg.hook) { if (arg.hook) {
arg.hook(local); arg.hook(local);
@ -67,7 +67,7 @@ export const createViLocal = (
}, []); }, []);
return modifyChild(children, { return modifyChild(children, {
...meta.script?.passprop, ...meta.script?.scope,
[arg.name]: local, [arg.name]: local,
}); });
}; };

View File

@ -4,7 +4,23 @@ import { VG } from "../global";
export const createViPassProp = (vi: { meta: VG["meta"] }, meta: IMeta) => { export const createViPassProp = (vi: { meta: VG["meta"] }, meta: IMeta) => {
return (arg: Record<string, any> & { children: ReactNode }) => { return (arg: Record<string, any> & { children: ReactNode }) => {
return modifyChild(arg, meta.script?.passprop); if (!meta.item.script) {
meta.item.script = {};
}
if (!meta.item.script.passprop) {
meta.item.script.passprop = {};
}
if (meta.item.script.passprop) {
for (const [k, v] of Object.entries(arg)) {
if (!["children", "key"].includes(k)) {
meta.item.script.passprop[k] = { end: 0, start: 0, value: v };
}
}
}
return modifyChild(arg, meta.script?.scope);
}; };
}; };

View File

@ -59,7 +59,7 @@ export type IMeta = {
is_root: boolean; is_root: boolean;
}; };
script?: { script?: {
passprop?: any; scope?: any;
result: ReactNode; result: ReactNode;
Local: ReturnType<typeof createViLocal>; Local: ReturnType<typeof createViLocal>;
PassProp: ReturnType<typeof createViPassProp>; PassProp: ReturnType<typeof createViPassProp>;