seed the client cache

This commit is contained in:
Seth Trowbridge 2023-04-21 20:27:37 -04:00
parent 866eb9b26d
commit 26cb46923f
3 changed files with 35 additions and 14 deletions

1
.vscode/launch.json vendored
View File

@ -13,6 +13,7 @@
"runtimeExecutable": "C:\\Users\\Seth\\.deno\\bin\\deno.EXE", "runtimeExecutable": "C:\\Users\\Seth\\.deno\\bin\\deno.EXE",
"runtimeArgs": [ "runtimeArgs": [
"run", "run",
"--no-lock",
"--unstable", "--unstable",
"--inspect-wait", "--inspect-wait",
"--allow-all" "--allow-all"

View File

@ -160,11 +160,18 @@ export const Switch =({children}:{children:Children})=>
export const Case =({children, value}:{children:Children, value?:string, default?:true})=>null; export const Case =({children, value}:{children:Children, value?:string, default?:true})=>null;
export const useRouteVars =()=> React.useContext(SwitchContext).keys; export const useRouteVars =()=> React.useContext(SwitchContext).keys;
type FetchRecord = {URL:string, CacheFor:number, CachedAt:number, CacheOnServer:boolean, Promise?:Promise<FetchRecord>, DelaySSR:boolean, Error?:string, JSON?:object}; export type FetchRecord = {URL:string, CacheFor:number, CachedAt:number, CacheOnServer:boolean, Promise?:Promise<FetchRecord>, DelaySSR:boolean, Error?:string, JSON?:object};
export const Fetch = { export const Fetch = {
Cache:new Map() as Map<string, FetchRecord>, Cache:new Map() as Map<string, FetchRecord>,
SSR:false as false|Promise<FetchRecord>[], ServerBlocking:false as false|Promise<FetchRecord>[],
ServerTouched:new Set() as Set<FetchRecord>,
Seed(seed:FetchRecord[])
{
seed.forEach(r=>{
r.Promise = Promise.resolve(r);
Fetch.Cache.set(r.URL, r)
});
},
Request(URL:string, Init?:RequestInit, CacheFor:number = 60, CacheOnServer:boolean = true, DelaySSR:boolean = true) Request(URL:string, Init?:RequestInit, CacheFor:number = 60, CacheOnServer:boolean = true, DelaySSR:boolean = true)
{ {
let check = Fetch.Cache.get(URL); let check = Fetch.Cache.get(URL);
@ -213,12 +220,16 @@ export const Fetch = {
{ {
type FetchHookState = [Data:undefined|object, Updating:boolean]; type FetchHookState = [Data:undefined|object, Updating:boolean];
const [cacheGet, cacheSet] = React.useState([undefined, true] as FetchHookState); const [cacheGet, cacheSet] = React.useState([undefined, true] as FetchHookState);
if(Fetch.SSR && DelaySSR) if(Fetch.ServerBlocking && DelaySSR)
{ {
const receipt = Fetch.Request(URL, Init, CacheFor, CacheOnServer, DelaySSR); const receipt = Fetch.Request(URL, Init, CacheFor, CacheOnServer, DelaySSR);
if(receipt.CachedAt === 0 && receipt.Promise) if(receipt.CachedAt === 0 && receipt.Promise)
{ {
Fetch.SSR.push(receipt.Promise); Fetch.ServerBlocking.push(receipt.Promise);
}
else
{
Fetch.ServerTouched.add(receipt);
} }
return [receipt.JSON, receipt.CachedAt === 0]; return [receipt.JSON, receipt.CachedAt === 0];
} }

View File

@ -221,21 +221,29 @@ FileListen("${url.pathname}", reloadHandler);`;
} }
else else
{ {
let bake = ""; Iso.Fetch.ServerBlocking = [];
Iso.Fetch.SSR = []; let bake = SSR(<Iso.Router.Provider url={url}><App/></Iso.Router.Provider>);
bake = SSR(<Iso.Router.Provider url={url}><App/></Iso.Router.Provider>); while(Iso.Fetch.ServerBlocking.length)
while(Iso.Fetch.SSR.length)
{ {
await Promise.all(Iso.Fetch.SSR); await Promise.all(Iso.Fetch.ServerBlocking);
Iso.Fetch.SSR = []; Iso.Fetch.ServerBlocking = [];
bake = SSR(<Iso.Router.Provider url={url}><App/></Iso.Router.Provider>); bake = SSR(<Iso.Router.Provider url={url}><App/></Iso.Router.Provider>);
} }
const seed:Iso.FetchRecord[] = [];
Iso.Fetch.ServerTouched.forEach((record)=>{
const r:Iso.FetchRecord = {...record};
delete r.Promise;
seed.push(r);
});
Iso.Fetch.ServerTouched = new Set();
const results = Twind.extract(bake, TwindInst); const results = Twind.extract(bake, TwindInst);
type = `text/html`; type = `text/html`;
body = `<!doctype html> body =
`<!doctype html>
<html lang="en"> <html lang="en">
<head> <head>
<title>${Iso.Meta.title}</title> <title>${Iso.Meta.title}</title>
@ -250,8 +258,9 @@ FileListen("${url.pathname}", reloadHandler);`;
import {render, createElement as H} from "react"; import {render, createElement as H} from "react";
import * as Twind from "https://esm.sh/v115/@twind/core@1.1.3/es2022/core.mjs"; import * as Twind from "https://esm.sh/v115/@twind/core@1.1.3/es2022/core.mjs";
import {default as App, CSS} from "@eno/app"; import {default as App, CSS} from "@eno/app";
import {Router} from "@eno/iso"; import {Router, Fetch} from "@eno/iso";
Twind.install(CSS); Twind.install(CSS);
Fetch.Seed(${JSON.stringify(seed)});
render( H(Router.Provider, null, H(App)), document.querySelector("#app")); render( H(Router.Provider, null, H(App)), document.querySelector("#app"));
</script> </script>
</body> </body>