checkpoint
This commit is contained in:
parent
74ed45c8fd
commit
3e242c9e53
|
|
@ -1,5 +1,5 @@
|
||||||
import { useLocal } from "lib/utils/use-local";
|
import { useLocal } from "lib/utils/use-local";
|
||||||
import { FC } from "react";
|
import { FC, useEffect } from "react";
|
||||||
import { FieldLocal, FieldProp, FMLocal } from "../../typings";
|
import { FieldLocal, FieldProp, FMLocal } from "../../typings";
|
||||||
import { PropTypeInput } from "./TypeInput";
|
import { PropTypeInput } from "./TypeInput";
|
||||||
|
|
||||||
|
|
@ -15,6 +15,13 @@ export const FieldOTP: FC<{
|
||||||
ref: [] as HTMLInputElement[],
|
ref: [] as HTMLInputElement[],
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// useEffect(() => {
|
||||||
|
// if (typeof fm.data[field.name] === "string") {
|
||||||
|
// local.otp = fm.data[field.name].split("");
|
||||||
|
// local.render();
|
||||||
|
// }
|
||||||
|
// }, [fm.data[field.name]]);
|
||||||
|
|
||||||
if (local.otp.length === 0 && digit) {
|
if (local.otp.length === 0 && digit) {
|
||||||
for (let i = 0; i < digit; i++) {
|
for (let i = 0; i < digit; i++) {
|
||||||
local.otp.push("");
|
local.otp.push("");
|
||||||
|
|
@ -74,10 +81,8 @@ export const FieldOTP: FC<{
|
||||||
}
|
}
|
||||||
|
|
||||||
const otp = local.otp.join("");
|
const otp = local.otp.join("");
|
||||||
if (otp.length === digit) {
|
fm.data[field.name] = otp;
|
||||||
fm.data[field.name] = otp;
|
fm.render();
|
||||||
fm.render();
|
|
||||||
}
|
|
||||||
local.render();
|
local.render();
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
import { EsensiSession } from "app/server/session";
|
||||||
import day from "dayjs";
|
import day from "dayjs";
|
||||||
|
|
||||||
const w = window as any;
|
const w = window as any;
|
||||||
|
|
@ -8,7 +9,7 @@ export type RG = {
|
||||||
};
|
};
|
||||||
|
|
||||||
export type UserSession = {
|
export type UserSession = {
|
||||||
data: any;
|
data: EsensiSession;
|
||||||
expired: Date; // second
|
expired: Date; // second
|
||||||
};
|
};
|
||||||
export const registerSession = (session: RG) => {
|
export const registerSession = (session: RG) => {
|
||||||
|
|
|
||||||
|
|
@ -7,8 +7,9 @@ import { FieldLoading } from "lib/comps/ui/field-loading";
|
||||||
|
|
||||||
const w = window as any;
|
const w = window as any;
|
||||||
const initResponsive = function () {
|
const initResponsive = function () {
|
||||||
const mode = localStorage.getItem("prasi-editor-mode");
|
let mode = "desktop";
|
||||||
if (isEditor) {
|
if (isEditor) {
|
||||||
|
const mode = localStorage.getItem("prasi-editor-mode");
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
if (mode === "mobile") {
|
if (mode === "mobile") {
|
||||||
w.isMobile = true;
|
w.isMobile = true;
|
||||||
|
|
|
||||||
|
|
@ -4,8 +4,8 @@ import { ServerContext, SessionContext } from "../session/type";
|
||||||
|
|
||||||
type RouteFn = (...arg: any[]) => Promise<any>;
|
type RouteFn = (...arg: any[]) => Promise<any>;
|
||||||
|
|
||||||
type SingleRoute = [string, () => Promise<{ default: RouteFn }>];
|
export type SingleRoute = [string, () => Promise<{ default: RouteFn }>];
|
||||||
type SingleRouteWithOption = [
|
export type SingleRouteWithOption = [
|
||||||
string,
|
string,
|
||||||
() => Promise<{ default: RouteFn }>,
|
() => Promise<{ default: RouteFn }>,
|
||||||
RouteOption
|
RouteOption
|
||||||
|
|
@ -22,6 +22,10 @@ export const newServerRouter = <
|
||||||
return arg;
|
return arg;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const prasiApi = <T extends (...arg: any[]) => any>(fn: T) => {
|
||||||
|
return fn as (...arg: Parameters<T>) => ReturnType<T>;
|
||||||
|
};
|
||||||
|
|
||||||
export const newClientRouter = <T extends ReturnType<typeof newServerRouter>>(
|
export const newClientRouter = <T extends ReturnType<typeof newServerRouter>>(
|
||||||
...routers: T[]
|
...routers: T[]
|
||||||
) => {
|
) => {
|
||||||
|
|
@ -33,6 +37,7 @@ export const newClientRouter = <T extends ReturnType<typeof newServerRouter>>(
|
||||||
for (const router of routers) {
|
for (const router of routers) {
|
||||||
if (router[api_name as any]) {
|
if (router[api_name as any]) {
|
||||||
const [url, _, opt] = router[api_name as any];
|
const [url, _, opt] = router[api_name as any];
|
||||||
|
|
||||||
if (opt && opt.response_as)
|
if (opt && opt.response_as)
|
||||||
return _post(url, args, { response_as: opt.response_as });
|
return _post(url, args, { response_as: opt.response_as });
|
||||||
|
|
||||||
|
|
@ -84,7 +89,11 @@ export const useServerRouter = <T extends ReturnType<typeof newServerRouter>>(
|
||||||
try {
|
try {
|
||||||
params = await req.json();
|
params = await req.json();
|
||||||
} catch (e) {}
|
} catch (e) {}
|
||||||
result = await route.handler.default.bind(arg)(params);
|
if (Array.isArray(params)) {
|
||||||
|
result = await route.handler.default.bind(arg)(...params);
|
||||||
|
} else {
|
||||||
|
result = await route.handler.default.bind(arg)(params);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (typeof result === "object" && result instanceof Response) {
|
if (typeof result === "object" && result instanceof Response) {
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,104 @@
|
||||||
|
import { LoginResult } from "app/server/router/login";
|
||||||
|
import {
|
||||||
|
newClientRouter,
|
||||||
|
SingleRoute,
|
||||||
|
SingleRouteWithOption,
|
||||||
|
} from "../server/server-route";
|
||||||
|
import { ClientSession, SessionAuth } from "./type";
|
||||||
|
|
||||||
|
export const newClientSession = <T>(arg: {
|
||||||
|
tracker?: { enabled?: boolean };
|
||||||
|
route: {
|
||||||
|
login: SingleRoute | SingleRouteWithOption;
|
||||||
|
};
|
||||||
|
on: {
|
||||||
|
save: (data: T) => Promise<void>;
|
||||||
|
load: () => Promise<T | null>;
|
||||||
|
clear: () => Promise<void>;
|
||||||
|
messageReceived?: (session: ClientSession<T>) => Promise<void>;
|
||||||
|
afterLogin: (arg: LoginResult, session: ClientSession<T>) => Promise<void>;
|
||||||
|
afterLogout?: (session: ClientSession<T>) => Promise<void>;
|
||||||
|
afterInit: (session: ClientSession<T>) => Promise<void>;
|
||||||
|
};
|
||||||
|
}) => {
|
||||||
|
const router = { login: arg.route.login };
|
||||||
|
const client = newClientRouter(router);
|
||||||
|
|
||||||
|
const login_promise = { resolve: null as any, reject: null as any };
|
||||||
|
const logout_promise = { resolve: null as any, reject: null as any };
|
||||||
|
|
||||||
|
const session: ClientSession<T> = {
|
||||||
|
status: "checking",
|
||||||
|
current: null,
|
||||||
|
connected: false,
|
||||||
|
save: arg.on.save,
|
||||||
|
load: arg.on.load,
|
||||||
|
clear: arg.on.clear,
|
||||||
|
async init() {
|
||||||
|
arg.on.afterInit(session);
|
||||||
|
|
||||||
|
return { status: this.status };
|
||||||
|
},
|
||||||
|
login(auth: SessionAuth) {
|
||||||
|
return new Promise<T>(async (resolve, reject) => {
|
||||||
|
if (isEditor) {
|
||||||
|
resolve({} as any);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
login_promise.resolve = resolve;
|
||||||
|
login_promise.reject = reject;
|
||||||
|
if (this.status === "checking") {
|
||||||
|
await new Promise<void>((done) => {
|
||||||
|
const ival = setInterval(() => {
|
||||||
|
if (this.status !== "checking") {
|
||||||
|
clearInterval(ival);
|
||||||
|
done();
|
||||||
|
}
|
||||||
|
}, 100);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.status !== "active") {
|
||||||
|
const result: LoginResult = await client.login(auth);
|
||||||
|
arg.on.afterLogin(result, session);
|
||||||
|
} else {
|
||||||
|
console.error(
|
||||||
|
`\
|
||||||
|
Session login failed, current status is: ${this.status}.
|
||||||
|
Login is prevented, please logout first before re-login!`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.current) {
|
||||||
|
resolve(this.current);
|
||||||
|
} else {
|
||||||
|
if (auth) {
|
||||||
|
} else {
|
||||||
|
reject("Current session not found");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
logout() {
|
||||||
|
return new Promise<void>(async (resolve, reject) => {
|
||||||
|
if (isEditor) {
|
||||||
|
resolve({} as any);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
logout_promise.resolve = resolve;
|
||||||
|
logout_promise.reject = reject;
|
||||||
|
|
||||||
|
if (arg.on.afterLogout) {
|
||||||
|
arg.on.afterLogout(session);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
if (!isEditor) {
|
||||||
|
session.init();
|
||||||
|
}
|
||||||
|
return session;
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,56 @@
|
||||||
|
/// <reference types="bun-types" />
|
||||||
|
|
||||||
|
import { ServerWebSocket } from "bun";
|
||||||
|
import { useServerRouter } from "../server/server-route";
|
||||||
|
import { newSessionStore } from "./store/session-store";
|
||||||
|
import { ServerContext } from "./type";
|
||||||
|
|
||||||
|
type WS = ServerWebSocket<{ url: string }>;
|
||||||
|
type SessionServerHandler = {
|
||||||
|
cleanup: () => Promise<void>;
|
||||||
|
handle: (arg: ServerContext) => Promise<Response>;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const initSessionServer = <T>(
|
||||||
|
server: PrasiServer,
|
||||||
|
arg: {
|
||||||
|
encrypt?: boolean;
|
||||||
|
router: ReturnType<typeof useServerRouter>;
|
||||||
|
}
|
||||||
|
) => {
|
||||||
|
try {
|
||||||
|
const session_store = newSessionStore<T>(server.site_id);
|
||||||
|
const session_router = arg.router;
|
||||||
|
const server_handler: SessionServerHandler = {
|
||||||
|
async cleanup() {},
|
||||||
|
|
||||||
|
async handle(server_arg) {
|
||||||
|
const { req, handle, url } = server_arg;
|
||||||
|
|
||||||
|
const route_arg = {
|
||||||
|
...server_arg,
|
||||||
|
session: {
|
||||||
|
...session_store,
|
||||||
|
current: undefined,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
if (url.pathname.startsWith("/_session/")) {
|
||||||
|
const res = await session_router.handle(route_arg);
|
||||||
|
if (res) return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (arg.router) {
|
||||||
|
const res = await arg.router.handle(route_arg);
|
||||||
|
if (res) return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
return handle(req);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
server.session = server_handler;
|
||||||
|
} catch (e) {
|
||||||
|
console.log(e);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
@ -1,3 +1,5 @@
|
||||||
|
import { Server } from "bun";
|
||||||
|
|
||||||
export interface NewSessionData<T> {
|
export interface NewSessionData<T> {
|
||||||
uid: string;
|
uid: string;
|
||||||
role: string;
|
role: string;
|
||||||
|
|
@ -52,12 +54,14 @@ export type ClientSessionStatus =
|
||||||
| "logout";
|
| "logout";
|
||||||
export type ClientSession<T> = {
|
export type ClientSession<T> = {
|
||||||
status: ClientSessionStatus;
|
status: ClientSessionStatus;
|
||||||
current: null | SessionData<T>;
|
current: null | T;
|
||||||
init(): Promise<{ status: ClientSessionStatus }>;
|
init(): Promise<{ status: ClientSessionStatus }>;
|
||||||
connect(auth?: SessionAuth): Promise<void>;
|
|
||||||
connected: boolean;
|
connected: boolean;
|
||||||
login(auth: SessionAuth): Promise<SessionData<T>>;
|
login(auth: SessionAuth): Promise<T>;
|
||||||
logout(): Promise<void>;
|
logout(): Promise<void>;
|
||||||
|
save(data: T): Promise<void>;
|
||||||
|
load(): Promise<T | null>;
|
||||||
|
clear(): Promise<void>;
|
||||||
};
|
};
|
||||||
|
|
||||||
export interface SessionContext<T> extends ServerContext {
|
export interface SessionContext<T> extends ServerContext {
|
||||||
|
|
@ -66,6 +70,7 @@ export interface SessionContext<T> extends ServerContext {
|
||||||
|
|
||||||
export type ServerContext = {
|
export type ServerContext = {
|
||||||
req: Request;
|
req: Request;
|
||||||
|
server: Server;
|
||||||
handle: (req: Request) => Promise<Response>;
|
handle: (req: Request) => Promise<Response>;
|
||||||
mode: "dev" | "prod";
|
mode: "dev" | "prod";
|
||||||
url: {
|
url: {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue