fix sync
This commit is contained in:
parent
7052dad65b
commit
8b35fa274e
|
|
@ -1,7 +1,7 @@
|
||||||
import { user } from "../user";
|
import { user } from "../user";
|
||||||
|
|
||||||
export const syncEditorLoad = async (user_id: string) => {
|
export const loadUserConf = async (user_id: string) => {
|
||||||
const conf = user.conf.get(user_id);
|
const conf = user.conf.getOrCreate(user_id);
|
||||||
if (conf) {
|
if (conf) {
|
||||||
if (!conf.site_id) {
|
if (!conf.site_id) {
|
||||||
const site = await db.site.findFirst({
|
const site = await db.site.findFirst({
|
||||||
|
|
@ -11,7 +11,10 @@ export const syncEditorLoad = async (user_id: string) => {
|
||||||
},
|
},
|
||||||
select: { id: true },
|
select: { id: true },
|
||||||
});
|
});
|
||||||
if (site) conf.site_id = site.id;
|
if (site) {
|
||||||
|
conf.site_id = site.id;
|
||||||
|
user.conf.set(user_id, "site_id", site.id);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (conf.site_id && !conf.page_id) {
|
if (conf.site_id && !conf.page_id) {
|
||||||
|
|
@ -25,7 +28,9 @@ export const syncEditorLoad = async (user_id: string) => {
|
||||||
|
|
||||||
if (page) {
|
if (page) {
|
||||||
conf.page_id = page.id;
|
conf.page_id = page.id;
|
||||||
|
user.conf.set(user_id, "page_id", page.id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return conf;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,8 @@ import { createId } from "@paralleldrive/cuid2";
|
||||||
import { ServerWebSocket, WebSocketHandler } from "bun";
|
import { ServerWebSocket, WebSocketHandler } from "bun";
|
||||||
import { Packr } from "msgpackr";
|
import { Packr } from "msgpackr";
|
||||||
import { WSData } from "../../../../pkgs/core/server/create";
|
import { WSData } from "../../../../pkgs/core/server/create";
|
||||||
|
import { ClientEvent } from "../../../web/src/utils/sync/client";
|
||||||
|
import { loadUserConf } from "./editor/load";
|
||||||
import { SyncType } from "./type";
|
import { SyncType } from "./type";
|
||||||
const packr = new Packr({ structuredClone: true });
|
const packr = new Packr({ structuredClone: true });
|
||||||
|
|
||||||
|
|
@ -17,6 +19,9 @@ const conns = new Map<
|
||||||
}
|
}
|
||||||
>();
|
>();
|
||||||
const wconns = new WeakMap<ServerWebSocket<WSData>, string>();
|
const wconns = new WeakMap<ServerWebSocket<WSData>, string>();
|
||||||
|
const send = (ws: ServerWebSocket<WSData>, msg: any) => {
|
||||||
|
ws.sendBinary(packr.pack(msg));
|
||||||
|
};
|
||||||
export const syncHandler: WebSocketHandler<WSData> = {
|
export const syncHandler: WebSocketHandler<WSData> = {
|
||||||
open(ws) {
|
open(ws) {
|
||||||
const client_id = createId();
|
const client_id = createId();
|
||||||
|
|
@ -26,7 +31,7 @@ export const syncHandler: WebSocketHandler<WSData> = {
|
||||||
msg: { pending: {}, resolve: {} },
|
msg: { pending: {}, resolve: {} },
|
||||||
});
|
});
|
||||||
wconns.set(ws, client_id);
|
wconns.set(ws, client_id);
|
||||||
ws.sendBinary(packr.pack({ type: SyncType.ClientID, client_id }));
|
send(ws, { type: SyncType.ClientID, client_id });
|
||||||
},
|
},
|
||||||
close(ws, code, reason) {
|
close(ws, code, reason) {
|
||||||
const conn_id = wconns.get(ws);
|
const conn_id = wconns.get(ws);
|
||||||
|
|
@ -35,7 +40,7 @@ export const syncHandler: WebSocketHandler<WSData> = {
|
||||||
wconns.delete(ws);
|
wconns.delete(ws);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
message(ws, raw) {
|
async message(ws, raw) {
|
||||||
const conn_id = wconns.get(ws);
|
const conn_id = wconns.get(ws);
|
||||||
if (conn_id) {
|
if (conn_id) {
|
||||||
const conn = conns.get(conn_id);
|
const conn = conns.get(conn_id);
|
||||||
|
|
@ -44,6 +49,12 @@ export const syncHandler: WebSocketHandler<WSData> = {
|
||||||
if (msg.type === SyncType.UserID) {
|
if (msg.type === SyncType.UserID) {
|
||||||
const { user_id } = msg;
|
const { user_id } = msg;
|
||||||
conn.user_id = user_id;
|
conn.user_id = user_id;
|
||||||
|
const conf = await loadUserConf(user_id);
|
||||||
|
send(ws, {
|
||||||
|
type: SyncType.Event,
|
||||||
|
event: "editor_start" as ClientEvent,
|
||||||
|
data: conf,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
export enum SyncType {
|
export enum SyncType {
|
||||||
ClientID,
|
ClientID,
|
||||||
UserID,
|
UserID,
|
||||||
Event
|
Event,
|
||||||
}
|
}
|
||||||
|
|
@ -15,6 +15,14 @@ const db = open<UserConf, string>({
|
||||||
|
|
||||||
export const user = {
|
export const user = {
|
||||||
conf: {
|
conf: {
|
||||||
|
getOrCreate(user_id: string) {
|
||||||
|
const res = db.get(user_id);
|
||||||
|
if (!res) {
|
||||||
|
db.put(user_id, structuredClone(defaultConf));
|
||||||
|
return db.get(user_id);
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
},
|
||||||
get(user_id: string) {
|
get(user_id: string) {
|
||||||
return db.get(user_id);
|
return db.get(user_id);
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,10 @@ export default page({
|
||||||
component: ({}) => {
|
component: ({}) => {
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (localStorage.getItem("prasi-session")) {
|
if (localStorage.getItem("prasi-session")) {
|
||||||
if (location.pathname.startsWith("/ed/")) {
|
if (
|
||||||
|
location.pathname === "/ed" ||
|
||||||
|
location.pathname.startsWith("/ed/")
|
||||||
|
) {
|
||||||
navigate("/ed/_/_");
|
navigate("/ed/_/_");
|
||||||
} else {
|
} else {
|
||||||
navigate("/editor/_/_");
|
navigate("/editor/_/_");
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,7 @@
|
||||||
import { page, useGlobal } from "web-utils";
|
import { page, useGlobal } from "web-utils";
|
||||||
import { EditorGlobal } from "../../render/editor/logic/global";
|
|
||||||
import { Loading } from "../../utils/ui/loading";
|
|
||||||
import { clientStartSync } from "../../utils/sync/client";
|
|
||||||
import { EDGlobal } from "../../render/ed/logic/global";
|
import { EDGlobal } from "../../render/ed/logic/global";
|
||||||
|
import { clientStartSync } from "../../utils/sync/client";
|
||||||
|
import { Loading } from "../../utils/ui/loading";
|
||||||
|
|
||||||
export default page({
|
export default page({
|
||||||
url: "/ed/:site_id/:page_id",
|
url: "/ed/:site_id/:page_id",
|
||||||
|
|
@ -20,9 +19,14 @@ export default page({
|
||||||
if (!p.sync) {
|
if (!p.sync) {
|
||||||
p.sync = clientStartSync({
|
p.sync = clientStartSync({
|
||||||
user_id: session.data.user.id,
|
user_id: session.data.user.id,
|
||||||
events: { editor_start() {} },
|
events: {
|
||||||
|
editor_start(e) {
|
||||||
|
if (e.site_id && e.page_id) {
|
||||||
|
navigate(`/ed/${e.site_id}/${e.page_id}`);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
return <Loading />;
|
return <Loading />;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -14,6 +14,10 @@ export const all = {
|
||||||
url: "**",
|
url: "**",
|
||||||
page: () => import("./page/all"),
|
page: () => import("./page/all"),
|
||||||
};
|
};
|
||||||
|
export const ed = {
|
||||||
|
url: "/ed/:site_id/:page_id",
|
||||||
|
page: () => import("./page/ed"),
|
||||||
|
};
|
||||||
export const editor = {
|
export const editor = {
|
||||||
url: "/editor/:site_id/:page_id",
|
url: "/editor/:site_id/:page_id",
|
||||||
page: () => import("./page/editor"),
|
page: () => import("./page/editor"),
|
||||||
|
|
@ -22,7 +26,3 @@ export const live = {
|
||||||
url: "/live/:domain/**",
|
url: "/live/:domain/**",
|
||||||
page: () => import("./page/live"),
|
page: () => import("./page/live"),
|
||||||
};
|
};
|
||||||
export const ned = {
|
|
||||||
url: "/ed/:site_id/:page_id",
|
|
||||||
page: () => import("./page/ned"),
|
|
||||||
};
|
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,9 @@ type User = {
|
||||||
name: string;
|
name: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export type ClientEventObject = Parameters<typeof clientStartSync>[0]["events"];
|
||||||
|
export type ClientEvent = keyof ClientEventObject;
|
||||||
|
|
||||||
export const clientStartSync = async (arg: {
|
export const clientStartSync = async (arg: {
|
||||||
user_id: string;
|
user_id: string;
|
||||||
events: {
|
events: {
|
||||||
|
|
@ -31,7 +34,7 @@ export const clientStartSync = async (arg: {
|
||||||
}) => {
|
}) => {
|
||||||
const { user_id, events } = arg;
|
const { user_id, events } = arg;
|
||||||
conf.idb = initIDB(user_id);
|
conf.idb = initIDB(user_id);
|
||||||
await connect(user_id);
|
await connect(user_id, events);
|
||||||
const path: any[] = [];
|
const path: any[] = [];
|
||||||
return new DeepProxy(
|
return new DeepProxy(
|
||||||
SyncActionDefinition,
|
SyncActionDefinition,
|
||||||
|
|
@ -64,7 +67,7 @@ export const clientStartSync = async (arg: {
|
||||||
) as unknown as typeof SyncActions;
|
) as unknown as typeof SyncActions;
|
||||||
};
|
};
|
||||||
|
|
||||||
const connect = (user_id: string) => {
|
const connect = (user_id: string, event: ClientEventObject) => {
|
||||||
return new Promise<WebSocket>((resolve) => {
|
return new Promise<WebSocket>((resolve) => {
|
||||||
if (!conf.ws) {
|
if (!conf.ws) {
|
||||||
const url = new URL(location.href);
|
const url = new URL(location.href);
|
||||||
|
|
@ -83,7 +86,11 @@ const connect = (user_id: string) => {
|
||||||
if (msg.type === SyncType.ClientID) {
|
if (msg.type === SyncType.ClientID) {
|
||||||
conf.client_id = msg.client_id;
|
conf.client_id = msg.client_id;
|
||||||
resolve(ws);
|
resolve(ws);
|
||||||
} else if (msg.type === "event") {
|
} else if (msg.type === SyncType.Event) {
|
||||||
|
const eventName = msg.event as keyof ClientEventObject;
|
||||||
|
if (event[eventName]) {
|
||||||
|
event[eventName](msg.data);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Binary file not shown.
Binary file not shown.
Loading…
Reference in New Issue