diff --git a/app/srv/ws/sync/actions/page_load.ts b/app/srv/ws/sync/actions/page_load.ts index cfd2afc4..077f4a53 100644 --- a/app/srv/ws/sync/actions/page_load.ts +++ b/app/srv/ws/sync/actions/page_load.ts @@ -1,5 +1,4 @@ import { EPage } from "../../../../web/src/nova/ed/logic/ed-global"; -import { assignMitem } from "../../../../web/src/nova/ed/logic/tree/assign-mitem"; import { initLoadComp } from "../../../../web/src/nova/vi/meta/comp/init-comp-load"; import { genMeta } from "../../../../web/src/nova/vi/meta/meta"; import { simplifyMeta } from "../../../../web/src/nova/vi/meta/simplify"; @@ -9,6 +8,8 @@ import { DPage } from "../../../../web/src/utils/types/root"; import { SAction } from "../actions"; import { loadComponent, userSyncComponent } from "../editor/load-component"; import { parseJs } from "../editor/parser/parse-js"; +import { prepareComponentForPage } from "../editor/prep-comp-page"; +import { prepContentTree } from "../editor/prep-page"; import { activity } from "../entity/activity"; import { conns } from "../entity/conn"; import { docs } from "../entity/docs"; @@ -85,7 +86,8 @@ export const page_load: SAction["page"]["load"] = async function ( const doc = new Y.Doc(); let root = doc.getMap("map"); - syncronize(root, { id, root: page.content_tree }); + const proot = await prepContentTree(page.id, page.content_tree, this); + syncronize(root, { id, root: proot }); const um = await createUndoManager(root); docs.page[id] = { @@ -116,14 +118,12 @@ export const page_load: SAction["page"]["load"] = async function ( page_id: page.id, }); - const meta = await scanMeta(docs.page[id].doc, this); - return { id: id, url: page.url, name: page.name, snapshot: await gzipAsync(bin), - ...meta, + comps: await prepareComponentForPage(id), }; } } else if (snap && !ydoc) { @@ -151,14 +151,12 @@ export const page_load: SAction["page"]["load"] = async function ( page_id: snap.id, }); - const meta = await scanMeta(docs.page[id].doc, this); - return { id: id, url: snap.url, name: snap.name, snapshot: await gzipAsync(snap.bin), - ...meta, + comps: await prepareComponentForPage(id), }; } else if (snap && ydoc) { await setActivityPage(snap.id_site, id); @@ -171,117 +169,116 @@ export const page_load: SAction["page"]["load"] = async function ( page_id: snap.id, }); - const meta = await scanMeta(ydoc.doc, this); return { id: snap.id, url: snap.url, name: snap.name, snapshot: await gzipAsync(snap.bin), - ...meta, + comps: await prepareComponentForPage(id), }; } }; -const scanMeta = async (doc: DPage, sync: SyncConnection) => { - const meta: GenMetaP["meta"] = {}; - const mcomps: GenMetaP["comps"] = {}; - const msnap: Record = {}; +// const scanMeta = async (doc: DPage, sync: SyncConnection) => { +// const meta: GenMetaP["meta"] = {}; +// const mcomps: GenMetaP["comps"] = {}; +// const msnap: Record = {}; - const loading = {} as Record>; - const mchilds = doc.getMap("map").get("root")?.get("childs"); - const entry: string[] = []; - if (mchilds) { - const childs = mchilds.map((m) => m); - for (const mchild of childs) { - await initLoadComp( - { comps: mcomps, meta }, - mchild.toJSON(), - async (comp_ids) => { - for (const id of comp_ids) { - if (!docs.comp[id]) { - if (typeof loading[id] === "undefined") { - loading[id] = new Promise(async (resolve) => { - await loadComponent(id, sync); - resolve(); - }); - } - await loading[id]; - } else { - userSyncComponent(sync, id); - } +// const loading = {} as Record>; +// const mchilds = doc.getMap("map").get("root")?.get("childs"); +// const entry: string[] = []; +// if (mchilds) { +// const childs = mchilds.map((m) => m); +// for (const mchild of childs) { +// await initLoadComp( +// { comps: mcomps, meta }, +// mchild.toJSON(), +// async (comp_ids) => { +// for (const id of comp_ids) { +// if (!docs.comp[id]) { +// if (typeof loading[id] === "undefined") { +// loading[id] = new Promise(async (resolve) => { +// await loadComponent(id, sync); +// resolve(); +// }); +// } +// await loading[id]; +// } else { +// userSyncComponent(sync, id); +// } - const snap = snapshot.get("comp", id); - if (snap) { - msnap[id] = snap; - } +// const snap = snapshot.get("comp", id); +// if (snap) { +// msnap[id] = snap; +// } - if (docs.comp[id]) { - const mitem = docs.comp[id].doc.getMap("map").get("root"); - const comp = mitem?.toJSON() as IItem; - const smeta: Record = {}; - genMeta( - { - comps: {}, - meta: smeta, - on: { - visit(meta) { - if (typeof meta.item.adv?.js === "string") { - meta.scope.def = parseJs(meta.item.adv?.js); - } - }, - }, - }, - { item: comp, ignore_first_component: true } - ); - mcomps[id] = { comp, smeta: simplifyMeta(smeta) }; - } - } - } - ); - } +// if (docs.comp[id]) { +// const mitem = docs.comp[id].doc.getMap("map").get("root"); +// const comp = mitem?.toJSON() as IItem; +// const smeta: Record = {}; +// genMeta( +// { +// comps: {}, +// meta: smeta, +// on: { +// visit(meta) { +// if (typeof meta.item.adv?.js === "string") { +// meta.scope.def = parseJs(meta.item.adv?.js); +// } +// }, +// }, +// }, +// { item: comp, ignore_first_component: true } +// ); +// mcomps[id] = { comp, smeta: simplifyMeta(smeta) }; +// } +// } +// } +// ); +// } - const transact = { - instances_check: {} as Record, - }; +// const save = { +// instances_check: {} as Record, +// }; - for (const mitem of childs) { - const item = mitem.toJSON() as IItem; - entry.push(item.id); - genMeta( - { - comps: mcomps, - meta, - on: { - visit_component(item) { - if (!item.component?.instances) { - transact.instances_check[item.id] = true; - } - }, - visit(m) { - if (!m.parent?.comp_id) { - if (typeof m.item.adv?.js === "string") { - m.scope.def = parseJs(m.item.adv?.js); - } - } +// for (const mitem of childs) { +// const item = mitem.toJSON() as IItem; +// entry.push(item.id); +// genMeta( +// { +// comps: mcomps, +// meta, +// on: { +// visit_component(item) { +// if (!item.component?.instances) { +// save.instances_check[item.id] = true; +// } +// }, +// visit(m) { +// if (!m.parent?.comp_id) { +// if (typeof m.item.adv?.js === "string") { +// m.scope.def = parseJs(m.item.adv?.js); +// } +// } - if (m.item.component?.id) { - if (transact.instances_check[m.item.id]) { - transact.instances_check[m.item.id] = m; - } - } - }, - }, - }, - { item } - ); - } - } +// if (m.item.component?.id) { +// if (save.instances_check[m.item.id]) { +// save.instances_check[m.item.id] = m; +// } +// } +// }, +// }, +// }, +// { item } +// ); +// } +// } - const comps: EPage["comps"] = {}; - for (const [id, snap] of Object.entries(msnap)) { - const meta = mcomps[id].smeta; - comps[id] = { id, meta, snapshot: await gzipAsync(snap.bin) }; - } +// const comps: EPage["comps"] = {}; +// for (const [id, snap] of Object.entries(msnap)) { +// const meta = mcomps[id].smeta; +// comps[id] = { id, meta, snapshot: await gzipAsync(snap.bin) }; +// } - return { meta: simplifyMeta(meta), comps, entry }; -}; +// return { meta: simplifyMeta(meta), comps, entry }; +// }; diff --git a/app/srv/ws/sync/editor/prep-comp-page.ts b/app/srv/ws/sync/editor/prep-comp-page.ts new file mode 100644 index 00000000..62fb6271 --- /dev/null +++ b/app/srv/ws/sync/editor/prep-comp-page.ts @@ -0,0 +1,5 @@ +import { EComp } from "../../../../web/src/nova/ed/logic/ed-global"; + +export const prepareComponentForPage = async (page_id: string) => { + return {} as Record; +}; diff --git a/app/srv/ws/sync/editor/prep-page.ts b/app/srv/ws/sync/editor/prep-page.ts new file mode 100644 index 00000000..3c273d6a --- /dev/null +++ b/app/srv/ws/sync/editor/prep-page.ts @@ -0,0 +1,83 @@ +import { initLoadComp } from "../../../../web/src/nova/vi/meta/comp/init-comp-load"; +import { genMeta } from "../../../../web/src/nova/vi/meta/meta"; +import { GenMetaP } from "../../../../web/src/nova/vi/utils/types"; +import { IItem } from "../../../../web/src/utils/types/item"; +import { IRoot } from "../../../../web/src/utils/types/root"; +import { docs } from "../entity/docs"; +import { SyncConnection } from "../type"; +import { loadComponent, userSyncComponent } from "./load-component"; +import { parseJs } from "./parser/parse-js"; + +export const prepContentTree = async ( + page_id: string, + ctree: any, + sync: SyncConnection +) => { + const root = ctree as IRoot; + + root.id_page = page_id; + root.component_ids = await loadCompForPage(ctree, sync); + + const comps: GenMetaP["comps"] = {}; + for (const id of root.component_ids) { + const comp = docs.comp[id].doc.getMap("map").get("root")?.toJSON() as IItem; + if (comp) comps[id] = comp; + } + + const meta = {}; + genMeta( + { + comps, + meta, + on: { + visit_component(item) { + if (item.component) { + if (!item.component.instances) { + item.component.instances = {}; + } + } + }, + visit(meta) { + if (meta.item.adv?.js) { + meta.item.script = parseJs(meta.item.adv.js); + } + }, + }, + mode: "page", + }, + { item: root as unknown as IItem } + ); + + return ctree; +}; + +const loadCompForPage = async (ctree: IRoot, sync: SyncConnection) => { + const meta: GenMetaP["meta"] = {}; + const mcomps: GenMetaP["comps"] = {}; + const result = new Set(); + const loading = {} as Record>; + for (const mchild of ctree.childs) { + await initLoadComp( + { comps: mcomps, meta, mode: "page" }, + mchild as unknown as IItem, + async (comp_ids) => { + for (const id of comp_ids) { + if (!docs.comp[id]) { + if (typeof loading[id] === "undefined") { + loading[id] = new Promise(async (resolve) => { + await loadComponent(id, sync); + resolve(); + }); + } + await loading[id]; + } else { + userSyncComponent(sync, id); + } + + result.add(id); + } + } + ); + } + return [...result]; +}; diff --git a/app/web/src/nova/ed/logic/ed-global.ts b/app/web/src/nova/ed/logic/ed-global.ts index bdb99da3..d10a2ca2 100644 --- a/app/web/src/nova/ed/logic/ed-global.ts +++ b/app/web/src/nova/ed/logic/ed-global.ts @@ -53,8 +53,6 @@ const EmptyPage = { name: "", url: "", snapshot: null as null | Uint8Array, - entry: [] as string[], - meta: {} as Record, comps: {} as Record, }; diff --git a/app/web/src/nova/vi/meta/comp.tsx b/app/web/src/nova/vi/meta/comp.tsx index 28a49e09..692e6bf0 100644 --- a/app/web/src/nova/vi/meta/comp.tsx +++ b/app/web/src/nova/vi/meta/comp.tsx @@ -8,42 +8,30 @@ import { simplifyItemChild } from "./simplify"; export const genComp = (p: GenMetaP, arg: GenMetaArg) => { const { item } = arg; if (item.type === "item" && item.component?.id && arg.parent?.item.id) { - let pcomp = p.comps[item.component.id]; + let item_comp = p.comps[item.component.id]; if (p.on?.visit_component) { p.on.visit_component(item); } - if (!pcomp) { + if (!item_comp) { return; } - if (pcomp) { - let instance = {}; - let instances: IMeta["instances"] = undefined; - - if (item.component.instances) { + if (item_comp) { + let instances: undefined | typeof item.component.instances = undefined; + if (p.mode === "page") { instances = item.component.instances; - instance = instances[item.id] || {}; - instances[item.id] = instance; } else { - const parent_instance = getParentInstance(p, arg, item.id); - instance = parent_instance || {}; - instances = !parent_instance ? { [item.id]: instance } : undefined; + instances = arg.parent?.root_instances; } - instantiate({ - item, - comp: pcomp.comp, - ids: instance, - }); - - if (item.component) { - item.component.loaded = true; - } - - let smeta = p.comps[item.component.id].smeta; - if (smeta) { - smeta = applySMeta(smeta, instance); + if (instances) { + const instance = instances[item.id]; + instantiate({ + item, + comp: item_comp, + ids: instance, + }); } const meta: IMeta = { @@ -53,16 +41,8 @@ export const genComp = (p: GenMetaP, arg: GenMetaArg) => { comp_id: arg.parent?.comp?.component?.id, instance_id: arg.parent?.instance_id, }, - instances, - scope: {}, }; - if (!meta.parent?.comp_id) { - if (p.smeta?.[item.id]) { - meta.scope.def = p.smeta[item.id].scope; - } - } - if (item.id) { if (p.set_meta !== false) { p.meta[item.id] = meta; @@ -71,14 +51,14 @@ export const genComp = (p: GenMetaP, arg: GenMetaArg) => { walkProp({ item, - pcomp, + item_comp: item_comp, each(name, prop) { const comp_id = item.component?.id; if (prop.meta?.type === "content-element" && comp_id) { if (prop.content) { genMeta( - { ...p, smeta }, + { ...p }, { item: prop.content, is_root: false, @@ -90,7 +70,8 @@ export const genComp = (p: GenMetaP, arg: GenMetaArg) => { parent: { item: meta.item, instance_id: item.id, - comp: pcomp.comp, + comp: item_comp, + root_instances: instances, }, } ); @@ -99,14 +80,6 @@ export const genComp = (p: GenMetaP, arg: GenMetaArg) => { }, }); - if (p.on) { - if (p.on.item_exists && p.meta[item.id]) { - p.on.item_exists({ old: p.meta[item.id], new: meta }); - } else if (p.on.item_new && !p.meta[item.id]) { - p.on.item_new({ new: meta }); - } - } - if (p.on?.visit) { p.on.visit(meta); } @@ -115,14 +88,14 @@ export const genComp = (p: GenMetaP, arg: GenMetaArg) => { if (child.name.startsWith("jsx:")) continue; genMeta( - { ...p, smeta }, + { ...p, mode: "comp" }, { item: child, is_root: false, parent: { item, instance_id: item.id, - comp: pcomp.comp, + root_instances: instances, }, } ); @@ -130,38 +103,3 @@ export const genComp = (p: GenMetaP, arg: GenMetaArg) => { } } }; - -const getParentInstance = (p: GenMetaP, arg: GenMetaArg, id: string) => { - if (arg.parent?.instance_id && p.meta[arg.parent?.instance_id]) { - const parent_instance = p.meta[arg.parent?.instance_id]; - if (parent_instance.instances) { - if (!parent_instance.instances[id]) { - parent_instance.instances[id] = {}; - } - - return parent_instance.instances[id]; - } - } -}; - -const applySMeta = ( - smeta: Record, - ids: Record -) => { - const nmeta: typeof smeta = {}; - - for (const [k, v] of Object.entries(smeta)) { - const id = ids[k]; - if (id) { - nmeta[id] = deepClone(v); - nmeta[id].id = id; - const parent = nmeta[id].parent; - if (parent) { - if (parent.instance_id) parent.instance_id = ids[parent.instance_id]; - if (parent.id) parent.id = ids[id]; - } - } - } - - return nmeta; -}; diff --git a/app/web/src/nova/vi/meta/comp/walk-prop.tsx b/app/web/src/nova/vi/meta/comp/walk-prop.tsx index df16cf7c..9dca7090 100644 --- a/app/web/src/nova/vi/meta/comp/walk-prop.tsx +++ b/app/web/src/nova/vi/meta/comp/walk-prop.tsx @@ -4,10 +4,10 @@ import { FNCompDef } from "../../../../utils/types/meta-fn"; export const walkProp = (arg: { item: IItem; - pcomp: { comp: IItem }; + item_comp: IItem; each: (name: string, prop: FNCompDef) => void; }) => { - for (const [k, v] of Object.entries(arg.pcomp.comp.component?.props || {})) { + for (const [k, v] of Object.entries(arg.item_comp.component?.props || {})) { let prop = deepClone(v); const props = arg.item.component?.props; if (props && props[k]) { diff --git a/app/web/src/nova/vi/meta/meta.ts b/app/web/src/nova/vi/meta/meta.ts index 30239e67..3973477e 100644 --- a/app/web/src/nova/vi/meta/meta.ts +++ b/app/web/src/nova/vi/meta/meta.ts @@ -13,13 +13,6 @@ export const genMeta = (p: GenMetaP, arg: GenMetaArg) => { } } - let scope: IMeta["scope"] = {}; - if (p.smeta) { - if (p.smeta[item.id] && p.smeta[item.id].scope) { - scope.def = p.smeta[item.id].scope; - } - } - const meta: IMeta = { item: simplifyItemChild(item), jsx_prop: arg.jsx_prop, @@ -28,20 +21,12 @@ export const genMeta = (p: GenMetaP, arg: GenMetaArg) => { instance_id: arg.parent?.instance_id, comp_id: arg.parent?.comp?.component?.id, }, - scope, }; if (p.on?.visit) { p.on.visit(meta); } - if (p.on) { - if (p.on.item_exists && p.meta[item.id]) { - p.on.item_exists({ old: p.meta[item.id], new: meta }); - } else if (p.on.item_new && !p.meta[item.id]) { - p.on.item_new({ new: meta }); - } - } if (item.id) { if (p.set_meta !== false) { p.meta[meta.item.id] = meta; @@ -57,6 +42,7 @@ export const genMeta = (p: GenMetaP, arg: GenMetaArg) => { item: meta.item, instance_id: arg.parent?.instance_id, comp: arg.parent?.comp, + root_instances: arg.parent?.root_instances, }, }); } diff --git a/app/web/src/nova/vi/utils/types.ts b/app/web/src/nova/vi/utils/types.ts index c948e0cf..ff5b8368 100644 --- a/app/web/src/nova/vi/utils/types.ts +++ b/app/web/src/nova/vi/utils/types.ts @@ -7,16 +7,14 @@ import { createViPassProp } from "../render/script/passprop"; export type GenMetaP = { meta: Record; - comps: Record }>; + comps: Record; on?: { visit_component?: (item: IItem) => void; visit?: (meta: IMeta) => void; - item_exists?: (arg: { old: IMeta; new: IMeta }) => void; - item_new?: (arg: { new: IMeta }) => void; }; - smeta?: Record; set_meta?: boolean; note?: string; + mode: "page" | "comp"; }; export type GenMetaArg = { @@ -28,6 +26,7 @@ export type GenMetaArg = { item: IItem; instance_id?: string; comp?: IItem; + root_instances?: Record>; }; }; @@ -42,7 +41,6 @@ export type ISimpleMeta = { instance_id?: string; comp_id?: string; }; - scope: IMeta["scope"]["def"]; }; export type IMeta = { @@ -67,8 +65,5 @@ export type IMeta = { PassProp: ReturnType; } >; - scope: { - def?: ReturnType; - }; render?: () => void; }; diff --git a/app/web/src/utils/types/item.ts b/app/web/src/utils/types/item.ts index cbd9eaa0..1f5b1b08 100644 --- a/app/web/src/utils/types/item.ts +++ b/app/web/src/utils/types/item.ts @@ -1,18 +1,16 @@ import { TypedArray, TypedMap } from "yjs-types"; +import { parseJs } from "../../../../srv/ws/sync/editor/parser/parse-js"; import { BasicItem, MBasicItem, MetaItem } from "./meta"; -import { - FNAdv, - FNComponent, - FNLayout, - FNLinkTag -} from "./meta-fn"; +import { FNAdv, FNComponent, FNLayout, FNLinkTag } from "./meta-fn"; import { MSection } from "./section"; import { IText, MText } from "./text"; + export type IItem = { layout?: FNLayout; linktag?: FNLinkTag; mobile?: IItem; adv?: FNAdv; + script?: ReturnType; type: "item"; component?: FNComponent; childs: (IItem | IText)[]; diff --git a/app/web/src/utils/types/meta-fn.ts b/app/web/src/utils/types/meta-fn.ts index ed4f11a6..f4e8a78e 100644 --- a/app/web/src/utils/types/meta-fn.ts +++ b/app/web/src/utils/types/meta-fn.ts @@ -19,10 +19,7 @@ export type FNAdv = { export type FMAdv = TypedMap; export type FNComponent = { id: string; - name?: string; - loaded?: boolean; props: Record; - ref_ids?: Record; instances?: Record>; }; diff --git a/app/web/src/utils/types/root.ts b/app/web/src/utils/types/root.ts index b65a2ebf..3ffc0702 100644 --- a/app/web/src/utils/types/root.ts +++ b/app/web/src/utils/types/root.ts @@ -5,8 +5,10 @@ import * as Y from "yjs"; export type IRoot = { id: "root"; type: "root"; - id_page: string; + id_page?: string; childs: ISection[]; + component_ids?: string[]; + entry_ids?: string[]; }; export type MRoot = TypedMap<{ id: "root";