This commit is contained in:
Rizky 2023-10-22 12:22:25 +07:00
parent 18d6b3128c
commit ecd2dc33f9
5 changed files with 140 additions and 18 deletions

View File

@ -1,6 +1,7 @@
import { dir } from "dir";
import { RootDatabase, open } from "lmdb";
import { g } from "utils/global";
import { KeyMap } from "../../../../web/src/utils/sync/keymap";
const defaultConf = {
site_id: "",
@ -9,6 +10,11 @@ const defaultConf = {
export type UserConf = typeof defaultConf;
export const user = {
active: KeyMap.create<{
user_id: string;
site_id: string;
page_id: string;
}>("user_id"),
conf: {
_db: null as null | RootDatabase<UserConf>,
init() {

View File

@ -33,6 +33,10 @@ const EmptyComp = {
export type EdMeta = {
item: IItem | IText;
mitem?: MItem | MText;
parent_item: {
id: string;
mitem?: MItem;
};
parent_comp?: {
ref_ids: Record<string, string>;
mcomp: MItem;

View File

@ -20,16 +20,25 @@ export const treeRebuild = async (p: PG) => {
p.page.tree = [];
p.page.meta = {};
const portal = {};
const portal = {
in: {} as Record<string, EdMeta>,
out: {} as Record<string, EdMeta>,
};
const sections = root.get("childs");
if (sections) {
await Promise.all(
sections.map(async (e) => {
p.page.entry.push(e.get("id"));
await walkMap(p, { mitem: e, tree_parent_id: "root", portal });
await walkMap(p, { mitem: e, parent_item: { id: "root" }, portal });
})
);
console.log(p.page);
for (const [k, v] of Object.entries(portal.out)) {
const name = k.replace(/⮕/gi, "").trim();
const portal_in = portal.in[`${name}`];
if (portal_in) {
}
}
}
}
};
@ -54,13 +63,16 @@ const walkMap = async (
p: PG,
arg: {
mitem: MItem | MSection;
portal: Record<string, EdMeta>;
tree_parent_id: string;
portal: {
in: Record<string, EdMeta>;
out: Record<string, EdMeta>;
};
parent_item: EdMeta["parent_item"];
parent_comp?: EdMeta["parent_comp"];
skip_add_tree?: boolean;
}
) => {
const { mitem, tree_parent_id, parent_comp } = arg;
const { mitem, parent_item, parent_comp } = arg;
const item = {} as unknown as IItem;
mapItem(mitem, item);
@ -80,7 +92,7 @@ const walkMap = async (
if (!arg.skip_add_tree) {
p.page.tree.push({
id: item.id,
parent: tree_parent_id,
parent: parent_item.id,
text: item.name,
});
}
@ -122,7 +134,7 @@ const walkMap = async (
if (mcontent) {
walkMap(p, {
mitem: mcontent,
tree_parent_id: item.id,
parent_item: { id: item.id, mitem: mitem as MItem },
parent_comp: { ref_ids, mcomp },
portal: arg.portal,
});
@ -137,7 +149,7 @@ const walkMap = async (
mcomp.get("childs")?.map(async (e) => {
await walkMap(p, {
mitem: e,
tree_parent_id: item.id,
parent_item: { id: item.id, mitem: mitem as MItem },
parent_comp: { ref_ids, mcomp },
skip_add_tree: true,
portal: arg.portal,
@ -156,15 +168,16 @@ const walkMap = async (
const meta: EdMeta = {
item,
mitem: mitem as MItem,
parent_item,
parent_comp,
};
if (!item_comp) {
if (item.name.startsWith("⬅")) {
arg.portal[item.name] = meta;
arg.portal.in[item.name] = meta;
}
if (item.name.startsWith("⮕")) {
arg.portal[item.name] = meta;
arg.portal.out[item.name] = meta;
}
}
@ -173,7 +186,7 @@ const walkMap = async (
if (!arg.skip_add_tree) {
p.page.tree.push({
id: item.id,
parent: tree_parent_id,
parent: parent_item.id,
text: item.name,
data: meta,
});
@ -186,7 +199,7 @@ const walkMap = async (
item.childs.push(e.get("id"));
await walkMap(p, {
mitem: e,
tree_parent_id: item.id,
parent_item: { id: item.id, mitem: mitem as MItem },
portal: arg.portal,
});
}) || []
@ -195,14 +208,13 @@ const walkMap = async (
};
const loadComponent = async (p: PG, item_comp: FNComponent) => {
let found = false;
const cur = await p.sync.comp.load(item_comp.id);
if (cur && cur.snapshot) {
const doc = new Y.Doc() as DComp;
if (cur.snapshot) {
Y.applyUpdate(doc as any, cur.snapshot);
p.comp.list[item_comp.id] = { cur, doc };
found = true;
return true;
}
}
return false;

View File

@ -0,0 +1,86 @@
export const KeyMap = {
create: <K extends Record<string, string>>(main: keyof K) => {
const childs = {} as Record<string, ReturnType<typeof createChild>>;
const all = {} as Record<string, Record<string, string>>;
const createChild = (key: string) => {
return {
remove(id: string) {
if (all[id]) {
map.delete(all[key][id]);
}
},
};
};
const map = new EventedMap({
onSet({ key, value }) {
for (const [k, v] of Object.entries(value)) {
if (!childs[k]) {
childs[k] = createChild(k);
all[k] = {};
}
all[k][v] = key;
}
},
onDelete(key) {
const val = map.get(key);
for (const [k, v] of Object.entries(val)) {
delete all[k][v as string];
}
return true;
},
});
return new Proxy(
{},
{
get(_, key: string, receiver) {
if (key === "get") {
return map.get;
}
if (key === "set") {
return (val: K) => {
const key = val[main];
map.set(key, val);
};
}
if (!childs[key]) {
childs[key] = createChild(key);
}
return childs[key];
},
}
) as { get: (key: typeof main) => K; set: (val: K) => void } & Record<
keyof K,
EventedMap
>;
},
};
type MapEvents = Partial<{
onSet: (arg: { key: string; value: Record<string, string> }) => void;
onDelete: (key: string) => boolean;
}>;
class EventedMap extends Map {
_events: MapEvents;
constructor(events: MapEvents) {
super();
this._events = events;
}
set(key: string, value: Record<string, any>): this {
super.set(key, value);
this._events.onSet?.({ key, value });
return this;
}
delete(key: string): boolean {
const value = this.get(key);
if (value) {
this._events.onDelete?.(key);
}
return super.delete(key);
}
}

View File

@ -1,5 +1,5 @@
import { spawn, spawnSync } from "bun";
import { readAsync } from "fs-jetpack";
import { existsAsync, readAsync } from "fs-jetpack";
import { dir } from "../utils/dir";
import { g } from "../utils/global";
@ -7,13 +7,27 @@ export const prepareAPITypes = async () => {
const out: string[] = [];
for (const [k, v] of Object.entries(g.api)) {
const name = k.substring(0, k.length - 3).replace(/\W/gi, "_");
let p = {
path: `app/srv/api/${v.path}`,
handler: `"./api/${v.path.substring(0, v.path.length - 3)}"`,
};
if (!(await existsAsync(dir.path(p.path)))) {
p.path = `pkgs/core/api/${v.path}`;
p.handler = `"../../pkgs/core/api/${v.path.substring(
0,
v.path.length - 3
)}"`;
}
out.push(`\
export const ${name} = {
name: "${name}",
url: "${v.url}",
path: "app/srv/api/${v.path}",
path: "${p.path}",
args: ${JSON.stringify(v.args)},
handler: import("./api/${v.path.substring(0, v.path.length - 3)}")
handler: import(${p.handler})
}`);
}
await Bun.write(dir.path(`app/srv/exports.ts`), out.join(`\n`));