From 26cb46923fead330d205950a7b3ac06707c159e7 Mon Sep 17 00:00:00 2001 From: Seth Trowbridge Date: Fri, 21 Apr 2023 20:27:37 -0400 Subject: [PATCH] seed the client cache --- .vscode/launch.json | 1 + lib/iso.tsx | 21 ++++++++++++++++----- server.tsx | 27 ++++++++++++++++++--------- 3 files changed, 35 insertions(+), 14 deletions(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index 179eb6d..a0c25b9 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -13,6 +13,7 @@ "runtimeExecutable": "C:\\Users\\Seth\\.deno\\bin\\deno.EXE", "runtimeArgs": [ "run", + "--no-lock", "--unstable", "--inspect-wait", "--allow-all" diff --git a/lib/iso.tsx b/lib/iso.tsx index a9030bc..f6f07c8 100644 --- a/lib/iso.tsx +++ b/lib/iso.tsx @@ -160,11 +160,18 @@ export const Switch =({children}:{children:Children})=> export const Case =({children, value}:{children:Children, value?:string, default?:true})=>null; export const useRouteVars =()=> React.useContext(SwitchContext).keys; -type FetchRecord = {URL:string, CacheFor:number, CachedAt:number, CacheOnServer:boolean, Promise?:Promise, DelaySSR:boolean, Error?:string, JSON?:object}; - +export type FetchRecord = {URL:string, CacheFor:number, CachedAt:number, CacheOnServer:boolean, Promise?:Promise, DelaySSR:boolean, Error?:string, JSON?:object}; export const Fetch = { Cache:new Map() as Map, - SSR:false as false|Promise[], + ServerBlocking:false as false|Promise[], + ServerTouched:new Set() as Set, + 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) { let check = Fetch.Cache.get(URL); @@ -213,12 +220,16 @@ export const Fetch = { { type FetchHookState = [Data:undefined|object, Updating:boolean]; 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); 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]; } diff --git a/server.tsx b/server.tsx index 986c043..68465b7 100644 --- a/server.tsx +++ b/server.tsx @@ -221,21 +221,29 @@ FileListen("${url.pathname}", reloadHandler);`; } else { - let bake = ""; - Iso.Fetch.SSR = []; - bake = SSR(); - - while(Iso.Fetch.SSR.length) + Iso.Fetch.ServerBlocking = []; + let bake = SSR(); + while(Iso.Fetch.ServerBlocking.length) { - await Promise.all(Iso.Fetch.SSR); - Iso.Fetch.SSR = []; + await Promise.all(Iso.Fetch.ServerBlocking); + Iso.Fetch.ServerBlocking = []; bake = SSR(); } + 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); type = `text/html`; - body = ` + body = +` ${Iso.Meta.title} @@ -250,8 +258,9 @@ FileListen("${url.pathname}", reloadHandler);`; import {render, createElement as H} from "react"; 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 {Router} from "@eno/iso"; + import {Router, Fetch} from "@eno/iso"; Twind.install(CSS); + Fetch.Seed(${JSON.stringify(seed)}); render( H(Router.Provider, null, H(App)), document.querySelector("#app"));