wip fix
This commit is contained in:
parent
2a5e0164a4
commit
d335510e69
|
|
@ -1 +1,3 @@
|
||||||
u Œ“Tõ5Jk¿“ŸÖË~ɪ¼2<C2BC>Òõ<><C3B5>R€º<E282AC>´ÖñÞR’’vÃl³p$ƒq§Û<þ‚ 有‡Å`aúŠH=(øX9 F”²,$´©ï<EFBFBD>%ïú@0ìÅØ>OºÍ#îýHò«'öVìààGzàŽÝÈe$cý@™¾týÌ«c^ùj1Úd%Q¸š±ôˆPT :ÒüoTeˆÂ¤×Ù$<24>i
|
Æ ŒÔ`Íž±®Tw®³B¬Â¡`y9ûÿc3¦˜u!k
|
||||||
|
?AÄ®Óv=þ®Hg›$YH†ø…"
=˜2àYÑ
|
||||||
|
4V)á‹mŠ;Dk…]/LuÁ·Gri¯+õtº$ù/}o¥èü<0F>±›(»”é§Ýø"ûãveñ$ñj±_äBŹG}GÒC«JÒ‘ÿ•Y{¡7‹?¯ºÎLU/jìÞjêþÔNûu
_¬×m\¸^äÆ?F_V76S
|
||||||
|
|
@ -11,6 +11,7 @@
|
||||||
<body className="flex-col flex-1 w-full min-h-screen flex opacity-0">
|
<body className="flex-col flex-1 w-full min-h-screen flex opacity-0">
|
||||||
<div id="root"></div>
|
<div id="root"></div>
|
||||||
<script src="/index.js"></script>
|
<script src="/index.js"></script>
|
||||||
|
<script>window.__REACT_DEVTOOLS_GLOBAL_HOOK__ = { isDisabled: true };</script>
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
</html>
|
</html>
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
(BigInt.prototype as any).toJSON = function (): string {
|
(BigInt.prototype as any).toJSON = function (): string {
|
||||||
return `BigInt::` + this.toString();
|
return `BigInt::` + this.toString();
|
||||||
};
|
};
|
||||||
let w = window;
|
let w = window as any;
|
||||||
|
|
||||||
export const fetchViaProxy = async (
|
export const fetchViaProxy = async (
|
||||||
url: string,
|
url: string,
|
||||||
|
|
@ -64,7 +64,7 @@ export const fetchViaProxy = async (
|
||||||
return raw;
|
return raw;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
const res = await fetch(`/_proxy`, {
|
const res = await fetch(`${w.basehost ? w.basehost : ""}/_proxy`, {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
body: JSON.stringify([
|
body: JSON.stringify([
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -9,38 +9,37 @@ import { registerMobile } from "./render/live/logic/mobile";
|
||||||
import { sworkerAddCache, sworkerRegister } from "./sworker-boot";
|
import { sworkerAddCache, sworkerRegister } from "./sworker-boot";
|
||||||
import { w } from "./utils/types/general";
|
import { w } from "./utils/types/general";
|
||||||
|
|
||||||
|
|
||||||
const start = async () => {
|
const start = async () => {
|
||||||
const base = `${location.protocol}//${location.host}`;
|
let react = {
|
||||||
let react = {
|
root: null as null | ReactRoot,
|
||||||
root: null as null | ReactRoot,
|
};
|
||||||
};
|
w.mobile = registerMobile();
|
||||||
w.mobile = registerMobile();
|
|
||||||
|
|
||||||
const cur = new URL(location.href);
|
const cur = new URL(w.basehost || location.href);
|
||||||
const base_url = `${cur.protocol}//${cur.host}`;
|
const base_url = `${cur.protocol}//${cur.host}`;
|
||||||
w.db = dbProxy(base_url);
|
w.db = dbProxy(base_url);
|
||||||
|
|
||||||
try {
|
|
||||||
await loadApiProxyDef(base_url, false);
|
|
||||||
w.api = apiProxy(base_url);
|
|
||||||
} catch (e) {
|
|
||||||
console.warn("Failed to load API:", base_url);
|
|
||||||
}
|
|
||||||
|
|
||||||
w.serverurl = base;
|
try {
|
||||||
|
await loadApiProxyDef(base_url, false);
|
||||||
|
w.api = apiProxy(base_url);
|
||||||
|
} catch (e) {
|
||||||
|
console.warn("Failed to load API:", base_url);
|
||||||
|
}
|
||||||
|
|
||||||
sworkerRegister(react);
|
w.serverurl = base_url;
|
||||||
defineReact();
|
|
||||||
await defineWindow(false);
|
|
||||||
sworkerAddCache(base);
|
|
||||||
|
|
||||||
const el = document.getElementById("root");
|
sworkerRegister(react);
|
||||||
|
defineReact();
|
||||||
|
await defineWindow(false);
|
||||||
|
sworkerAddCache(base_url);
|
||||||
|
|
||||||
if (el) {
|
const el = document.getElementById("root");
|
||||||
react.root = createRoot(el);
|
|
||||||
react.root.render(<Root />);
|
if (el) {
|
||||||
}
|
react.root = createRoot(el);
|
||||||
|
react.root.render(<Root />);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
start();
|
start();
|
||||||
|
|
|
||||||
|
|
@ -26,9 +26,13 @@ export const edInitSync = (p: PG) => {
|
||||||
location.href = "/login";
|
location.href = "/login";
|
||||||
return <Loading note="logging in" />;
|
return <Loading note="logging in" />;
|
||||||
}
|
}
|
||||||
p.user.id = session.data.user.id;
|
if (session?.data?.user) {
|
||||||
p.user.username = session.data.user.username;
|
p.user.id = session.data.user.id;
|
||||||
|
p.user.username = session.data.user.username;
|
||||||
|
} else {
|
||||||
|
p.user.id = "ab1390f5-40d5-448e-a8c3-84b0fb600930";
|
||||||
|
p.user.username = "anonymous";
|
||||||
|
}
|
||||||
if (!params.page_id) {
|
if (!params.page_id) {
|
||||||
if (location.pathname.startsWith("/vi/")) {
|
if (location.pathname.startsWith("/vi/")) {
|
||||||
p.preview.show_loading = false;
|
p.preview.show_loading = false;
|
||||||
|
|
@ -164,7 +168,7 @@ export const edInitSync = (p: PG) => {
|
||||||
}
|
}
|
||||||
if (!p.sync) {
|
if (!p.sync) {
|
||||||
clientStartSync({
|
clientStartSync({
|
||||||
user_id: session.data.user.id,
|
user_id: p.user.id,
|
||||||
site_id: params.site_id,
|
site_id: params.site_id,
|
||||||
page_id: params.page_id,
|
page_id: params.page_id,
|
||||||
events: {
|
events: {
|
||||||
|
|
@ -250,7 +254,7 @@ export const edInitSync = (p: PG) => {
|
||||||
if (res) {
|
if (res) {
|
||||||
Y.applyUpdate(doc, decompress(res.diff), "sv_remote");
|
Y.applyUpdate(doc, decompress(res.diff), "sv_remote");
|
||||||
if (data.type === "page") {
|
if (data.type === "page") {
|
||||||
delete p.preview.meta_cache[data.id]
|
delete p.preview.meta_cache[data.id];
|
||||||
await treeRebuild(p, { note: "sv_remote" });
|
await treeRebuild(p, { note: "sv_remote" });
|
||||||
} else if (data.type === "comp") {
|
} else if (data.type === "comp") {
|
||||||
const updated = await updateComponentMeta(p, doc, data.id);
|
const updated = await updateComponentMeta(p, doc, data.id);
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,5 @@
|
||||||
|
import { w } from "../../../../../../utils/types/general";
|
||||||
|
|
||||||
function toAbsoluteURL(url: string) {
|
function toAbsoluteURL(url: string) {
|
||||||
const a = document.createElement("a");
|
const a = document.createElement("a");
|
||||||
a.setAttribute("href", url); // <a href="hoge.html">
|
a.setAttribute("href", url); // <a href="hoge.html">
|
||||||
|
|
@ -28,7 +30,7 @@ export function importModule(url: string) {
|
||||||
resolve((window as any)[vector]);
|
resolve((window as any)[vector]);
|
||||||
destructor();
|
destructor();
|
||||||
};
|
};
|
||||||
const absURL = toAbsoluteURL(url);
|
const absURL = w.basehost ? w.basehost + url : toAbsoluteURL(url);
|
||||||
const loader = `import * as m from "${absURL}"; window.${vector} = m;`; // export Module
|
const loader = `import * as m from "${absURL}"; window.${vector} = m;`; // export Module
|
||||||
const blob = new Blob([loader], { type: "text/javascript" });
|
const blob = new Blob([loader], { type: "text/javascript" });
|
||||||
script.src = URL.createObjectURL(blob);
|
script.src = URL.createObjectURL(blob);
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
import { apiProxy } from "../../../base/load/api/api-proxy";
|
import { apiProxy } from "../../../base/load/api/api-proxy";
|
||||||
import { loadApiProxyDef } from "../../../base/load/api/api-proxy-def";
|
import { loadApiProxyDef } from "../../../base/load/api/api-proxy-def";
|
||||||
import { dbProxy } from "../../../base/load/db/db-proxy";
|
import { dbProxy } from "../../../base/load/db/db-proxy";
|
||||||
import importModule from "../../../render/editor/tools/dynamic-import";
|
import importModule from "../../ed/panel/side/style/tools/dynamic-import";
|
||||||
import { VG } from "../render/global";
|
import { VG } from "../render/global";
|
||||||
import { viScriptArg } from "../render/script/arg";
|
import { viScriptArg } from "../render/script/arg";
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -150,7 +150,7 @@ const connect = (
|
||||||
if (!conf.ws) {
|
if (!conf.ws) {
|
||||||
let reconnect = 0;
|
let reconnect = 0;
|
||||||
const retry = () => {
|
const retry = () => {
|
||||||
const url = new URL(location.href);
|
const url = new URL(w.basehost || location.href);
|
||||||
url.pathname = "/sync";
|
url.pathname = "/sync";
|
||||||
url.protocol = url.protocol === "http:" ? "ws:" : "wss:";
|
url.protocol = url.protocol === "http:" ? "ws:" : "wss:";
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,7 @@ export type PrasiAPI = {
|
||||||
export const w = window as unknown as {
|
export const w = window as unknown as {
|
||||||
isEditor: boolean;
|
isEditor: boolean;
|
||||||
isMobile: boolean;
|
isMobile: boolean;
|
||||||
|
basehost?: string;
|
||||||
basepath: string;
|
basepath: string;
|
||||||
navigateOverride: (s: string) => string;
|
navigateOverride: (s: string) => string;
|
||||||
isDesktop: boolean;
|
isDesktop: boolean;
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import { g } from "utils/global";
|
|
||||||
import { gzipAsync } from "../../../app/srv/ws/sync/entity/zlib";
|
import { gzipAsync } from "../../../app/srv/ws/sync/entity/zlib";
|
||||||
|
import { CORS_HEADERS } from "../server/serve-api";
|
||||||
|
|
||||||
export const _ = {
|
export const _ = {
|
||||||
url: "/_proxy/*",
|
url: "/_proxy/*",
|
||||||
|
|
@ -38,6 +38,6 @@ export const _ = {
|
||||||
delete headers["content-encoding"];
|
delete headers["content-encoding"];
|
||||||
}
|
}
|
||||||
|
|
||||||
return new Response(body, { headers });
|
return new Response(body, { headers: { ...headers, ...CORS_HEADERS } });
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
import { g } from "utils/global";
|
import { g } from "utils/global";
|
||||||
|
import { CORS_HEADERS } from "../serve-api";
|
||||||
|
|
||||||
const parseQueryParams = (ctx: any) => {
|
const parseQueryParams = (ctx: any) => {
|
||||||
const pageHref = ctx.req.url;
|
const pageHref = ctx.req.url;
|
||||||
|
|
@ -69,11 +70,15 @@ export const createResponse = (existingRes: any, body: any) => {
|
||||||
res.headers.set("content-type", "application/json");
|
res.headers.set("content-type", "application/json");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const cur = existingRes as Response;
|
const cur = existingRes as Response;
|
||||||
for (const [key, value] of cur.headers.entries()) {
|
for (const [key, value] of cur.headers.entries()) {
|
||||||
res.headers.set(key, value);
|
res.headers.set(key, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (const [k, v] of Object.entries(CORS_HEADERS)) {
|
||||||
|
res.headers.set(k, v);
|
||||||
|
}
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,11 @@ import { createRouter } from "radix3";
|
||||||
import { g } from "utils/global";
|
import { g } from "utils/global";
|
||||||
import { createResponse } from "./api/api-ctx";
|
import { createResponse } from "./api/api-ctx";
|
||||||
|
|
||||||
|
export const CORS_HEADERS = {
|
||||||
|
"access-control-allow-origin": "*",
|
||||||
|
"access-control-allow-headers": "content-type",
|
||||||
|
};
|
||||||
|
|
||||||
export const serveAPI = {
|
export const serveAPI = {
|
||||||
init: async () => {
|
init: async () => {
|
||||||
g.router = createRouter({ strictTrailingSlash: false });
|
g.router = createRouter({ strictTrailingSlash: false });
|
||||||
|
|
@ -38,6 +43,12 @@ export const serveAPI = {
|
||||||
});
|
});
|
||||||
|
|
||||||
if (req.method !== "GET") {
|
if (req.method !== "GET") {
|
||||||
|
if (req.method === "OPTIONS") {
|
||||||
|
return new Response("OK", {
|
||||||
|
headers: CORS_HEADERS,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
if (
|
if (
|
||||||
!req.headers.get("content-type")?.startsWith("multipart/form-data")
|
!req.headers.get("content-type")?.startsWith("multipart/form-data")
|
||||||
) {
|
) {
|
||||||
|
|
@ -82,9 +93,13 @@ export const serveAPI = {
|
||||||
const finalResponse = await current.fn(...args);
|
const finalResponse = await current.fn(...args);
|
||||||
|
|
||||||
if (finalResponse instanceof Response) {
|
if (finalResponse instanceof Response) {
|
||||||
|
for (const [k, v] of Object.entries(CORS_HEADERS)) {
|
||||||
|
finalResponse.headers.set(k, v);
|
||||||
|
}
|
||||||
|
|
||||||
return finalResponse;
|
return finalResponse;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (finalResponse) {
|
if (finalResponse) {
|
||||||
return createResponse(current.res, finalResponse);
|
return createResponse(current.res, finalResponse);
|
||||||
}
|
}
|
||||||
|
|
@ -101,6 +116,10 @@ export const serveAPI = {
|
||||||
res.headers.set(k, v);
|
res.headers.set(k, v);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
for (const [k, v] of Object.entries(CORS_HEADERS)) {
|
||||||
|
res.headers.set(k, v);
|
||||||
|
}
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,93 +3,95 @@ import { exists, inspectTreeAsync } from "fs-jetpack";
|
||||||
import { InspectTreeResult } from "fs-jetpack/types";
|
import { InspectTreeResult } from "fs-jetpack/types";
|
||||||
import { join } from "path";
|
import { join } from "path";
|
||||||
import { watch } from "fs";
|
import { watch } from "fs";
|
||||||
|
import { CORS_HEADERS } from "./serve-api";
|
||||||
|
|
||||||
import mime from "mime";
|
import mime from "mime";
|
||||||
import { g } from "utils/global";
|
import { g } from "utils/global";
|
||||||
|
|
||||||
const web = {
|
const web = {
|
||||||
brExists: null as null | boolean,
|
brExists: null as null | boolean,
|
||||||
get path() {
|
get path() {
|
||||||
if (g.mode === "dev") return "static";
|
if (g.mode === "dev") return "static";
|
||||||
if (this.brExists === null) {
|
if (this.brExists === null) {
|
||||||
this.brExists = !!exists(dir.path("app/static-br"));
|
this.brExists = !!exists(dir.path("app/static-br"));
|
||||||
}
|
}
|
||||||
if (this.brExists) return "static-br";
|
if (this.brExists) return "static-br";
|
||||||
else return "static";
|
else return "static";
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
const cache = {
|
const cache = {
|
||||||
static: {} as Record<
|
static: {} as Record<
|
||||||
string,
|
string,
|
||||||
{ type: string; content: any; compression: "" | "br" }
|
{ type: string; content: any; compression: "" | "br" }
|
||||||
>,
|
>,
|
||||||
};
|
};
|
||||||
|
|
||||||
export const serveStatic = {
|
export const serveStatic = {
|
||||||
init: async () => {
|
init: async () => {
|
||||||
const list = await inspectTreeAsync(dir.path(`app/${web.path}`));
|
const list = await inspectTreeAsync(dir.path(`app/${web.path}`));
|
||||||
const walk = async (
|
const walk = async (
|
||||||
list: InspectTreeResult,
|
list: InspectTreeResult,
|
||||||
parent?: InspectTreeResult[],
|
parent?: InspectTreeResult[]
|
||||||
) => {
|
) => {
|
||||||
if (list.type === "dir") {
|
if (list.type === "dir") {
|
||||||
for (const item of list.children) {
|
for (const item of list.children) {
|
||||||
await walk(item, [...(parent || []), list]);
|
await walk(item, [...(parent || []), list]);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
const path = join(...(parent || []).map((e) => e.name), list.name);
|
const path = join(...(parent || []).map((e) => e.name), list.name);
|
||||||
const file = Bun.file(dir.path(`app/${path}`));
|
const file = Bun.file(dir.path(`app/${path}`));
|
||||||
if (await file.exists()) {
|
if (await file.exists()) {
|
||||||
cache.static[path.substring(web.path.length)] = {
|
cache.static[path.substring(web.path.length)] = {
|
||||||
type: mime.getType(path) || "application/octet-stream",
|
type: mime.getType(path) || "application/octet-stream",
|
||||||
compression: g.mode === "prod" ? "br" : "",
|
compression: g.mode === "prod" ? "br" : "",
|
||||||
content: await file.arrayBuffer(),
|
content: await file.arrayBuffer(),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
if (list) {
|
if (list) {
|
||||||
await walk(list);
|
await walk(list);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (g.mode === "dev") {
|
if (g.mode === "dev") {
|
||||||
watch(dir.path(`app/static`), async (_, filename) => {
|
watch(dir.path(`app/static`), async (_, filename) => {
|
||||||
if (filename) {
|
if (filename) {
|
||||||
const path = join("static", filename);
|
const path = join("static", filename);
|
||||||
const file = Bun.file(dir.path(`app/${path}`));
|
const file = Bun.file(dir.path(`app/${path}`));
|
||||||
if (await file.exists()) {
|
if (await file.exists()) {
|
||||||
cache.static[`/${filename}`] = {
|
cache.static[`/${filename}`] = {
|
||||||
type: mime.getType(path) || "application/octet-stream",
|
type: mime.getType(path) || "application/octet-stream",
|
||||||
compression: g.mode === "prod" ? "br" : "",
|
compression: g.mode === "prod" ? "br" : "",
|
||||||
content: await file.arrayBuffer(),
|
content: await file.arrayBuffer(),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
exists: (url: URL) => {
|
exists: (url: URL) => {
|
||||||
return !!cache.static[url.pathname];
|
return !!cache.static[url.pathname];
|
||||||
},
|
},
|
||||||
serve: (url: URL) => {
|
serve: (url: URL) => {
|
||||||
let file = cache.static[url.pathname];
|
let file = cache.static[url.pathname];
|
||||||
if (file) {
|
if (file) {
|
||||||
return new Response(file.content, {
|
return new Response(file.content, {
|
||||||
headers: {
|
headers: {
|
||||||
...{ "content-type": file.type },
|
...CORS_HEADERS,
|
||||||
...(file.compression ? { "content-encoding": file.compression } : {}),
|
...{ "content-type": file.type },
|
||||||
},
|
...(file.compression ? { "content-encoding": file.compression } : {}),
|
||||||
});
|
},
|
||||||
}
|
});
|
||||||
|
}
|
||||||
|
|
||||||
file = cache.static["/index.html"];
|
file = cache.static["/index.html"];
|
||||||
if (file) {
|
if (file) {
|
||||||
return new Response(file.content, {
|
return new Response(file.content, {
|
||||||
headers: {
|
headers: {
|
||||||
...{ "content-type": file.type },
|
...{ "content-type": file.type },
|
||||||
...(file.compression ? { "content-encoding": file.compression } : {}),
|
...(file.compression ? { "content-encoding": file.compression } : {}),
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue