fix init loading
This commit is contained in:
parent
0a39588932
commit
4bc08ebc29
|
|
@ -12,6 +12,7 @@
|
||||||
"mime-types": "^2.1.35",
|
"mime-types": "^2.1.35",
|
||||||
"msgpackr": "^1.9.9",
|
"msgpackr": "^1.9.9",
|
||||||
"radix3": "^1.1.0",
|
"radix3": "^1.1.0",
|
||||||
|
"uuid": "^9.0.1",
|
||||||
"y-pojo": "^0.0.8",
|
"y-pojo": "^0.0.8",
|
||||||
"yjs": "^13.6.8",
|
"yjs": "^13.6.8",
|
||||||
"yjs-types": "^0.0.1"
|
"yjs-types": "^0.0.1"
|
||||||
|
|
|
||||||
|
|
@ -2,5 +2,8 @@ import { SAction } from "../actions";
|
||||||
import { SyncConnection } from "../type";
|
import { SyncConnection } from "../type";
|
||||||
|
|
||||||
export const comp_new: SAction["comp"]["new"] = async function (
|
export const comp_new: SAction["comp"]["new"] = async function (
|
||||||
this: SyncConnection
|
this: SyncConnection,
|
||||||
) {};
|
arg
|
||||||
|
) {
|
||||||
|
console.log(arg);
|
||||||
|
};
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ export * from "./site_load";
|
||||||
export * from "./site_group";
|
export * from "./site_group";
|
||||||
export * from "./page_load";
|
export * from "./page_load";
|
||||||
export * from "./comp_load";
|
export * from "./comp_load";
|
||||||
|
export * from "./comp_new";
|
||||||
export * from "./comp_group";
|
export * from "./comp_group";
|
||||||
export * from "./yjs_um";
|
export * from "./yjs_um";
|
||||||
export * from "./yjs_sv_local";
|
export * from "./yjs_sv_local";
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,37 @@
|
||||||
|
import { validate } from "uuid";
|
||||||
|
import { user } from "../entity/user";
|
||||||
|
|
||||||
|
export const loadSitePage = async (
|
||||||
|
user_id: string,
|
||||||
|
site_id: string,
|
||||||
|
page_id?: string
|
||||||
|
) => {
|
||||||
|
if (validate(site_id)) {
|
||||||
|
const site = await db.site.findFirst({
|
||||||
|
where: { id: site_id },
|
||||||
|
select: { id: true },
|
||||||
|
});
|
||||||
|
|
||||||
|
if (site) {
|
||||||
|
await user.conf.set(user_id, "site_id", site_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
let page = null;
|
||||||
|
if (validate(page_id || "")) {
|
||||||
|
page = await db.page.findFirst({
|
||||||
|
where: { id: page_id, id_site: site_id, is_deleted: false },
|
||||||
|
select: { id: true },
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (!page) {
|
||||||
|
page = await db.page.findFirst({
|
||||||
|
where: { id_site: site_id, is_deleted: false },
|
||||||
|
select: { id: true },
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (page) {
|
||||||
|
await user.conf.set(user_id, "page_id", page.id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return user.conf.get(user_id);
|
||||||
|
};
|
||||||
|
|
@ -5,10 +5,11 @@ import { WSData } from "../../../../pkgs/core/server/create";
|
||||||
import { ClientEvent } from "../../../web/src/utils/sync/ws-client";
|
import { ClientEvent } from "../../../web/src/utils/sync/ws-client";
|
||||||
import { SyncActionPaths } from "./actions-def";
|
import { SyncActionPaths } from "./actions-def";
|
||||||
import * as actions from "./actions/index";
|
import * as actions from "./actions/index";
|
||||||
import { loadDefaultSite } from "./editor/load";
|
import { loadDefaultSite } from "./editor/load-default";
|
||||||
|
import { loadSitePage } from "./editor/load-sitepage";
|
||||||
|
import { conns, wconns } from "./entity/conn";
|
||||||
import { UserConf, user } from "./entity/user";
|
import { UserConf, user } from "./entity/user";
|
||||||
import { SyncType } from "./type";
|
import { SyncType } from "./type";
|
||||||
import { conns, wconns } from "./entity/conn";
|
|
||||||
const packr = new Packr({ structuredClone: true });
|
const packr = new Packr({ structuredClone: true });
|
||||||
|
|
||||||
export const sendWS = (ws: ServerWebSocket<WSData>, msg: any) => {
|
export const sendWS = (ws: ServerWebSocket<WSData>, msg: any) => {
|
||||||
|
|
@ -40,13 +41,19 @@ export const syncHandler: WebSocketHandler<WSData> = {
|
||||||
if (conn) {
|
if (conn) {
|
||||||
const msg = packr.unpack(Buffer.from(raw));
|
const msg = packr.unpack(Buffer.from(raw));
|
||||||
if (msg.type === SyncType.UserID) {
|
if (msg.type === SyncType.UserID) {
|
||||||
const { user_id } = msg;
|
const { user_id, page_id, site_id } = msg;
|
||||||
conn.user_id = user_id;
|
conn.user_id = user_id;
|
||||||
|
|
||||||
const conf = await user.conf.getOrCreate(user_id);
|
let conf = await user.conf.getOrCreate(user_id);
|
||||||
if (!conf.site_id) {
|
if (site_id) {
|
||||||
|
const newconf = await loadSitePage(user_id, site_id, page_id);
|
||||||
|
if (newconf) conf = newconf;
|
||||||
|
} else if (!conf.site_id) {
|
||||||
await loadDefaultSite(user_id);
|
await loadDefaultSite(user_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
console.log(conf);
|
||||||
|
|
||||||
conn.conf = new Proxy(conf, {
|
conn.conf = new Proxy(conf, {
|
||||||
get(_, p) {
|
get(_, p) {
|
||||||
const conf = user.conf.get(user_id);
|
const conf = user.conf.get(user_id);
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ import { Loading } from "../../../utils/ui/loading";
|
||||||
import { PG } from "./ed-global";
|
import { PG } from "./ed-global";
|
||||||
import { Y } from "../../../../../srv/ws/sync/entity/docs";
|
import { Y } from "../../../../../srv/ws/sync/entity/docs";
|
||||||
import { treeRebuild } from "./tree/build";
|
import { treeRebuild } from "./tree/build";
|
||||||
|
import { w } from "../../../utils/types/general";
|
||||||
|
|
||||||
export const edInitSync = (p: PG) => {
|
export const edInitSync = (p: PG) => {
|
||||||
const session = JSON.parse(
|
const session = JSON.parse(
|
||||||
|
|
@ -13,26 +14,34 @@ export const edInitSync = (p: PG) => {
|
||||||
navigate("/login");
|
navigate("/login");
|
||||||
return <Loading note="logging in" />;
|
return <Loading note="logging in" />;
|
||||||
}
|
}
|
||||||
const paramsOK =
|
|
||||||
!!params.site_id &&
|
|
||||||
!!params.page_id &&
|
|
||||||
params.site_id !== "_" &&
|
|
||||||
params.page_id !== "_";
|
|
||||||
|
|
||||||
if (!p.sync) {
|
if (!p.sync) {
|
||||||
clientStartSync({
|
clientStartSync({
|
||||||
user_id: session.data.user.id,
|
user_id: session.data.user.id,
|
||||||
|
site_id: params.site_id,
|
||||||
|
page_id: params.page_id,
|
||||||
events: {
|
events: {
|
||||||
|
connected() {
|
||||||
|
if (w.offline) console.log("connected");
|
||||||
|
w.offline = false;
|
||||||
|
p.render();
|
||||||
|
},
|
||||||
|
disconnected() {
|
||||||
|
console.log("offline, reconnecting...");
|
||||||
|
w.offline = true;
|
||||||
|
p.render();
|
||||||
|
return {
|
||||||
|
reconnect: true,
|
||||||
|
};
|
||||||
|
},
|
||||||
editor_start(e) {
|
editor_start(e) {
|
||||||
if (!paramsOK) {
|
if (params.site_id !== e.site_id || params.page_id !== e.page_id) {
|
||||||
if (e.site_id && e.page_id) {
|
p.site.id = e.site_id;
|
||||||
p.site.id = e.site_id;
|
p.page.cur.id = e.page_id;
|
||||||
p.page.cur.id = e.page_id;
|
navigate(`/ed/${e.site_id}/${e.page_id}`);
|
||||||
navigate(`/ed/${e.site_id}/${e.page_id}`);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
p.site.id = params.site_id;
|
p.site.id = e.site_id;
|
||||||
p.page.cur.id = params.page_id;
|
p.page.cur.id = e.page_id;
|
||||||
p.render();
|
p.render();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -9,13 +9,14 @@ export const EdPopCompGroup = () => {
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
(async () => {
|
(async () => {
|
||||||
if (!p.comp.group[p.site.id]) {
|
if (p.ui.popup.comp_group) {
|
||||||
p.comp.group[p.site.id] = await p.sync.comp.group(p.site.id);
|
if (!p.comp.group[p.site.id]) {
|
||||||
|
p.comp.group[p.site.id] = await p.sync.comp.group(p.site.id);
|
||||||
|
}
|
||||||
|
p.render();
|
||||||
}
|
}
|
||||||
console.log(p.comp.group[p.site.id]);
|
|
||||||
p.render();
|
|
||||||
})();
|
})();
|
||||||
}, []);
|
}, [p.ui.popup.comp_group]);
|
||||||
|
|
||||||
if (!p.ui.popup.comp_group) return null;
|
if (!p.ui.popup.comp_group) return null;
|
||||||
const pop = p.ui.popup.comp_group;
|
const pop = p.ui.popup.comp_group;
|
||||||
|
|
|
||||||
|
|
@ -13,10 +13,12 @@ export const indentHook = (
|
||||||
let shouldOpen = open[p.page.cur.id] || [];
|
let shouldOpen = open[p.page.cur.id] || [];
|
||||||
|
|
||||||
const cur = p.page.meta[active.item_id];
|
const cur = p.page.meta[active.item_id];
|
||||||
let meta = p.page.meta[cur.parent_item.id];
|
if (cur && cur.parent_item) {
|
||||||
while (meta) {
|
let meta = p.page.meta[cur.parent_item.id];
|
||||||
if (meta.item.id) shouldOpen.push(meta.item.id);
|
while (meta) {
|
||||||
meta = p.page.meta[meta.parent_item.id];
|
if (meta.item.id) shouldOpen.push(meta.item.id);
|
||||||
|
meta = p.page.meta[meta.parent_item.id];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (shouldOpen.length > 0 && local.tree) {
|
if (shouldOpen.length > 0 && local.tree) {
|
||||||
|
|
|
||||||
|
|
@ -48,6 +48,8 @@ const sendWs = (ws: WebSocket, msg: any) => {
|
||||||
|
|
||||||
export const clientStartSync = async (arg: {
|
export const clientStartSync = async (arg: {
|
||||||
user_id: string;
|
user_id: string;
|
||||||
|
site_id?: string;
|
||||||
|
page_id?: string;
|
||||||
events: {
|
events: {
|
||||||
editor_start: (arg: UserConf) => void;
|
editor_start: (arg: UserConf) => void;
|
||||||
site_loaded: (arg: { site: ESite }) => void;
|
site_loaded: (arg: { site: ESite }) => void;
|
||||||
|
|
@ -56,11 +58,13 @@ export const clientStartSync = async (arg: {
|
||||||
id: string;
|
id: string;
|
||||||
sv_local: Uint8Array;
|
sv_local: Uint8Array;
|
||||||
}) => void;
|
}) => void;
|
||||||
|
disconnected: () => { reconnect: boolean };
|
||||||
|
connected: () => void;
|
||||||
};
|
};
|
||||||
}) => {
|
}) => {
|
||||||
const { user_id, events } = arg;
|
const { user_id, site_id, page_id, events } = arg;
|
||||||
conf.idb = initIDB(user_id);
|
conf.idb = initIDB(user_id);
|
||||||
await connect(user_id, events);
|
await connect({ user_id, site_id, page_id }, events);
|
||||||
return new DeepProxy(
|
return new DeepProxy(
|
||||||
SyncActionDefinition,
|
SyncActionDefinition,
|
||||||
({ target, trapName, value, key, DEFAULT, PROXY }) => {
|
({ target, trapName, value, key, DEFAULT, PROXY }) => {
|
||||||
|
|
@ -91,7 +95,11 @@ export const clientStartSync = async (arg: {
|
||||||
) as unknown as typeof SyncActions;
|
) as unknown as typeof SyncActions;
|
||||||
};
|
};
|
||||||
|
|
||||||
const connect = (user_id: string, event: ClientEventObject) => {
|
const connect = (
|
||||||
|
opt: { user_id: string; page_id?: string; site_id?: string },
|
||||||
|
event: ClientEventObject
|
||||||
|
) => {
|
||||||
|
const { user_id, page_id, site_id } = opt;
|
||||||
conf.event = event;
|
conf.event = event;
|
||||||
if (w.offline) {
|
if (w.offline) {
|
||||||
return new Promise<void>(async (resolve) => {
|
return new Promise<void>(async (resolve) => {
|
||||||
|
|
@ -104,55 +112,64 @@ const connect = (user_id: string, event: ClientEventObject) => {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
return new Promise<void>((resolve) => {
|
return new Promise<void>((resolve, reject) => {
|
||||||
if (!conf.ws) {
|
if (!conf.ws) {
|
||||||
const url = new URL(location.href);
|
let reconnect = 0;
|
||||||
url.pathname = "/sync";
|
const retry = () => {
|
||||||
url.protocol = url.protocol === "http:" ? "ws:" : "wss:";
|
const url = new URL(location.href);
|
||||||
|
url.pathname = "/sync";
|
||||||
|
url.protocol = url.protocol === "http:" ? "ws:" : "wss:";
|
||||||
|
|
||||||
const ws = new WebSocket(url.toString());
|
const ws = new WebSocket(url.toString());
|
||||||
|
|
||||||
ws.onopen = () => {
|
ws.onopen = () => {
|
||||||
sendWs(ws, { type: SyncType.UserID, user_id });
|
console.clear();
|
||||||
conf.ws = ws;
|
sendWs(ws, { type: SyncType.UserID, user_id, site_id, page_id });
|
||||||
};
|
conf.ws = ws;
|
||||||
ws.onclose = async () => {
|
event.connected();
|
||||||
console.log("disconnected..");
|
};
|
||||||
w.offline = true;
|
ws.onclose = async () => {
|
||||||
if (!conf.ws) {
|
const res = event.disconnected();
|
||||||
await connect(user_id, event);
|
if (res.reconnect) {
|
||||||
resolve();
|
setTimeout(async () => {
|
||||||
}
|
reconnect++;
|
||||||
};
|
retry();
|
||||||
ws.onmessage = async (e) => {
|
}, reconnect * 5000);
|
||||||
const raw = e.data as Blob;
|
} else {
|
||||||
const msg = packr.unpack(Buffer.from(await raw.arrayBuffer()));
|
reject();
|
||||||
if (WS_DEBUG) console.log(`%c⬇`, `color:red`, msg);
|
|
||||||
|
|
||||||
if (msg.type === SyncType.ClientID) {
|
|
||||||
conf.client_id = msg.client_id;
|
|
||||||
resolve();
|
|
||||||
} else if (msg.type === SyncType.Event) {
|
|
||||||
const eventName = msg.event as ClientEvent;
|
|
||||||
|
|
||||||
if (event[eventName]) {
|
|
||||||
if (offlineEvents.includes(eventName)) {
|
|
||||||
saveEventOffline(eventName, msg.data);
|
|
||||||
}
|
|
||||||
event[eventName](msg.data);
|
|
||||||
}
|
}
|
||||||
} else if (msg.type === SyncType.ActionResult) {
|
};
|
||||||
const pending = runtime.action.pending[msg.argid];
|
ws.onmessage = async (e) => {
|
||||||
if (pending) {
|
const raw = e.data as Blob;
|
||||||
delete runtime.action.pending[msg.argid];
|
const msg = packr.unpack(Buffer.from(await raw.arrayBuffer()));
|
||||||
const idb = conf.idb;
|
if (WS_DEBUG) console.log(`%c⬇`, `color:red`, msg);
|
||||||
if (idb) {
|
|
||||||
await set(msg.argid, msg.val, idb);
|
if (msg.type === SyncType.ClientID) {
|
||||||
|
conf.client_id = msg.client_id;
|
||||||
|
resolve();
|
||||||
|
} else if (msg.type === SyncType.Event) {
|
||||||
|
const eventName = msg.event as ClientEvent;
|
||||||
|
|
||||||
|
if (event[eventName]) {
|
||||||
|
if (offlineEvents.includes(eventName)) {
|
||||||
|
saveEventOffline(eventName, msg.data);
|
||||||
|
}
|
||||||
|
event[eventName](msg.data);
|
||||||
|
}
|
||||||
|
} else if (msg.type === SyncType.ActionResult) {
|
||||||
|
const pending = runtime.action.pending[msg.argid];
|
||||||
|
if (pending) {
|
||||||
|
delete runtime.action.pending[msg.argid];
|
||||||
|
const idb = conf.idb;
|
||||||
|
if (idb) {
|
||||||
|
await set(msg.argid, msg.val, idb);
|
||||||
|
}
|
||||||
|
pending.resolve(msg.val);
|
||||||
}
|
}
|
||||||
pending.resolve(msg.val);
|
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
};
|
};
|
||||||
|
retry();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue