This commit is contained in:
Rizky 2023-12-16 15:20:10 +07:00
parent 7015599cd5
commit 8cffe6fa69
5 changed files with 204 additions and 3 deletions

View File

@ -1,10 +1,16 @@
import init from "wasm-gzip";
import { jscript } from "../../../utils/script/jscript";
import { dbClient } from "../../vi/load/db/client-db";
import { PG } from "./ed-global";
let w = window as unknown as { db: ReturnType<typeof dbClient> };
export const edInit = async (p: PG) => {
p.status = "ready";
const cur = new URL(location.href);
w.db = dbClient("prasi", `${cur.protocol}//${cur.host}`);
await init();
jscript.init(p.render);

View File

@ -0,0 +1,111 @@
import hash_sum from "hash-sum";
import { fetchViaProxy } from "../proxy";
export const dbClient = (name: string, dburl: string) => {
return new Proxy(
{},
{
get(_, table: string) {
if (table === "_tables") {
return () => {
return fetchSendDb(
name,
{
name,
action: "definition",
table: "*",
},
dburl
);
};
}
if (table === "_definition") {
return (table: string) => {
return fetchSendDb(
name,
{
name,
action: "definition",
table,
},
dburl
);
};
}
if (table.startsWith("$")) {
return (...params: any[]) => {
return fetchSendDb(
name,
{
name,
action: "query",
table,
params,
},
dburl
);
};
}
return new Proxy(
{},
{
get(_, action: string) {
return (...params: any[]) => {
if (table === "query") {
table = action;
action = "query";
}
return fetchSendDb(
name,
{
name,
action,
table,
params,
},
dburl
);
};
},
}
);
},
}
);
};
const cachedQueryResult: Record<
string,
{ timestamp: number; result: any; promise: Promise<any> }
> = {};
export const fetchSendDb = async (name: string, params: any, dburl: string) => {
const base = new URL(dburl);
base.pathname = `/_dbs/${name}`;
if (params.table) {
base.pathname += `/${params.table}`;
}
const url = base.toString();
const hsum = hash_sum(params);
const cached = cachedQueryResult[hsum];
if (!cached || (cached && Date.now() - cached.timestamp > 1000)) {
cachedQueryResult[hsum] = {
timestamp: Date.now(),
promise: fetchViaProxy(url, params, {
"content-type": "application/json",
}),
result: null,
};
const result = await cachedQueryResult[hsum].promise;
cachedQueryResult[hsum].result = result;
return result;
}
return await cached.promise;
};

View File

@ -1,5 +1,5 @@
import importModule from "../../../render/editor/tools/dynamic-import";
import { createAPI, createDB, initApi } from "../../../utils/script/init-api";
import { initApi } from "../../../utils/script/init-api";
export const viLoadLegacy = async (vi: {
site: {
@ -43,10 +43,8 @@ export const viLoadLegacy = async (vi: {
const path = `/npm/site/${vi.site.id}/site.js`;
await importModule(path);
if (!vi.site.db.get()) {
vi.site.db.set(createDB(api_url));
}
if (!vi.site.api.get()) {
vi.site.api.set(createAPI(api_url));
}
const w = window as any;

View File

@ -0,0 +1,68 @@
(BigInt.prototype as any).toJSON = function (): string {
return `BigInt::` + this.toString();
};
let w = window;
export const fetchViaProxy = async (
url: string,
data?: any,
_headers?: any
) => {
const headers = { ..._headers };
let body = data;
let isFile = false;
const formatSingle = async (data: any) => {
if (!(data instanceof w.FormData || data instanceof w.File)) {
headers["content-type"] = "application/json";
} else {
if (data instanceof w.File) {
isFile = true;
let ab = await new Promise<ArrayBuffer | undefined>((resolve) => {
const reader = new FileReader();
reader.addEventListener("load", (e) => {
resolve(e.target?.result as ArrayBuffer);
});
reader.readAsArrayBuffer(data);
});
if (ab) {
data = new File([ab], data.name);
}
}
}
return data;
};
if (Array.isArray(data)) {
body = await Promise.all(data.map((e) => formatSingle(e)));
} else {
body = await formatSingle(data);
}
if (!isFile) {
body = JSON.stringify(body);
}
const cur = new URL(location.href);
const base = new URL(url);
if (cur.host === base.host) {
const res = await fetch(base.pathname, {
method: "POST",
body,
headers,
});
return res.json();
} else {
const res = await fetch(`/_proxy`, {
method: "POST",
body: JSON.stringify({
url,
body,
headers,
}),
headers: { "content-type": "application/json" },
});
return res.json();
}
};

18
pkgs/core/api/_proxy.ts Normal file
View File

@ -0,0 +1,18 @@
import { g } from "utils/global";
export const _ = {
url: "/_proxy/*",
async api(arg: {
url: string;
method: "POST" | "GET";
headers: any;
body: any;
}) {
const res = await fetch(arg.url, {
method: arg.method,
headers: arg.headers,
body: arg.body,
});
return res as any;
},
};