wip component

This commit is contained in:
Rizky 2023-12-27 08:22:44 +07:00
parent 57044a6a08
commit 346c1d2ed4
11 changed files with 222 additions and 223 deletions

View File

@ -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<string, CompSnapshot> = {};
// const scanMeta = async (doc: DPage, sync: SyncConnection) => {
// const meta: GenMetaP["meta"] = {};
// const mcomps: GenMetaP["comps"] = {};
// const msnap: Record<string, CompSnapshot> = {};
const loading = {} as Record<string, Promise<void>>;
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<void>(async (resolve) => {
await loadComponent(id, sync);
resolve();
});
}
await loading[id];
} else {
userSyncComponent(sync, id);
}
// const loading = {} as Record<string, Promise<void>>;
// 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<void>(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<string, IMeta> = {};
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<string, IMeta> = {};
// 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<string, true | IMeta>,
};
// const save = {
// instances_check: {} as Record<string, true | IMeta>,
// };
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 };
// };

View File

@ -0,0 +1,5 @@
import { EComp } from "../../../../web/src/nova/ed/logic/ed-global";
export const prepareComponentForPage = async (page_id: string) => {
return {} as Record<string, EComp>;
};

View File

@ -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<string>();
const loading = {} as Record<string, Promise<void>>;
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<void>(async (resolve) => {
await loadComponent(id, sync);
resolve();
});
}
await loading[id];
} else {
userSyncComponent(sync, id);
}
result.add(id);
}
}
);
}
return [...result];
};

View File

@ -53,8 +53,6 @@ const EmptyPage = {
name: "",
url: "",
snapshot: null as null | Uint8Array,
entry: [] as string[],
meta: {} as Record<string, ISimpleMeta>,
comps: {} as Record<string, EComp>,
};

View File

@ -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<string, ISimpleMeta>,
ids: Record<string, string>
) => {
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;
};

View File

@ -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]) {

View File

@ -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,
},
});
}

View File

@ -7,16 +7,14 @@ import { createViPassProp } from "../render/script/passprop";
export type GenMetaP = {
meta: Record<string, IMeta>;
comps: Record<string, { comp: IItem; smeta: Record<string, ISimpleMeta> }>;
comps: Record<string, IItem>;
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<string, ISimpleMeta>;
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<string, Record<string, string>>;
};
};
@ -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<typeof createViPassProp>;
}
>;
scope: {
def?: ReturnType<typeof parseJs>;
};
render?: () => void;
};

View File

@ -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<typeof parseJs>;
type: "item";
component?: FNComponent;
childs: (IItem | IText)[];

View File

@ -19,10 +19,7 @@ export type FNAdv = {
export type FMAdv = TypedMap<FNAdv>;
export type FNComponent = {
id: string;
name?: string;
loaded?: boolean;
props: Record<string, FNCompDef>;
ref_ids?: Record<string, string>;
instances?: Record<string, Record<string, string>>;
};

View File

@ -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";