Skip to content

Commit

Permalink
refactor: optimize data fetching in page.tsx with caching
Browse files Browse the repository at this point in the history
  • Loading branch information
maggienegm committed Jan 14, 2025
1 parent 5ff089f commit 1dea77f
Show file tree
Hide file tree
Showing 5 changed files with 68 additions and 40 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
"dependencies": {
"clsx": "^2.0.0",
"next": "^14.0.0",
"node-cache": "^5.1.2",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"tidelift-me-up": "^0.4.2"
Expand Down
17 changes: 17 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

25 changes: 16 additions & 9 deletions src/app/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,34 +3,41 @@ import { MainArea } from "~/components/MainArea";
import { OptionsForm } from "~/components/OptionsForm";
import { ResultDisplay } from "~/components/ResultDisplay";
import { ScrollButton } from "~/components/ScrollButton";
import { SearchParamsType, fetchData } from "~/utils/fetchData";
import { fetchData } from "~/utils/fetchData";
import { SearchParams, getOptions } from "~/utils/getOptions";

import { metadata as defaultMetadata } from "./layout";
import styles from "./page.module.css";

export interface HomeProps {
searchParams: SearchParamsType;
searchParams: SearchParams;
}

export async function generateMetadata({ searchParams }: HomeProps) {
const { options, result } = await fetchData(searchParams);
const username = options.username || "";
const packageCount = Array.isArray(result) ? result.length : 0;
const options = getOptions(searchParams);
const username = options.username;

if (!username) {
return defaultMetadata;
}

const result = await fetchData(options);

const description = Array.isArray(result)
? `${username} has ${result.length} npm package${
result.length === 1 ? "" : "s"
} eligible for Tidelift funding. 💸`
: `Could not find packages for ${username}`;

return {
description: `${username} has ${packageCount} npm package${
packageCount === 1 ? "" : "s"
} eligible for Tidelift funding. 💸`,
description,
title: `${username} | Tidelift Me Up`,
};
}

export default async function Home({ searchParams }: HomeProps) {
const { options, result } = await fetchData(searchParams);
const options = getOptions(searchParams);
const result = await fetchData(options);

return (
<>
Expand Down
44 changes: 13 additions & 31 deletions src/utils/fetchData.ts
Original file line number Diff line number Diff line change
@@ -1,44 +1,26 @@
import {
EstimatedPackage,
PackageOwnership,
tideliftMeUp,
} from "tidelift-me-up";
import NodeCache from "node-cache";
import { EstimatedPackage, tideliftMeUp } from "tidelift-me-up";

export type OptionsType = Record<string, unknown>;
export type SearchParamsType = Record<string, unknown>;
export type DataOptions = Record<string, unknown>;
export type DataResults = Error | EstimatedPackage[] | undefined;

export async function fetchData(searchParams: SearchParamsType) {
const options = getOptions(searchParams);
const result = await getTideliftData(options);
return { options, result };
}
const cache = new NodeCache();

function getOptions(searchParams: SearchParamsType) {
return {
ownership: undefinedIfEmpty(
[
searchParams.author === "on" && "author",
searchParams.maintainer === "on" && "maintainer",
searchParams.publisher === "on" && "publisher",
].filter(Boolean) as PackageOwnership[],
),
since: (searchParams.since || undefined) as string | undefined,
username: searchParams.username as string,
};
}
export async function fetchData(options: DataOptions) {
const cacheKey = JSON.stringify(options);

if (cache.has(cacheKey)) {
return cache.get<DataResults>(cacheKey);
}

async function getTideliftData(options: OptionsType) {
let result: Error | EstimatedPackage[] | undefined;
let result: DataResults;

try {
result = options.username ? await tideliftMeUp(options) : undefined;
cache.set(cacheKey, result);
} catch (error) {
result = error as Error;
}

return result;
}

function undefinedIfEmpty<T>(items: T[]) {
return items.length === 0 ? undefined : items;
}
21 changes: 21 additions & 0 deletions src/utils/getOptions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { PackageOwnership } from "tidelift-me-up";

export type SearchParams = Record<string, unknown>;

export function getOptions(searchParams: SearchParams) {
return {
ownership: undefinedIfEmpty(
[
searchParams.author === "on" && "author",
searchParams.maintainer === "on" && "maintainer",
searchParams.publisher === "on" && "publisher",
].filter(Boolean) as PackageOwnership[],
),
since: (searchParams.since || undefined) as string | undefined,
username: (searchParams.username || "") as string,
};
}

function undefinedIfEmpty<T>(items: T[]) {
return items.length === 0 ? undefined : items;
}

0 comments on commit 1dea77f

Please sign in to comment.