issue/fetch #21

Merged
SethTrowbridge merged 9 commits from issue/fetch into master 2023-04-22 15:18:27 -04:00
3 changed files with 52 additions and 20 deletions
Showing only changes of commit 7847410f3e - Show all commits

View File

@ -4,14 +4,18 @@ import * as Iso from "@eno/iso";
export default ()=> export default ()=>
{ {
const [countGet, countSet] = React.useState(1); const [countGet, countSet] = React.useState(1);
const [routeGet, routeSet] = Iso.Router.Consumer(); const [routeGet, routeSet] = Iso.Router.Consumer();
type CatFact = {fact:string, length:number}|undefined;
const [Data, Updating] = Iso.Fetch.Use(`https://catfact.ninja/fact`);
return <div class="p-4 text-red-500"> return <div class="p-4 text-red-500">
<Iso.Metas title="Component!"/> <Iso.Metas title="Component!"/>
Route is: {routeGet.Path.toString()} Route is: {routeGet.Path.toString()}
<button className="p-4 bg-red-500 text-white" onClick={e=>{countSet(countGet+1); routeSet(["lol", "idk"], {count:countGet+1});}}>{countGet}</button> <button className="p-4 bg-red-500 text-white" onClick={e=>{countSet(countGet+1); routeSet(["lol", "idk"], {count:countGet+1});}}>{countGet}</button>
Component!!! Component!!!
<a href="/page/about-us" className="p-2 text(lg blue-500) font-bold">a link</a> <a href="/page/about-us" className="p-2 text(lg blue-500) font-bold">a link</a>
<p>Data:{Data && (Data as CatFact)?.fact}</p>
<p>Status:{Updating?'loading':'done'}</p>
</div>; </div>;
}; };

View File

@ -10,6 +10,15 @@ const delay =async(inHandler:()=>void, inDelay:number):Promise<void>=>
}); });
}; };
const cacheRecord = {Promise:delay(()=>{}, 1000)};
cacheRecord.Promise.then(()=>{console.log(`handler one`)});
cacheRecord.Promise.then(()=>{console.log(`handler two`)});
cacheRecord.Promise = delay(()=>{}, 3000);
/*
let r1, r2, r3; let r1, r2, r3;
delay(()=>{r1 = Fetch.Request(`https://catfact.ninja/fact`, undefined, 0.2); console.log(r1); }, 10); delay(()=>{r1 = Fetch.Request(`https://catfact.ninja/fact`, undefined, 0.2); console.log(r1); }, 10);
@ -21,4 +30,6 @@ await delay(()=>{}, 3000);
console.log(r1); console.log(r1);
console.log(r2); console.log(r2);
console.log(r3); console.log(r3);
*/

View File

@ -160,46 +160,44 @@ 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, Promise?:Promise<FetchRecord>, DelaySSR:boolean, Error?:string, JSON?:object};
type FetchRecord = {URL:string, CacheFor:number, CachedAt:number, DelaySSR:boolean, Error:boolean, Text:false|string};
export const Fetch = { export const Fetch = {
Cache:new Map() as Map<string, FetchRecord>, Cache:new Map() as Map<string, FetchRecord>,
async Request(URL:string, Init?:RequestInit, CacheFor:number = 60, DelaySSR:boolean = true) Request(URL:string, Init?:RequestInit, CacheFor:number = 60, DelaySSR:boolean = true)
{ {
let check = Fetch.Cache.get(URL); let check = Fetch.Cache.get(URL);
const load =async(inCheck:FetchRecord)=> const load =(inCheck:FetchRecord)=>
{ {
Fetch.Cache.set(URL, inCheck); Fetch.Cache.set(URL, inCheck);
const resp = await fetch(URL, Init); inCheck.CachedAt = 0;
inCheck.Text = await resp.text(); inCheck.Promise = fetch(URL, Init).then(resp=>resp.json()).then((json)=>{
inCheck.CachedAt = new Date().getTime(); inCheck.JSON = json;
console.log(`...cached!`); inCheck.CachedAt = new Date().getTime();
console.log(`...cached!`);
return inCheck;
});
return inCheck; return inCheck;
} }
if(!check) if(!check)
{ {
console.log(`making new cache record...`); console.log(`making new cache record...`);
check = {URL, CacheFor, CachedAt:0, DelaySSR, Error:false, Text:false}; return load({URL, CacheFor, CachedAt:0, DelaySSR});
load(check);
return check;
} }
if(check.CachedAt == 0) else if(check.CachedAt == 0)
{ {
console.log(`currently being cached...`); console.log(`currently being cached...`);
return check; return check;
} }
else if(check?.Text) else
{ {
console.log(`found in cache...`); console.log(`found in cache...`);
let secondsAge = Math.floor((new Date().getTime() - check.CachedAt)/1000); let secondsAge = (new Date().getTime() - check.CachedAt)/1000;
if(secondsAge > check.CacheFor) if(secondsAge > check.CacheFor)
{ {
console.log(`...outdated...`); console.log(`...outdated...`);
check.CachedAt = 0; return load(check);
load(check);
return check;
} }
else else
{ {
@ -208,5 +206,24 @@ export const Fetch = {
} }
} }
},
Use(URL:string, Init?:RequestInit, CacheFor:number = 60, DelaySSR:boolean = true)
{
type FetchHookState = [Data:undefined|object, Updating:boolean];
const [cacheGet, cacheSet] = React.useState([undefined, true] as FetchHookState);
React.useEffect(()=>
{
const receipt = Fetch.Request(URL, Init, CacheFor, DelaySSR);
receipt.Promise?.then(()=>{
++count;
if(count > 10){return;}
console.log(`updating state`, receipt);
cacheSet([receipt.JSON, receipt.CachedAt === 0]);
});
}
, []);
return cacheGet;
} }
}; };
let count = 0;