This commit is contained in:
Rizky 2023-10-20 16:14:32 +07:00
parent 8b35fa274e
commit 4de34a8a86
6 changed files with 104 additions and 46 deletions

View File

@ -18,7 +18,7 @@ export default page({
} else {
navigate("/login");
}
}, []);
});
return <Loading />;
},

View File

@ -21,9 +21,13 @@ export default page({
user_id: session.data.user.id,
events: {
editor_start(e) {
if (params.site_id !== "_" && params.page_id !== "_") {
p.render();
} else {
if (e.site_id && e.page_id) {
navigate(`/ed/${e.site_id}/${e.page_id}`);
}
}
},
},
});

View File

@ -10,7 +10,7 @@ const start = async () => {
let react = {
root: null as null | ReactRoot,
};
if (!["localhost", "127.0.0.1"].includes(location.hostname)) {
if (true || !["localhost", "127.0.0.1"].includes(location.hostname)) {
const sw = await registerServiceWorker();
navigator.serviceWorker.addEventListener("message", (e) => {
if (react.root) {
@ -125,9 +125,11 @@ const start = async () => {
const swc = navigator.serviceWorker.controller;
if (swc) {
[location.href, "", "/", "/ed", "/ed/_/_", "/login"].forEach((url) => {
swc.postMessage({
type: "add-cache",
url: location.href,
url: url,
});
});
if (w.prasiApi && w.prasiApi[base] && w.prasiApi[base].apiEntry) {
const routes = Object.entries(w.prasiApi[base].apiEntry).map(

View File

@ -1,17 +1,19 @@
import { DeepProxy } from "@qiwi/deep-proxy";
import { xxhash32 } from "hash-wasm";
import { UseStore, get } from "idb-keyval";
import { UseStore, get, set } from "idb-keyval";
import { Packr } from "msgpackr";
import { stringify } from "safe-stable-stringify";
import { SyncActions } from "../../../../srv/ws/sync/actions";
import { SyncActionDefinition } from "../../../../srv/ws/sync/actions-def";
import { initIDB } from "./idb";
import { SyncType } from "../../../../srv/ws/sync/type";
import { w } from "../types/general";
const packr = new Packr({ structuredClone: true });
const conf = {
ws: null as null | WebSocket,
client_id: "",
idb: null as null | UseStore,
event: null as null | ClientEventObject,
};
type User = {
@ -48,7 +50,7 @@ export const clientStartSync = async (arg: {
if (path[0] === "then") path.shift();
return (...args: any[]) =>
new Promise((resolve) => {
operation({
doAction({
path: path.join("."),
resolve,
args,
@ -68,52 +70,95 @@ export const clientStartSync = async (arg: {
};
const connect = (user_id: string, event: ClientEventObject) => {
return new Promise<WebSocket>((resolve) => {
conf.event = event;
if (w.offline) {
return new Promise<void>(async (resolve) => {
resolve();
const eventName = "editor_start";
const data = await loadOfflineMsg("ev", eventName);
if (event[eventName]) {
event[eventName](data);
}
});
} else {
return new Promise<void>((resolve) => {
if (!conf.ws) {
const url = new URL(location.href);
url.pathname = "/sync";
url.protocol = url.protocol === "http:" ? "ws:" : "wss:";
const ws = new WebSocket(url.toString());
conf.ws = ws;
ws.onopen = () => {
ws.send(packr.pack({ type: SyncType.UserID, user_id }));
conf.ws = ws;
};
ws.onclose = async () => {
w.offline = true;
if (!conf.ws) {
await connect(user_id, event);
resolve();
}
};
ws.onmessage = async (e) => {
const raw = e.data as Blob;
const msg = packr.unpack(Buffer.from(await raw.arrayBuffer()));
if (msg.type === SyncType.ClientID) {
conf.client_id = msg.client_id;
resolve(ws);
resolve();
} else if (msg.type === SyncType.Event) {
const eventName = msg.event as keyof ClientEventObject;
const eventName = msg.event as ClientEvent;
if (event[eventName]) {
if (offlineEvents.includes(eventName)) {
saveOfflineMsg("ev", eventName, msg.data);
}
event[eventName](msg.data);
}
}
};
}
});
}
};
const operation = async (arg: {
const offlineEvents: ClientEvent[] = ["editor_start"];
const saveOfflineMsg = async (type: "ev", name: ClientEvent, data: any) => {
const idb = conf.idb;
if (idb) {
const hargs = await xxhash32(`${type}-${name}`);
await set(hargs, data, idb);
}
};
const loadOfflineMsg = async (type: "ev", name: ClientEvent) => {
const idb = conf.idb;
if (idb) {
const hargs = await xxhash32(`${type}-${name}`);
return await get(hargs, idb);
}
};
const doAction = <T>(arg: {
path: string;
resolve: (value: any) => void;
args: any[];
}) => {
return new Promise<T>(async (resolve) => {
const ws = conf.ws;
const idb = conf.idb;
if (idb) {
const sargs = stringify(arg.args);
const hargs = await xxhash32(`${arg.path}-${sargs}`);
const hargs = await xxhash32(`op-${arg.path}-${sargs}`);
if (ws && ws.readyState === ws.OPEN) {
if (w.offline || (ws && ws.readyState === ws.OPEN)) {
// online
} else {
// offline
const cache = await get(hargs, idb);
console.log(cache);
resolve(cache as T);
}
}
});
};

View File

@ -84,6 +84,13 @@ export const defineWindow = async (awaitServerUrl = true) => {
if (typeof window === "object") {
window.addEventListener("popstate", () => {
const sw = navigator.serviceWorker.controller;
if (sw) {
sw.postMessage({
type: "add-cache",
url: location.href,
});
}
if (w.preventPopRender) {
w.preventPopRender = false;
return;

Binary file not shown.