mirror of
https://github.com/jakejarvis/jarv.is.git
synced 2025-04-26 07:05:21 -04:00
properly use vercel data cache for fetch results
This commit is contained in:
parent
f0d4937f0f
commit
68b09ebc36
@ -1,9 +1,7 @@
|
|||||||
import { NextResponse } from "next/server";
|
import { NextResponse } from "next/server";
|
||||||
|
import { unstable_cache as cache } from "next/cache";
|
||||||
import redis from "../../../lib/helpers/redis";
|
import redis from "../../../lib/helpers/redis";
|
||||||
|
|
||||||
export const dynamic = "force-static";
|
|
||||||
export const revalidate = 1800; // 30 mins
|
|
||||||
|
|
||||||
export const GET = async (): Promise<
|
export const GET = async (): Promise<
|
||||||
NextResponse<{
|
NextResponse<{
|
||||||
total: {
|
total: {
|
||||||
@ -15,32 +13,43 @@ export const GET = async (): Promise<
|
|||||||
}>;
|
}>;
|
||||||
}>
|
}>
|
||||||
> => {
|
> => {
|
||||||
// get all keys (aka slugs)
|
const { total, pages } = await cache(
|
||||||
const slugs = await redis.scan(0, {
|
async () => {
|
||||||
match: "hits:*",
|
// get all keys (aka slugs)
|
||||||
type: "string",
|
const slugs = await redis.scan(0, {
|
||||||
// set an arbitrary yet generous upper limit, just in case...
|
match: "hits:*",
|
||||||
count: 99,
|
type: "string",
|
||||||
});
|
// set an arbitrary yet generous upper limit, just in case...
|
||||||
|
count: 99,
|
||||||
|
});
|
||||||
|
|
||||||
// get the value (number of hits) for each key (the slug of the page)
|
// get the value (number of hits) for each key (the slug of the page)
|
||||||
const values = await redis.mget<string[]>(...slugs[1]);
|
const values = await redis.mget<string[]>(...slugs[1]);
|
||||||
|
|
||||||
// pair the slugs with their hit values
|
// pair the slugs with their hit values
|
||||||
const pages = slugs[1].map((slug, index) => ({
|
const pages = slugs[1].map((slug, index) => ({
|
||||||
slug: slug.split(":").pop() as string, // remove the "hits:" prefix
|
slug: slug.split(":").pop() as string, // remove the "hits:" prefix
|
||||||
hits: parseInt(values[index], 10),
|
hits: parseInt(values[index], 10),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
// sort descending by hits
|
// sort descending by hits
|
||||||
pages.sort((a, b) => b.hits - a.hits);
|
pages.sort((a, b) => b.hits - a.hits);
|
||||||
|
|
||||||
// calculate total hits
|
// calculate total hits
|
||||||
const total = { hits: 0 };
|
const total = { hits: 0 };
|
||||||
pages.forEach((page) => {
|
pages.forEach((page) => {
|
||||||
// add these hits to running tally
|
// add these hits to running tally
|
||||||
total.hits += page.hits;
|
total.hits += page.hits;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
return { total, pages };
|
||||||
|
},
|
||||||
|
undefined,
|
||||||
|
{
|
||||||
|
revalidate: 1800, // 30 minutes
|
||||||
|
tags: ["hits"],
|
||||||
|
}
|
||||||
|
)();
|
||||||
|
|
||||||
return NextResponse.json({ total, pages });
|
return NextResponse.json({ total, pages });
|
||||||
};
|
};
|
||||||
|
@ -86,8 +86,8 @@ const getRepos = async (): Promise<Project[] | null> => {
|
|||||||
...options,
|
...options,
|
||||||
cache: "force-cache",
|
cache: "force-cache",
|
||||||
next: {
|
next: {
|
||||||
// 10 minutes
|
revalidate: 600, // 10 minutes
|
||||||
revalidate: 600,
|
tags: ["github-api"],
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
@ -12,8 +12,8 @@ const Gist = async ({ id, file }: GistProps) => {
|
|||||||
const scriptResponse = await fetch(scriptUrl, {
|
const scriptResponse = await fetch(scriptUrl, {
|
||||||
cache: "force-cache",
|
cache: "force-cache",
|
||||||
next: {
|
next: {
|
||||||
// cache indefinitely in data store
|
revalidate: false, // cache indefinitely in data store
|
||||||
revalidate: false,
|
tags: ["gist"],
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { unstable_cache } from "next/cache";
|
import { unstable_cache as cache } from "next/cache";
|
||||||
import Image from "next/image";
|
import Image from "next/image";
|
||||||
import { EmbeddedTweet, TweetNotFound } from "react-tweet";
|
import { EmbeddedTweet, TweetNotFound } from "react-tweet";
|
||||||
import { fetchTweet as _fetchTweet } from "react-tweet/api";
|
import { fetchTweet as _fetchTweet } from "react-tweet/api";
|
||||||
@ -12,9 +12,9 @@ export type TweetProps = Omit<ComponentPropsWithoutRef<typeof EmbeddedTweet>, "t
|
|||||||
className?: string;
|
className?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
const fetchTweet = unstable_cache(async (id: string) => _fetchTweet(id), [], {
|
const fetchTweet = cache(async (id: string) => _fetchTweet(id), undefined, {
|
||||||
// cache indefinitely
|
revalidate: false, // cache indefinitely
|
||||||
revalidate: false,
|
tags: ["tweet"],
|
||||||
});
|
});
|
||||||
|
|
||||||
const Tweet = async ({ id, className, ...rest }: TweetProps) => {
|
const Tweet = async ({ id, className, ...rest }: TweetProps) => {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user