This commit is contained in:
Rizky 2023-10-20 15:07:52 +07:00
parent 7052dad65b
commit 8b35fa274e
10 changed files with 57 additions and 19 deletions

View File

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

View File

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

View File

@ -1,5 +1,5 @@
export enum SyncType { export enum SyncType {
ClientID, ClientID,
UserID, UserID,
Event Event,
} }

View File

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

View File

@ -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/_/_");

View File

@ -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 />;
} }

View File

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

View File

@ -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.