1
mirror of https://github.com/jakejarvis/jarv.is.git synced 2025-06-27 18:05:41 -04:00
Files
jarv.is/lib/views.ts

83 lines
2.4 KiB
TypeScript

import "server-only";
import { eq, inArray } from "drizzle-orm";
import { db } from "@/lib/db";
import { page } from "@/lib/db/schema";
export const incrementViews = async (slug: string): Promise<number> => {
try {
// First, try to find the existing record
const existingPage = await db.select().from(page).where(eq(page.slug, slug)).limit(1);
if (existingPage.length === 0) {
// Create new record if it doesn't exist
await db.insert(page).values({ slug, views: 1 }).execute();
return 1; // New record starts with 1 hit
} else {
// Calculate new hit count
const newViewCount = existingPage[0].views + 1;
// Update existing record by incrementing hits
await db.update(page).set({ views: newViewCount }).where(eq(page.slug, slug)).execute();
return newViewCount;
}
} catch (error) {
console.error("[view-counter] fatal error:", error);
throw new Error("Failed to increment views");
}
};
export const getViews: {
/**
* Retrieves the number of views for a given slug, or null if the slug does not exist
*/
(slug: string): Promise<number | null>;
/**
* Retrieves the numbers of views for an array of slugs
*/
(slug: string[]): Promise<Record<string, number | null>>;
/**
* Retrieves the numbers of views for ALL slugs
*/
(): Promise<Record<string, number>>;
} = async (
// eslint-disable-next-line @typescript-eslint/no-explicit-any
slug?: any
): // eslint-disable-next-line @typescript-eslint/no-explicit-any
Promise<any> => {
try {
// return one page
if (typeof slug === "string") {
const pages = await db.select().from(page).where(eq(page.slug, slug)).limit(1);
return pages[0].views;
}
// return multiple pages
if (Array.isArray(slug)) {
const pages = await db.select().from(page).where(inArray(page.slug, slug));
return pages.reduce(
(acc, page, index) => {
acc[slug[index]] = page.views;
return acc;
},
{} as Record<string, number | null>
);
}
// return ALL pages
const pages = await db.select().from(page);
return pages.reduce(
(acc, page) => {
acc[page.slug] = page.views;
return acc;
},
{} as Record<string, number>
);
} catch (error) {
console.error("[server/views] fatal error:", error);
throw new Error("Failed to get views");
}
};