wip fix time
This commit is contained in:
parent
1d6ed73f2b
commit
b52975ebfd
|
|
@ -13,21 +13,22 @@ export const SyncActionDefinition = {
|
|||
},
|
||||
"page": {
|
||||
"list": "8",
|
||||
"load": "9"
|
||||
"load": "9",
|
||||
"cache": "10"
|
||||
},
|
||||
"yjs": {
|
||||
"um": "10",
|
||||
"sv_local": "11",
|
||||
"diff_local": "12",
|
||||
"sv_remote": "13"
|
||||
"um": "11",
|
||||
"sv_local": "12",
|
||||
"diff_local": "13",
|
||||
"sv_remote": "14"
|
||||
},
|
||||
"client": {
|
||||
"info": "14"
|
||||
"info": "15"
|
||||
},
|
||||
"code": {
|
||||
"load": "15",
|
||||
"edit": "16",
|
||||
"parse": "17"
|
||||
"load": "16",
|
||||
"edit": "17",
|
||||
"parse": "18"
|
||||
}
|
||||
};
|
||||
export const SyncActionPaths = {
|
||||
|
|
@ -41,12 +42,13 @@ export const SyncActionPaths = {
|
|||
"7": "comp.load",
|
||||
"8": "page.list",
|
||||
"9": "page.load",
|
||||
"10": "yjs.um",
|
||||
"11": "yjs.sv_local",
|
||||
"12": "yjs.diff_local",
|
||||
"13": "yjs.sv_remote",
|
||||
"14": "client.info",
|
||||
"15": "code.load",
|
||||
"16": "code.edit",
|
||||
"17": "code.parse"
|
||||
"10": "page.cache",
|
||||
"11": "yjs.um",
|
||||
"12": "yjs.sv_local",
|
||||
"13": "yjs.diff_local",
|
||||
"14": "yjs.sv_remote",
|
||||
"15": "client.info",
|
||||
"16": "code.load",
|
||||
"17": "code.edit",
|
||||
"18": "code.parse"
|
||||
};
|
||||
|
|
|
|||
|
|
@ -52,6 +52,8 @@ export const SyncActions = {
|
|||
list: async (id_site: string) =>
|
||||
({}) as Record<string, Exclude<page, "content_tree">>,
|
||||
load: async (id: string) => ({}) as EPage | void,
|
||||
cache: async (site_id: string, urls: string[], exclude_page_id: string[]) =>
|
||||
({}) as { gzip: Uint8Array } | null,
|
||||
},
|
||||
yjs: {
|
||||
um: async (
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ export * from "./comp_group";
|
|||
export * from "./comp_load";
|
||||
export * from "./page_list";
|
||||
export * from "./page_load";
|
||||
export * from "./page_cache";
|
||||
export * from "./yjs_um";
|
||||
export * from "./yjs_sv_local";
|
||||
export * from "./yjs_diff_local";
|
||||
|
|
|
|||
|
|
@ -0,0 +1,58 @@
|
|||
import { RadixRouter, createRouter } from "radix3";
|
||||
import { SAction } from "../actions";
|
||||
import { SyncConnection } from "../type";
|
||||
import { gzipAsync } from "../entity/zlib";
|
||||
|
||||
const cache = {} as Record<
|
||||
string,
|
||||
{ ts: number; router: RadixRouter<{ url: string; id: string }> }
|
||||
>;
|
||||
|
||||
const encoder = new TextEncoder();
|
||||
export const page_cache: SAction["page"]["cache"] = async function (
|
||||
this: SyncConnection,
|
||||
site_id,
|
||||
urls,
|
||||
exclude_page_id
|
||||
) {
|
||||
let result = null as unknown as Awaited<ReturnType<SAction["page"]["cache"]>>;
|
||||
|
||||
if (
|
||||
!cache[site_id] ||
|
||||
(cache[site_id] && Date.now() - cache[site_id].ts > 5000)
|
||||
) {
|
||||
const pages = await db.page.findMany({
|
||||
where: { id_site: site_id, is_deleted: false },
|
||||
select: { id: true, url: true },
|
||||
});
|
||||
const router = createRouter<{ url: string; id: string }>();
|
||||
for (const page of pages) {
|
||||
router.insert(page.url, page);
|
||||
}
|
||||
cache[site_id] = {
|
||||
router,
|
||||
ts: Date.now(),
|
||||
};
|
||||
}
|
||||
|
||||
const router = cache[site_id]?.router;
|
||||
if (router) {
|
||||
const result: Record<string, any> = {};
|
||||
for (const url of urls) {
|
||||
const found = router.lookup(url);
|
||||
if (found && !exclude_page_id.includes(found.id)) {
|
||||
const row = await db.page.findFirst({
|
||||
where: { id: found.id },
|
||||
select: { content_tree: true },
|
||||
});
|
||||
if (row) {
|
||||
result[found.id] = row.content_tree;
|
||||
}
|
||||
}
|
||||
}
|
||||
const gzip = await gzipAsync(encoder.encode(JSON.stringify(result)));
|
||||
return { gzip };
|
||||
}
|
||||
|
||||
return null;
|
||||
};
|
||||
|
|
@ -25,7 +25,7 @@ export const loadApiProxyDef = async (_url: string, with_types: boolean) => {
|
|||
|
||||
const ts = localStorage.getItem("api-ts-" + url);
|
||||
|
||||
if (with_types) {
|
||||
if (with_types) {
|
||||
script.src = `${base}/_prasi/load.js?url=${url}&v3&dev=1&ts=${ts}`;
|
||||
} else {
|
||||
script.src = `${base}/_prasi/load.js?url=${url}&v3&ts=${ts}`;
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import { SAction } from "../../../../../srv/ws/sync/actions";
|
|||
import { parseJs } from "../../../../../srv/ws/sync/editor/parser/parse-js";
|
||||
import { clientStartSync } from "../../../utils/sync/ws-client";
|
||||
import { IItem } from "../../../utils/types/item";
|
||||
import { DCode, DComp, DPage } from "../../../utils/types/root";
|
||||
import { DCode, DComp, DPage, IRoot } from "../../../utils/types/root";
|
||||
import { GenMetaP, IMeta as LogicMeta } from "../../vi/utils/types";
|
||||
|
||||
export type IMeta = LogicMeta;
|
||||
|
|
@ -147,6 +147,12 @@ export const EDGlobal = {
|
|||
| "page-not-found"
|
||||
| "ready",
|
||||
preview: {
|
||||
url_cache: new Set<string>(),
|
||||
page_cache: {} as Record<string, IRoot>,
|
||||
meta_cache: {} as Record<
|
||||
string,
|
||||
{ entry: string[]; meta: Record<string, IMeta> }
|
||||
>,
|
||||
show_loading: false,
|
||||
},
|
||||
sync: null as unknown as Awaited<ReturnType<typeof clientStartSync>>,
|
||||
|
|
|
|||
|
|
@ -1,10 +1,32 @@
|
|||
import { createId } from "@paralleldrive/cuid2";
|
||||
import { IContent } from "../../../../utils/types/general";
|
||||
import { IItem, MItem } from "../../../../utils/types/item";
|
||||
import { genMeta } from "../../../vi/meta/meta";
|
||||
import { IMeta, PG, active } from "../ed-global";
|
||||
import { assignMitem } from "./assign-mitem";
|
||||
import { pushTreeNode } from "./build/push-tree";
|
||||
|
||||
export const treeCacheBuild = async (p: PG, page_id: string) => {
|
||||
const root = p.preview.page_cache[page_id];
|
||||
|
||||
const meta_cache = {
|
||||
meta: {} as Record<string, IMeta>,
|
||||
entry: [] as string[],
|
||||
};
|
||||
for (const item of root.childs) {
|
||||
meta_cache.entry.push(item.id);
|
||||
genMeta(
|
||||
{
|
||||
note: "tree-rebuild",
|
||||
comps: p.comp.loaded,
|
||||
meta: meta_cache.meta,
|
||||
mode: "page",
|
||||
},
|
||||
{ item: item as IContent }
|
||||
);
|
||||
}
|
||||
p.preview.meta_cache[page_id] = meta_cache;
|
||||
};
|
||||
|
||||
export const treeRebuild = async (p: PG, arg?: { note?: string }) => {
|
||||
if (document.activeElement) {
|
||||
const a = document.activeElement;
|
||||
|
|
|
|||
|
|
@ -4,9 +4,12 @@ import { EDGlobal, PG, active } from "../ed/logic/ed-global";
|
|||
import { reloadPage } from "../ed/logic/ed-route";
|
||||
import { loadSite } from "../ed/logic/ed-site";
|
||||
import { Vi } from "./vi";
|
||||
import init from "wasm-gzip";
|
||||
import init, { decompress } from "wasm-gzip";
|
||||
import { w } from "../../utils/types/general";
|
||||
import { IRoot } from "../../utils/types/root";
|
||||
import { treeCacheBuild } from "../ed/logic/tree/build";
|
||||
|
||||
const decoder = new TextDecoder();
|
||||
export const ViPreview = (arg: { pathname: string }) => {
|
||||
const p = useGlobal(EDGlobal, "EDITOR");
|
||||
|
||||
|
|
@ -49,6 +52,13 @@ export const ViPreview = (arg: { pathname: string }) => {
|
|||
|
||||
const mode = p.mode;
|
||||
|
||||
if (!w.isEditor) {
|
||||
p.preview.meta_cache[params.page_id] = {
|
||||
meta: p.page.meta,
|
||||
entry: p.page.entry,
|
||||
};
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={cx("relative flex flex-1 items-center justify-center")}>
|
||||
<div
|
||||
|
|
@ -91,6 +101,36 @@ export const ViPreview = (arg: { pathname: string }) => {
|
|||
db={p.script.db}
|
||||
render_stat="disabled"
|
||||
script={{ init_local_effect: p.script.init_local_effect }}
|
||||
on_nav_loaded={async ({ urls }) => {
|
||||
const load_urls: string[] = [];
|
||||
if (p.preview.url_cache) {
|
||||
for (const url of urls) {
|
||||
if (!p.preview.url_cache.has(url)) {
|
||||
load_urls.push(url);
|
||||
p.preview.url_cache.add(url);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (load_urls.length > 0) {
|
||||
console.log(load_urls);
|
||||
const res = await p.sync.page.cache(
|
||||
p.site.id,
|
||||
load_urls,
|
||||
Object.keys(p.preview.page_cache)
|
||||
);
|
||||
if (res) {
|
||||
const pages = JSON.parse(
|
||||
decoder.decode(decompress(res.gzip)) || "{}"
|
||||
);
|
||||
|
||||
for (const [id, page] of Object.entries(pages)) {
|
||||
p.preview.page_cache[id] = page as IRoot;
|
||||
treeCacheBuild(p, params.page_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -130,6 +170,23 @@ const viRoute = async (p: PG) => {
|
|||
}
|
||||
|
||||
p.script.init_local_effect = {};
|
||||
|
||||
if (!w.isEditor) {
|
||||
const page_cache = p.preview.meta_cache[params.page_id];
|
||||
|
||||
if (page_cache) {
|
||||
p.page.meta = page_cache.meta;
|
||||
p.page.entry = page_cache.entry;
|
||||
|
||||
if (p.page.cur.id !== params.page_id) {
|
||||
p.page.cur = { id: params.page_id } as any;
|
||||
}
|
||||
p.status = "ready";
|
||||
p.render();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
await reloadPage(p, params.page_id, "load-route");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
import { IItem } from "../../../utils/types/item";
|
||||
import { IMeta } from "../../ed/logic/ed-global";
|
||||
import { viParts } from "./parts";
|
||||
|
||||
|
|
@ -25,6 +24,13 @@ export const ViGlobal = {
|
|||
| undefined
|
||||
| ((meta: IMeta, parts: ReturnType<typeof viParts>) => void),
|
||||
on_status_changes: undefined as void | ((status: ViStatus) => void),
|
||||
page: {
|
||||
cur: { id: "" },
|
||||
navs: {} as Record<string, Set<string>>,
|
||||
},
|
||||
on_nav_loaded: undefined as
|
||||
| undefined
|
||||
| ((arg: { urls: string[] }) => Promise<void>),
|
||||
};
|
||||
|
||||
export type VG = typeof ViGlobal & { render: () => void };
|
||||
|
|
|
|||
|
|
@ -3,9 +3,16 @@ import { VG } from "../global";
|
|||
import { ViRender } from "../render";
|
||||
import { viScriptArg } from "./arg";
|
||||
import { replaceWithObject, replacement } from "./eval-script";
|
||||
import { extractNavigate } from "./extract-nav";
|
||||
|
||||
export const viEvalProps = (
|
||||
vi: { meta: VG["meta"]; site: { db: any; api: any } },
|
||||
vi: {
|
||||
mode: VG["mode"];
|
||||
meta: VG["meta"];
|
||||
site: { db: any; api: any };
|
||||
page: VG["page"];
|
||||
on_nav_loaded?: VG["on_nav_loaded"];
|
||||
},
|
||||
meta: IMeta,
|
||||
passprop: any
|
||||
) => {
|
||||
|
|
@ -85,6 +92,10 @@ export const viEvalProps = (
|
|||
continue;
|
||||
}
|
||||
|
||||
if (prop.value) {
|
||||
extractNavigate(vi, prop.value);
|
||||
}
|
||||
|
||||
const js = prop.valueBuilt || "";
|
||||
const src = replaceWithObject(js, replacement) || "";
|
||||
const fn = new Function(
|
||||
|
|
|
|||
|
|
@ -8,13 +8,18 @@ import { viScriptArg } from "./arg";
|
|||
import { updatePropScope } from "./eval-prop";
|
||||
import { createViLocal } from "./local";
|
||||
import { createViPassProp } from "./passprop";
|
||||
import { extractNavigate } from "./extract-nav";
|
||||
import { w } from "../../../../utils/types/general";
|
||||
|
||||
export const viEvalScript = (
|
||||
vi: {
|
||||
page: VG["page"];
|
||||
mode: VG["mode"];
|
||||
site: { db: any; api: any };
|
||||
meta: VG["meta"];
|
||||
visit?: VG["visit"];
|
||||
script?: { init_local_effect: any };
|
||||
on_nav_loaded?: VG["on_nav_loaded"];
|
||||
},
|
||||
meta: IMeta,
|
||||
passprop: any
|
||||
|
|
@ -66,6 +71,10 @@ export const viEvalScript = (
|
|||
}
|
||||
}
|
||||
|
||||
if (!w.isEditor && meta.item.adv?.js) {
|
||||
extractNavigate(vi, meta.item.adv.js);
|
||||
}
|
||||
|
||||
const js = meta.item.adv?.jsBuilt || "";
|
||||
const src = replaceWithObject(js, replacement) || "";
|
||||
const fn = new Function(
|
||||
|
|
|
|||
|
|
@ -0,0 +1,58 @@
|
|||
import { VG } from "../global";
|
||||
|
||||
const nav = { timeout: null as any };
|
||||
|
||||
export const extractNavigate = (
|
||||
vi: { page: VG["page"]; on_nav_loaded?: VG["on_nav_loaded"] },
|
||||
str: string
|
||||
) => {
|
||||
const found_nav = [
|
||||
...findBetween(str, `navigate(`, `)`),
|
||||
...findBetween(str, `href = `, `;`),
|
||||
];
|
||||
|
||||
const page_id = vi.page.cur.id;
|
||||
if (!vi.page.navs[page_id]) {
|
||||
vi.page.navs[page_id] = new Set();
|
||||
}
|
||||
|
||||
for (const url of found_nav) {
|
||||
vi.page.navs[page_id].add(url);
|
||||
}
|
||||
|
||||
clearTimeout(nav.timeout);
|
||||
nav.timeout = setTimeout(() => {
|
||||
if (vi.on_nav_loaded) {
|
||||
vi.on_nav_loaded({
|
||||
urls: Array.from(vi.page.navs[page_id]),
|
||||
});
|
||||
}
|
||||
}, 100);
|
||||
};
|
||||
|
||||
const findBetween = (text: string, opener: string, closer: string) => {
|
||||
let i = 0;
|
||||
let last = 0;
|
||||
const founds: string[] = [];
|
||||
while (true) {
|
||||
const startIndex = text.indexOf(opener, i);
|
||||
last = i;
|
||||
if (startIndex >= 0) {
|
||||
const char = text[startIndex + opener.length];
|
||||
if (char === '"' || char === "'" || char === "`") {
|
||||
const end = text.indexOf(
|
||||
`${char}${closer}`,
|
||||
startIndex + opener.length + 1
|
||||
);
|
||||
const found = text.substring(startIndex + opener.length + 1, end);
|
||||
i = end + 2 + closer.length;
|
||||
founds.push(found);
|
||||
}
|
||||
}
|
||||
|
||||
if (last === i) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return founds;
|
||||
};
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
import { FC, Suspense, useState } from "react";
|
||||
import { FC, Suspense, useEffect, useState } from "react";
|
||||
import { useGlobal } from "web-utils";
|
||||
import { IMeta } from "../ed/logic/ed-global";
|
||||
import { viLoad } from "./load/load";
|
||||
|
|
@ -6,6 +6,7 @@ import { VG, ViGlobal } from "./render/global";
|
|||
import { ViRoot } from "./root";
|
||||
import { ErrorBox } from "./utils/error-box";
|
||||
import { render_stat } from "./render/render";
|
||||
import { IRoot } from "../../utils/types/root";
|
||||
|
||||
const w = window as any;
|
||||
export const Vi: FC<{
|
||||
|
|
@ -22,6 +23,7 @@ export const Vi: FC<{
|
|||
visit?: VG["visit"];
|
||||
render_stat?: "enabled" | "disabled";
|
||||
on_status_changed?: (status: VG["status"]) => void;
|
||||
on_nav_loaded?: (arg: { urls: string[] }) => Promise<void>;
|
||||
}> = ({
|
||||
meta,
|
||||
entry,
|
||||
|
|
@ -32,15 +34,18 @@ export const Vi: FC<{
|
|||
db,
|
||||
visit,
|
||||
script,
|
||||
page_id,
|
||||
render_stat: rs,
|
||||
on_status_changed,
|
||||
on_nav_loaded,
|
||||
}) => {
|
||||
const vi = useGlobal(ViGlobal, "VI");
|
||||
vi.mode = mode;
|
||||
vi.on_nav_loaded = on_nav_loaded;
|
||||
|
||||
w.isMobile = mode === "mobile";
|
||||
w.isDesktop = mode === "desktop";
|
||||
|
||||
vi.page.cur.id = page_id;
|
||||
vi.on_status_changes = on_status_changed;
|
||||
|
||||
if (rs === "disabled") {
|
||||
|
|
@ -61,6 +66,19 @@ export const Vi: FC<{
|
|||
viLoad(vi, { api_url, site_id });
|
||||
}
|
||||
|
||||
if (on_nav_loaded) {
|
||||
useEffect(() => {
|
||||
setTimeout(() => {
|
||||
const nav = vi.page.navs[vi.page.cur.id];
|
||||
if (nav) {
|
||||
on_nav_loaded({
|
||||
urls: Array.from(nav),
|
||||
});
|
||||
}
|
||||
}, 500);
|
||||
}, [vi.page.cur.id]);
|
||||
}
|
||||
|
||||
return (
|
||||
<ErrorBox>
|
||||
<Suspense>
|
||||
|
|
|
|||
Loading…
Reference in New Issue