Skip to content

Commit

Permalink
Try using only next data caching
Browse files Browse the repository at this point in the history
  • Loading branch information
trevorsharp committed Apr 15, 2024
1 parent 7040632 commit e70afe7
Show file tree
Hide file tree
Showing 5 changed files with 69 additions and 133 deletions.
Binary file modified bun.lockb
Binary file not shown.
2 changes: 0 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,7 @@
"dependencies": {
"@hookform/resolvers": "^3.3.1",
"@t3-oss/env-nextjs": "^0.9.2",
"@upstash/redis": "^1.29.0",
"next": "^14.1.3",
"node-cache": "^5.1.2",
"podcast": "git+https://github.com/trevorsharp/node-podcast-edge.git#5ea1727",
"react-dom": "^18.2.0",
"react-hook-form": "^7.46.1",
Expand Down
54 changes: 0 additions & 54 deletions src/services/cacheService.ts

This file was deleted.

130 changes: 63 additions & 67 deletions src/services/twitchService.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { env } from "~/env";
import { withCache } from "./cacheService";
import type { User, Video } from "~/types";

type DataWrapper<T> = { data?: T };
Expand Down Expand Up @@ -42,87 +41,84 @@ const getUserData = async (rawUsername: string) => {
return user;
};

const getRawUserData = withCache(
{ cacheKey: "twitch-api-raw-user-data", ttl: 3 * 24 * 60 * 60 },
async (username: string) => {
const data = await getTwitch<DataWrapper<RawUser[]>>(
`https://api.twitch.tv/helix/users?login=${username}`,
);

if (!data?.data || data.data.length === 0)
throw `Sorry, we could not find the user "${username}" 🙁`;

const rawUserData = data.data[0];

if (!rawUserData) throw `Sorry, we could not find the user "${username}" 🙁`;

return rawUserData;
},
);

const getVideos = withCache(
{ cacheKey: "twitch-api-user-videos", ttl: 10 * 60 },
async (userId: string) => {
const data = await getTwitch<DataWrapper<RawVideo[]>>(
`https://api.twitch.tv/helix/videos?user_id=${userId}`,
);

if (!data?.data || data.data.length === 0) return [];

const currentStreamData = await getTwitch<DataWrapper<RawCurrentStream[]>>(
`https://api.twitch.tv/helix/streams?user_id=${userId}`,
);

const currentStream =
currentStreamData?.data && currentStreamData.data.length > 0
? currentStreamData.data[0]
: undefined;

const videos = data.data
.filter((rawVideo) => rawVideo.type === "upload" || rawVideo.type === "archive")
.map((rawVideo) => {
const video: Video = {
id: rawVideo.id,
title: rawVideo.title,
date: rawVideo.published_at,
url: `https://twitch.tv/videos/${rawVideo.id}`,
duration:
currentStream &&
Math.abs(
new Date(currentStream.started_at).getTime() -
new Date(rawVideo.published_at).getTime(),
) < 900000
? undefined
: getDuration(rawVideo.duration),
};

return video;
});

return videos;
},
);

const getTwitchToken = withCache({ cacheKey: "twitch-api-token", ttl: 2 * 60 * 60 }, async () => {
const getRawUserData = async (username: string) => {
const data = await getTwitch<DataWrapper<RawUser[]>>(
`https://api.twitch.tv/helix/users?login=${username}`,
{ ttl: 3 * 24 * 60 * 60 },
);

if (!data?.data || data.data.length === 0)
throw `Sorry, we could not find the user "${username}" 🙁`;

const rawUserData = data.data[0];

if (!rawUserData) throw `Sorry, we could not find the user "${username}" 🙁`;

return rawUserData;
};

const getVideos = async (userId: string) => {
const data = await getTwitch<DataWrapper<RawVideo[]>>(
`https://api.twitch.tv/helix/videos?user_id=${userId}`,
{ ttl: 10 * 60 },
);

if (!data?.data || data.data.length === 0) return [];

const currentStreamData = await getTwitch<DataWrapper<RawCurrentStream[]>>(
`https://api.twitch.tv/helix/streams?user_id=${userId}`,
{ ttl: 10 * 60 },
);

const currentStream =
currentStreamData?.data && currentStreamData.data.length > 0
? currentStreamData.data[0]
: undefined;

const videos = data.data
.filter((rawVideo) => rawVideo.type === "upload" || rawVideo.type === "archive")
.map((rawVideo) => {
const video: Video = {
id: rawVideo.id,
title: rawVideo.title,
date: rawVideo.published_at,
url: `https://twitch.tv/videos/${rawVideo.id}`,
duration:
currentStream &&
Math.abs(
new Date(currentStream.started_at).getTime() -
new Date(rawVideo.published_at).getTime(),
) < 900000
? undefined
: getDuration(rawVideo.duration),
};

return video;
});

return videos;
};

const getTwitchToken = async () => {
const data = await fetch(
`https://id.twitch.tv/oauth2/token?client_id=${env.TWITCH_API_CLIENT_ID}&client_secret=${env.TWITCH_API_SECRET}&grant_type=client_credentials`,
{ method: "POST", cache: "no-store" },
{ method: "POST", next: { revalidate: 2 * 60 * 60 } },
).then((response) => response.json() as Promise<{ access_token?: string; expires_in?: number }>);

if (!data?.access_token || !data?.expires_in) throw "Could not get Twith API token";

return data.access_token;
});
};

const getTwitch = async <T>(url: string) => {
const getTwitch = async <T>(url: string, options?: { ttl?: number }) => {
const token = await getTwitchToken();

const headers = {
Authorization: `Bearer ${token}`,
"Client-Id": env.TWITCH_API_CLIENT_ID,
};

const data = await fetch(url, { headers, cache: "no-store" }).then(
const data = await fetch(url, { headers, next: { revalidate: options?.ttl ?? 0 } }).then(
(response) => response.json() as Promise<T>,
);

Expand Down
16 changes: 6 additions & 10 deletions src/services/videoService.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,13 @@
import { Quality } from "~/types";
import { withCache } from "./cacheService";
import { getVodPlaylist } from "./m3u8Service";

const getStream = withCache(
{ cacheKey: "playlist-data", ttl: 5 * 60 },
async (videoId: string, quality: Quality) => {
const playlistData = await getPlaylistData(videoId, quality);
const getStream = async (videoId: string, quality: Quality) => {
const playlistData = await getPlaylistData(videoId, quality);

if (playlistData === "") throw `Video not found with id ${videoId}`;
if (playlistData === "") throw `Video not found with id ${videoId}`;

return playlistData;
},
);
return playlistData;
};

const getPlaylistData = async (videoId: string, quality: Quality) => {
const [rawPlaylist, playlistData] = await getVodPlaylist(videoId);
Expand All @@ -35,7 +31,7 @@ const getPlaylistData = async (videoId: string, quality: Quality) => {
break;
}

const response = await fetch(playlistUrl, { cache: "no-store" });
const response = await fetch(playlistUrl, { next: { revalidate: 5 * 60 } });
if (response.status !== 200) throw "Failed to fetch content stream";

const baseStreamUrl = playlistUrl.replace(/index[^\.]*\.m3u8/i, "");
Expand Down

0 comments on commit e70afe7

Please sign in to comment.