Added Redis for Caching and Started Database Query Caching Migration to Redis

This commit is contained in:
Ahmad 2025-01-18 19:14:19 -05:00
parent f99360d9b9
commit 0f899cb34f
No known key found for this signature in database
GPG key ID: 8FD8A93530D182BF
12 changed files with 260 additions and 632 deletions

View file

@ -23,9 +23,8 @@ Documentation can be found [here](https://docs.tasko.ahmadk953.org/).
This will be published on the site some time soon but for now, the roadmap will be listed here.
- [ ] Board sorting options (Boards Page)
- [ ] Add real-time collaboration _In Progress - Liveblocks with presence implemented roughly_
- [ ] Add real-time collaboration _In Progress - Part 1 Finished_
- [ ] Add end-to-end Database encryption (for customer data such as card titles and descriptions, and subscription information)
- [ ] Add dark mode _In Progress_
- [ ] Rich Text Support in Card Descriptions
- [ ] Self-Hosted Version
- [ ] Move Roadmap to Website _In Progress - Starting off With a Basic MDX Page_

View file

@ -1,7 +1,7 @@
'use server';
import { auth } from '@clerk/nextjs/server';
import { revalidatePath } from 'next/cache';
import { revalidatePath, revalidateTag } from 'next/cache';
import { db } from '@/lib/db';
import { createSafeAction } from '@/lib/create-safe-action';
@ -36,6 +36,9 @@ const handler = async (data: InputType): Promise<ReturnType> => {
);
updatedCards = await db.$transaction(transaction);
items.map((card) => {
revalidateTag(`card-${card.id}`);
});
} catch (error) {
return {
error: 'Failed to reorder list',

View file

@ -1,7 +1,7 @@
'use server';
import { auth } from '@clerk/nextjs/server';
import { revalidatePath } from 'next/cache';
import { revalidatePath, revalidateTag } from 'next/cache';
import { ACTION, ENTITY_TYPE } from '@prisma/client';
import { db } from '@/lib/db';
@ -48,6 +48,7 @@ const handler = async (data: InputType): Promise<ReturnType> => {
};
}
revalidateTag(`card-${id}`);
revalidatePath(`/board/${boardId}`);
return { data: card };
};

View file

@ -1,6 +1,7 @@
import { auth } from '@clerk/nextjs/server';
import { ENTITY_TYPE } from '@prisma/client';
import { NextResponse } from 'next/server';
import { unstable_cache } from 'next/cache';
import { db } from '@/lib/db';
@ -17,21 +18,28 @@ export async function GET(
status: 401,
});
const auditLogs = await db.auditLog.findMany({
where: {
orgId,
entityId: params.cardId,
entityType: ENTITY_TYPE.CARD,
const getAuditLogs = unstable_cache(
async () => {
return await db.auditLog.findMany({
where: {
orgId,
entityId: params.cardId,
entityType: ENTITY_TYPE.CARD,
},
orderBy: {
createdAt: 'desc',
},
take: 3,
});
},
orderBy: {
createdAt: 'desc',
},
take: 3,
cacheStrategy: {
ttl: 30,
swr: 60,
},
});
[`card-logs-${params.cardId}`],
{
tags: [`card-logs-${params.cardId}`],
revalidate: false,
}
);
const auditLogs = await getAuditLogs();
return new NextResponse(JSON.stringify(auditLogs), {
status: 200,

View file

@ -2,6 +2,7 @@ import { auth } from '@clerk/nextjs/server';
import { NextResponse } from 'next/server';
import { db } from '@/lib/db';
import { unstable_cache } from 'next/cache';
export async function GET(
req: Request,
@ -16,27 +17,34 @@ export async function GET(
status: 401,
});
const card = await db.card.findUnique({
where: {
id: params.cardId,
list: {
board: {
orgId,
const getCard = unstable_cache(
async () => {
return await db.card.findUnique({
where: {
id: params.cardId,
list: {
board: {
orgId,
},
},
},
},
},
include: {
list: {
select: {
title: true,
include: {
list: {
select: {
title: true,
},
},
},
},
});
},
cacheStrategy: {
ttl: 30,
swr: 60,
},
});
[`card-${params.cardId}`],
{
tags: [`card-${params.cardId}`],
revalidate: false,
}
);
const card = await getCard();
return new NextResponse(JSON.stringify(card), {
status: 200,

67
cache-handler.ts Normal file
View file

@ -0,0 +1,67 @@
import { CacheHandler } from '@neshca/cache-handler';
import createLruHandler from '@neshca/cache-handler/local-lru';
import createRedisHandler from '@neshca/cache-handler/redis-stack';
import { createClient } from 'redis';
CacheHandler.onCreation(async () => {
let client;
try {
client = createClient({
url: process.env.REDIS_URL,
});
client.on('error', (error) => {
if (typeof process.env.NEXT_PRIVATE_DEBUG_CACHE !== 'undefined') {
console.error('Redis client error:', error);
}
});
} catch (error) {
console.warn('Failed to create Redis client:', error);
}
if (client) {
try {
console.info('Connecting Redis client...');
await client.connect();
console.info('Redis client connected.');
} catch (error) {
console.warn('Failed to connect Redis client:', error);
console.warn('Disconnecting the Redis client...');
client
.disconnect()
.then(() => {
console.info('Redis client disconnected.');
})
.catch(() => {
console.warn(
'Failed to quit the Redis client after failing to connect.'
);
});
}
}
/** @type {import("@neshca/cache-handler").Handler | null} */
let handler;
if (client?.isReady) {
handler = await createRedisHandler({
client,
keyPrefix: 'tasko:',
timeoutMs: 1000,
});
} else {
handler = createLruHandler();
console.warn(
'Falling back to LRU handler because Redis client is not available.'
);
}
return {
handlers: [handler],
};
});
export default CacheHandler;

View file

@ -5,17 +5,14 @@ import Link from 'next/link';
import { useTheme } from 'next-themes';
export const Logo = () => {
const { theme } = useTheme();
const { resolvedTheme } = useTheme();
return (
// TODO: Make this go back to the organization page if you are logged in
<Link href='/'>
<div
className='hidden items-center gap-x-2 transition hover:opacity-75 md:flex'
suppressHydrationWarning
>
<Link href='/' suppressHydrationWarning>
<div className='hidden items-center gap-x-2 transition hover:opacity-75 md:flex'>
<Image
src={`/logo-${theme === 'light' ? 'light' : 'dark'}.svg`}
src={`/logo-${resolvedTheme === 'dark' ? 'dark' : 'light'}.svg`}
alt='logo'
height={100}
width={100}

View file

@ -3,6 +3,14 @@ import * as Sentry from '@sentry/nextjs';
export async function register() {
if (process.env.NEXT_RUNTIME === 'nodejs') {
await import('./sentry.server.config');
const { registerInitialCache } = await import(
'@neshca/cache-handler/instrumentation'
);
const CacheHandler = (await import('./cache-handler')).default;
await registerInitialCache(CacheHandler);
}
if (process.env.NEXT_RUNTIME === 'edge') {

View file

@ -2,6 +2,7 @@ import { auth, currentUser } from '@clerk/nextjs/server';
import { ACTION, ENTITY_TYPE } from '@prisma/client';
import { db } from '@/lib/db';
import { revalidateTag } from 'next/cache';
interface Props {
entityId: string;
@ -31,6 +32,8 @@ export const createAuditLog = async (props: Props) => {
userName: user?.firstName + ' ' + user?.lastName,
},
});
revalidateTag(`card-logs-${entityId}`);
} catch (error) {
console.error('[AUDIT_LOG_ERROR]', error);
}

View file

@ -9,6 +9,7 @@ const nextConfig: NextConfig = {
reactCompiler: true,
mdxRs: true,
webpackMemoryOptimizations: true,
webpackBuildWorker: true,
},
images: {
remotePatterns: [
@ -50,6 +51,10 @@ const nextConfig: NextConfig = {
return config;
},
cacheHandler:
process.env.NODE_ENV === 'production'
? require.resolve('./cache-handler.ts')
: undefined,
};
const withMDX = createMDX({});

View file

@ -26,6 +26,7 @@
"@liveblocks/react": "^2.15.1",
"@mdx-js/loader": "^3.1.0",
"@mdx-js/react": "^3.1.0",
"@neshca/cache-handler": "^1.9.0",
"@next/mdx": "^15.1.5",
"@prisma/client": "^6.2.1",
"@prisma/extension-accelerate": "^1.2.1",
@ -54,6 +55,7 @@
"react": "^19.0.0",
"react-day-picker": "^9.5.0",
"react-dom": "^19.0.0",
"redis": "^4.7.0",
"sharp": "^0.33.5",
"sonner": "^1.7.2",
"stripe": "^17.4.0",
@ -104,9 +106,7 @@
"prisma": "^6.2.1",
"tailwindcss": "^3.4.16",
"ts-node": "^10.9.2",
"typescript": "^5.7.3",
"vite-tsconfig-paths": "^5.1.4",
"vitest": "^2.1.8"
"typescript": "^5.7.3"
},
"packageManager": "yarn@4.6.0"
}

701
yarn.lock
View file

@ -1996,6 +1996,19 @@ __metadata:
languageName: node
linkType: hard
"@neshca/cache-handler@npm:^1.9.0":
version: 1.9.0
resolution: "@neshca/cache-handler@npm:1.9.0"
dependencies:
cluster-key-slot: "npm:1.1.2"
lru-cache: "npm:10.4.3"
peerDependencies:
next: ">= 13.5.1 < 15"
redis: ">= 4.6"
checksum: 10c0/883360e0979181448c8a81886d69e3460d3ea60283ceaaf1941a8bc8255cb1dedf5ba448951cf0cabf9969381a4481777d3c408cd7a5537e7e4d0c13f89544a4
languageName: node
linkType: hard
"@next/env@npm:15.1.5":
version: 15.1.5
resolution: "@next/env@npm:15.1.5"
@ -3617,6 +3630,62 @@ __metadata:
languageName: node
linkType: hard
"@redis/bloom@npm:1.2.0":
version: 1.2.0
resolution: "@redis/bloom@npm:1.2.0"
peerDependencies:
"@redis/client": ^1.0.0
checksum: 10c0/7dde8e67188164e96226c8a5c78ebd2801f1662947371e78fb95fb180c1e9ddff8d237012eb5e9182775be61cb546f67f759927cdaee0d178d863ee290e1fb27
languageName: node
linkType: hard
"@redis/client@npm:1.6.0":
version: 1.6.0
resolution: "@redis/client@npm:1.6.0"
dependencies:
cluster-key-slot: "npm:1.1.2"
generic-pool: "npm:3.9.0"
yallist: "npm:4.0.0"
checksum: 10c0/c80a01b4f72d32284515dac6d1aefe0e9c881d08b8db33281f87b51650c1c116b18074a29ca81599d15dccb37b29eef9b26a75a5755150ae27d163e680c34bf6
languageName: node
linkType: hard
"@redis/graph@npm:1.1.1":
version: 1.1.1
resolution: "@redis/graph@npm:1.1.1"
peerDependencies:
"@redis/client": ^1.0.0
checksum: 10c0/64199db2cb3669c4911af8aba3b7116c4c2c1df37ca74b2a65555e62c863935a0cea74bc41bd92acf2e551074eb2a30c75f54a9f439b40e0f9bb67fc5fb66614
languageName: node
linkType: hard
"@redis/json@npm:1.0.7":
version: 1.0.7
resolution: "@redis/json@npm:1.0.7"
peerDependencies:
"@redis/client": ^1.0.0
checksum: 10c0/cef473711d66f7568a16edbd728acca7d237cfeaa15e0326b5b628dfab4afc0c76c7354e7f8efad6ecc64a1cb774e4aa060ee46497b633e18ba0a2f0aace1cc4
languageName: node
linkType: hard
"@redis/search@npm:1.2.0":
version: 1.2.0
resolution: "@redis/search@npm:1.2.0"
peerDependencies:
"@redis/client": ^1.0.0
checksum: 10c0/01d57ac10d2c5698e04e4a2f945440db3087e8834643ca950c099879dbcd77526604ca6f5c2ee883dfd4b337b0a24cb7d81ac56845aa83f89a4f161362a08dc6
languageName: node
linkType: hard
"@redis/time-series@npm:1.1.0":
version: 1.1.0
resolution: "@redis/time-series@npm:1.1.0"
peerDependencies:
"@redis/client": ^1.0.0
checksum: 10c0/503d0d5cbc9113d26666bb7b4dea57619badbcdfeee0369abf647250f26c5482ed5827c83f88f9f0cf22e021e3e7cb562459669d733fac05652972e208d6ba0f
languageName: node
linkType: hard
"@rollup/plugin-commonjs@npm:28.0.1":
version: 28.0.1
resolution: "@rollup/plugin-commonjs@npm:28.0.1"
@ -3653,139 +3722,6 @@ __metadata:
languageName: node
linkType: hard
"@rollup/rollup-android-arm-eabi@npm:4.30.1":
version: 4.30.1
resolution: "@rollup/rollup-android-arm-eabi@npm:4.30.1"
conditions: os=android & cpu=arm
languageName: node
linkType: hard
"@rollup/rollup-android-arm64@npm:4.30.1":
version: 4.30.1
resolution: "@rollup/rollup-android-arm64@npm:4.30.1"
conditions: os=android & cpu=arm64
languageName: node
linkType: hard
"@rollup/rollup-darwin-arm64@npm:4.30.1":
version: 4.30.1
resolution: "@rollup/rollup-darwin-arm64@npm:4.30.1"
conditions: os=darwin & cpu=arm64
languageName: node
linkType: hard
"@rollup/rollup-darwin-x64@npm:4.30.1":
version: 4.30.1
resolution: "@rollup/rollup-darwin-x64@npm:4.30.1"
conditions: os=darwin & cpu=x64
languageName: node
linkType: hard
"@rollup/rollup-freebsd-arm64@npm:4.30.1":
version: 4.30.1
resolution: "@rollup/rollup-freebsd-arm64@npm:4.30.1"
conditions: os=freebsd & cpu=arm64
languageName: node
linkType: hard
"@rollup/rollup-freebsd-x64@npm:4.30.1":
version: 4.30.1
resolution: "@rollup/rollup-freebsd-x64@npm:4.30.1"
conditions: os=freebsd & cpu=x64
languageName: node
linkType: hard
"@rollup/rollup-linux-arm-gnueabihf@npm:4.30.1":
version: 4.30.1
resolution: "@rollup/rollup-linux-arm-gnueabihf@npm:4.30.1"
conditions: os=linux & cpu=arm & libc=glibc
languageName: node
linkType: hard
"@rollup/rollup-linux-arm-musleabihf@npm:4.30.1":
version: 4.30.1
resolution: "@rollup/rollup-linux-arm-musleabihf@npm:4.30.1"
conditions: os=linux & cpu=arm & libc=musl
languageName: node
linkType: hard
"@rollup/rollup-linux-arm64-gnu@npm:4.30.1":
version: 4.30.1
resolution: "@rollup/rollup-linux-arm64-gnu@npm:4.30.1"
conditions: os=linux & cpu=arm64 & libc=glibc
languageName: node
linkType: hard
"@rollup/rollup-linux-arm64-musl@npm:4.30.1":
version: 4.30.1
resolution: "@rollup/rollup-linux-arm64-musl@npm:4.30.1"
conditions: os=linux & cpu=arm64 & libc=musl
languageName: node
linkType: hard
"@rollup/rollup-linux-loongarch64-gnu@npm:4.30.1":
version: 4.30.1
resolution: "@rollup/rollup-linux-loongarch64-gnu@npm:4.30.1"
conditions: os=linux & cpu=loong64 & libc=glibc
languageName: node
linkType: hard
"@rollup/rollup-linux-powerpc64le-gnu@npm:4.30.1":
version: 4.30.1
resolution: "@rollup/rollup-linux-powerpc64le-gnu@npm:4.30.1"
conditions: os=linux & cpu=ppc64 & libc=glibc
languageName: node
linkType: hard
"@rollup/rollup-linux-riscv64-gnu@npm:4.30.1":
version: 4.30.1
resolution: "@rollup/rollup-linux-riscv64-gnu@npm:4.30.1"
conditions: os=linux & cpu=riscv64 & libc=glibc
languageName: node
linkType: hard
"@rollup/rollup-linux-s390x-gnu@npm:4.30.1":
version: 4.30.1
resolution: "@rollup/rollup-linux-s390x-gnu@npm:4.30.1"
conditions: os=linux & cpu=s390x & libc=glibc
languageName: node
linkType: hard
"@rollup/rollup-linux-x64-gnu@npm:4.30.1":
version: 4.30.1
resolution: "@rollup/rollup-linux-x64-gnu@npm:4.30.1"
conditions: os=linux & cpu=x64 & libc=glibc
languageName: node
linkType: hard
"@rollup/rollup-linux-x64-musl@npm:4.30.1":
version: 4.30.1
resolution: "@rollup/rollup-linux-x64-musl@npm:4.30.1"
conditions: os=linux & cpu=x64 & libc=musl
languageName: node
linkType: hard
"@rollup/rollup-win32-arm64-msvc@npm:4.30.1":
version: 4.30.1
resolution: "@rollup/rollup-win32-arm64-msvc@npm:4.30.1"
conditions: os=win32 & cpu=arm64
languageName: node
linkType: hard
"@rollup/rollup-win32-ia32-msvc@npm:4.30.1":
version: 4.30.1
resolution: "@rollup/rollup-win32-ia32-msvc@npm:4.30.1"
conditions: os=win32 & cpu=ia32
languageName: node
linkType: hard
"@rollup/rollup-win32-x64-msvc@npm:4.30.1":
version: 4.30.1
resolution: "@rollup/rollup-win32-x64-msvc@npm:4.30.1"
conditions: os=win32 & cpu=x64
languageName: node
linkType: hard
"@rtsao/scc@npm:^1.1.0":
version: 1.1.0
resolution: "@rtsao/scc@npm:1.1.0"
@ -4372,7 +4308,7 @@ __metadata:
languageName: node
linkType: hard
"@types/estree@npm:*, @types/estree@npm:1.0.6, @types/estree@npm:^1.0.0, @types/estree@npm:^1.0.6":
"@types/estree@npm:*, @types/estree@npm:^1.0.0, @types/estree@npm:^1.0.6":
version: 1.0.6
resolution: "@types/estree@npm:1.0.6"
checksum: 10c0/cdfd751f6f9065442cd40957c07fd80361c962869aa853c1c2fd03e101af8b9389d8ff4955a43a6fcfa223dd387a089937f95be0f3eec21ca527039fd2d9859a
@ -5012,87 +4948,6 @@ __metadata:
languageName: node
linkType: hard
"@vitest/expect@npm:2.1.8":
version: 2.1.8
resolution: "@vitest/expect@npm:2.1.8"
dependencies:
"@vitest/spy": "npm:2.1.8"
"@vitest/utils": "npm:2.1.8"
chai: "npm:^5.1.2"
tinyrainbow: "npm:^1.2.0"
checksum: 10c0/6fbf4abc2360efe4d3671d3425f8bb6012fe2dd932a88720d8b793030b766ba260494822c721d3fc497afe52373515c7e150635a95c25f6e1b567f86155c5408
languageName: node
linkType: hard
"@vitest/mocker@npm:2.1.8":
version: 2.1.8
resolution: "@vitest/mocker@npm:2.1.8"
dependencies:
"@vitest/spy": "npm:2.1.8"
estree-walker: "npm:^3.0.3"
magic-string: "npm:^0.30.12"
peerDependencies:
msw: ^2.4.9
vite: ^5.0.0
peerDependenciesMeta:
msw:
optional: true
vite:
optional: true
checksum: 10c0/b4113ed8a57c0f60101d02e1b1769357a346ecd55ded499eab384d52106fd4b12d51e9aaa6db98f47de0d56662477be0ed8d46d6dfa84c235f9e1b234709814e
languageName: node
linkType: hard
"@vitest/pretty-format@npm:2.1.8, @vitest/pretty-format@npm:^2.1.8":
version: 2.1.8
resolution: "@vitest/pretty-format@npm:2.1.8"
dependencies:
tinyrainbow: "npm:^1.2.0"
checksum: 10c0/1dc5c9b1c7c7e78e46a2a16033b6b20be05958bbebc5a5b78f29e32718c80252034804fccd23f34db6b3583239db47e68fc5a8e41942c54b8047cc3b4133a052
languageName: node
linkType: hard
"@vitest/runner@npm:2.1.8":
version: 2.1.8
resolution: "@vitest/runner@npm:2.1.8"
dependencies:
"@vitest/utils": "npm:2.1.8"
pathe: "npm:^1.1.2"
checksum: 10c0/d0826a71494adeafc8c6478257f584d11655145c83e2d8f94c17301d7059c7463ad768a69379e394c50838a7435abcc9255a6b7d8894f5ee06b153e314683a75
languageName: node
linkType: hard
"@vitest/snapshot@npm:2.1.8":
version: 2.1.8
resolution: "@vitest/snapshot@npm:2.1.8"
dependencies:
"@vitest/pretty-format": "npm:2.1.8"
magic-string: "npm:^0.30.12"
pathe: "npm:^1.1.2"
checksum: 10c0/8d7a77a52e128630ea737ee0a0fe746d1d325cac5848326861dbf042844da4d5c1a5145539ae0ed1a3f0b0363506e98d86f2679fadf114ec4b987f1eb616867b
languageName: node
linkType: hard
"@vitest/spy@npm:2.1.8":
version: 2.1.8
resolution: "@vitest/spy@npm:2.1.8"
dependencies:
tinyspy: "npm:^3.0.2"
checksum: 10c0/9740f10772ede004ea7f9ffb8a6c3011341d75d9d7f2d4d181b123a701c4691e942f38cf1700684a3bb5eea3c78addf753fd8cdf78c51d8eadc3bada6fadf8f2
languageName: node
linkType: hard
"@vitest/utils@npm:2.1.8":
version: 2.1.8
resolution: "@vitest/utils@npm:2.1.8"
dependencies:
"@vitest/pretty-format": "npm:2.1.8"
loupe: "npm:^3.1.2"
tinyrainbow: "npm:^1.2.0"
checksum: 10c0/d4a29ecd8f6c24c790e4c009f313a044d89e664e331bc9c3cfb57fe1380fb1d2999706dbbfc291f067d6c489602e76d00435309fbc906197c0d01f831ca17d64
languageName: node
linkType: hard
"abab@npm:^2.0.6":
version: 2.0.6
resolution: "abab@npm:2.0.6"
@ -5416,13 +5271,6 @@ __metadata:
languageName: node
linkType: hard
"assertion-error@npm:^2.0.1":
version: 2.0.1
resolution: "assertion-error@npm:2.0.1"
checksum: 10c0/bbbcb117ac6480138f8c93cf7f535614282dea9dc828f540cdece85e3c665e8f78958b96afac52f29ff883c72638e6a87d469ecc9fe5bc902df03ed24a55dba8
languageName: node
linkType: hard
"ast-types-flow@npm:^0.0.8":
version: 0.0.8
resolution: "ast-types-flow@npm:0.0.8"
@ -5670,13 +5518,6 @@ __metadata:
languageName: node
linkType: hard
"cac@npm:^6.7.14":
version: 6.7.14
resolution: "cac@npm:6.7.14"
checksum: 10c0/4ee06aaa7bab8981f0d54e5f5f9d4adcd64058e9697563ce336d8a3878ed018ee18ebe5359b2430eceae87e0758e62ea2019c3f52ae6e211b1bd2e133856cd10
languageName: node
linkType: hard
"cacache@npm:^19.0.1":
version: 19.0.1
resolution: "cacache@npm:19.0.1"
@ -5778,19 +5619,6 @@ __metadata:
languageName: node
linkType: hard
"chai@npm:^5.1.2":
version: 5.1.2
resolution: "chai@npm:5.1.2"
dependencies:
assertion-error: "npm:^2.0.1"
check-error: "npm:^2.1.1"
deep-eql: "npm:^5.0.1"
loupe: "npm:^3.1.0"
pathval: "npm:^2.0.0"
checksum: 10c0/6c04ff8495b6e535df9c1b062b6b094828454e9a3c9493393e55b2f4dbff7aa2a29a4645133cad160fb00a16196c4dc03dc9bb37e1f4ba9df3b5f50d7533a736
languageName: node
linkType: hard
"chalk@npm:3.0.0, chalk@npm:^3.0.0":
version: 3.0.0
resolution: "chalk@npm:3.0.0"
@ -5846,13 +5674,6 @@ __metadata:
languageName: node
linkType: hard
"check-error@npm:^2.1.1":
version: 2.1.1
resolution: "check-error@npm:2.1.1"
checksum: 10c0/979f13eccab306cf1785fa10941a590b4e7ea9916ea2a4f8c87f0316fc3eab07eabefb6e587424ef0f88cbcd3805791f172ea739863ca3d7ce2afc54641c7f0e
languageName: node
linkType: hard
"chokidar@npm:^3.5.3, chokidar@npm:^3.6.0":
version: 3.6.0
resolution: "chokidar@npm:3.6.0"
@ -5927,6 +5748,13 @@ __metadata:
languageName: node
linkType: hard
"cluster-key-slot@npm:1.1.2":
version: 1.1.2
resolution: "cluster-key-slot@npm:1.1.2"
checksum: 10c0/d7d39ca28a8786e9e801eeb8c770e3c3236a566625d7299a47bb71113fb2298ce1039596acb82590e598c52dbc9b1f088c8f587803e697cb58e1867a95ff94d3
languageName: node
linkType: hard
"co@npm:^4.6.0":
version: 4.6.0
resolution: "co@npm:4.6.0"
@ -6253,13 +6081,6 @@ __metadata:
languageName: node
linkType: hard
"deep-eql@npm:^5.0.1":
version: 5.0.2
resolution: "deep-eql@npm:5.0.2"
checksum: 10c0/7102cf3b7bb719c6b9c0db2e19bf0aa9318d141581befe8c7ce8ccd39af9eaa4346e5e05adef7f9bd7015da0f13a3a25dcfe306ef79dc8668aedbecb658dd247
languageName: node
linkType: hard
"deep-is@npm:^0.1.3":
version: 0.1.4
resolution: "deep-is@npm:0.1.4"
@ -6660,13 +6481,6 @@ __metadata:
languageName: node
linkType: hard
"es-module-lexer@npm:^1.5.4":
version: 1.6.0
resolution: "es-module-lexer@npm:1.6.0"
checksum: 10c0/667309454411c0b95c476025929881e71400d74a746ffa1ff4cb450bd87f8e33e8eef7854d68e401895039ac0bac64e7809acbebb6253e055dd49ea9e3ea9212
languageName: node
linkType: hard
"es-object-atoms@npm:^1.0.0":
version: 1.0.0
resolution: "es-object-atoms@npm:1.0.0"
@ -6732,7 +6546,7 @@ __metadata:
languageName: node
linkType: hard
"esbuild@npm:^0.21.3, esbuild@npm:^0.21.4":
"esbuild@npm:^0.21.4":
version: 0.21.5
resolution: "esbuild@npm:0.21.5"
dependencies:
@ -7311,7 +7125,7 @@ __metadata:
languageName: node
linkType: hard
"estree-walker@npm:^3.0.0, estree-walker@npm:^3.0.3":
"estree-walker@npm:^3.0.0":
version: 3.0.3
resolution: "estree-walker@npm:3.0.3"
dependencies:
@ -7351,13 +7165,6 @@ __metadata:
languageName: node
linkType: hard
"expect-type@npm:^1.1.0":
version: 1.1.0
resolution: "expect-type@npm:1.1.0"
checksum: 10c0/5af0febbe8fe18da05a6d51e3677adafd75213512285408156b368ca471252565d5ca6e59e4bddab25121f3cfcbbebc6a5489f8cc9db131cc29e69dcdcc7ae15
languageName: node
linkType: hard
"expect@npm:^29.0.0, expect@npm:^29.7.0":
version: 29.7.0
resolution: "expect@npm:29.7.0"
@ -7649,7 +7456,7 @@ __metadata:
languageName: node
linkType: hard
"fsevents@npm:2.3.3, fsevents@npm:^2.3.2, fsevents@npm:~2.3.2, fsevents@npm:~2.3.3":
"fsevents@npm:2.3.3, fsevents@npm:^2.3.2, fsevents@npm:~2.3.2":
version: 2.3.3
resolution: "fsevents@npm:2.3.3"
dependencies:
@ -7659,7 +7466,7 @@ __metadata:
languageName: node
linkType: hard
"fsevents@patch:fsevents@npm%3A2.3.3#optional!builtin<compat/fsevents>, fsevents@patch:fsevents@npm%3A^2.3.2#optional!builtin<compat/fsevents>, fsevents@patch:fsevents@npm%3A~2.3.2#optional!builtin<compat/fsevents>, fsevents@patch:fsevents@npm%3A~2.3.3#optional!builtin<compat/fsevents>":
"fsevents@patch:fsevents@npm%3A2.3.3#optional!builtin<compat/fsevents>, fsevents@patch:fsevents@npm%3A^2.3.2#optional!builtin<compat/fsevents>, fsevents@patch:fsevents@npm%3A~2.3.2#optional!builtin<compat/fsevents>":
version: 2.3.3
resolution: "fsevents@patch:fsevents@npm%3A2.3.3#optional!builtin<compat/fsevents>::version=2.3.3&hash=df0bf1"
dependencies:
@ -7696,6 +7503,13 @@ __metadata:
languageName: node
linkType: hard
"generic-pool@npm:3.9.0":
version: 3.9.0
resolution: "generic-pool@npm:3.9.0"
checksum: 10c0/6b314d0d71170d5cbaf7162c423f53f8d6556b2135626a65bcdc03c089840b0a2f59eeb2d907939b8200e945eaf71ceb6630426f22d2128a1d242aec4b232aa7
languageName: node
linkType: hard
"gensync@npm:^1.0.0-beta.2":
version: 1.0.0-beta.2
resolution: "gensync@npm:1.0.0-beta.2"
@ -7879,13 +7693,6 @@ __metadata:
languageName: node
linkType: hard
"globrex@npm:^0.1.2":
version: 0.1.2
resolution: "globrex@npm:0.1.2"
checksum: 10c0/a54c029520cf58bda1d8884f72bd49b4cd74e977883268d931fd83bcbd1a9eb96d57c7dbd4ad80148fb9247467ebfb9b215630b2ed7563b2a8de02e1ff7f89d1
languageName: node
linkType: hard
"gopd@npm:^1.0.1, gopd@npm:^1.2.0":
version: 1.2.0
resolution: "gopd@npm:1.2.0"
@ -9490,13 +9297,6 @@ __metadata:
languageName: node
linkType: hard
"loupe@npm:^3.1.0, loupe@npm:^3.1.2":
version: 3.1.2
resolution: "loupe@npm:3.1.2"
checksum: 10c0/b13c02e3ddd6a9d5f8bf84133b3242de556512d824dddeea71cce2dbd6579c8f4d672381c4e742d45cf4423d0701765b4a6e5fbc24701def16bc2b40f8daa96a
languageName: node
linkType: hard
"lower-case@npm:^2.0.2":
version: 2.0.2
resolution: "lower-case@npm:2.0.2"
@ -9506,7 +9306,7 @@ __metadata:
languageName: node
linkType: hard
"lru-cache@npm:^10.0.1, lru-cache@npm:^10.2.0":
"lru-cache@npm:10.4.3, lru-cache@npm:^10.0.1, lru-cache@npm:^10.2.0":
version: 10.4.3
resolution: "lru-cache@npm:10.4.3"
checksum: 10c0/ebd04fbca961e6c1d6c0af3799adcc966a1babe798f685bb84e6599266599cd95d94630b10262f5424539bc4640107e8a33aa28585374abf561d30d16f4b39fb
@ -9549,7 +9349,7 @@ __metadata:
languageName: node
linkType: hard
"magic-string@npm:^0.30.12, magic-string@npm:^0.30.3":
"magic-string@npm:^0.30.3":
version: 0.30.17
resolution: "magic-string@npm:0.30.17"
dependencies:
@ -10866,20 +10666,6 @@ __metadata:
languageName: node
linkType: hard
"pathe@npm:^1.1.2":
version: 1.1.2
resolution: "pathe@npm:1.1.2"
checksum: 10c0/64ee0a4e587fb0f208d9777a6c56e4f9050039268faaaaecd50e959ef01bf847b7872785c36483fa5cdcdbdfdb31fef2ff222684d4fc21c330ab60395c681897
languageName: node
linkType: hard
"pathval@npm:^2.0.0":
version: 2.0.0
resolution: "pathval@npm:2.0.0"
checksum: 10c0/602e4ee347fba8a599115af2ccd8179836a63c925c23e04bd056d0674a64b39e3a081b643cc7bc0b84390517df2d800a46fcc5598d42c155fe4977095c2f77c5
languageName: node
linkType: hard
"pg-int8@npm:1.0.1":
version: 1.0.1
resolution: "pg-int8@npm:1.0.1"
@ -11078,7 +10864,7 @@ __metadata:
languageName: node
linkType: hard
"postcss@npm:^8.4.43, postcss@npm:^8.4.47":
"postcss@npm:^8.4.47":
version: 8.4.49
resolution: "postcss@npm:8.4.49"
dependencies:
@ -11597,6 +11383,20 @@ __metadata:
languageName: node
linkType: hard
"redis@npm:^4.7.0":
version: 4.7.0
resolution: "redis@npm:4.7.0"
dependencies:
"@redis/bloom": "npm:1.2.0"
"@redis/client": "npm:1.6.0"
"@redis/graph": "npm:1.1.1"
"@redis/json": "npm:1.0.7"
"@redis/search": "npm:1.2.0"
"@redis/time-series": "npm:1.1.0"
checksum: 10c0/a05632a58adbcaa4566238073cd6d00ed008522d2ef015a31aaef200c184a4eff4fa007c514eda91dda1e1205350b5901d0c7b58824dbfa593feb81a0087bf4d
languageName: node
linkType: hard
"redux@npm:^5.0.1":
version: 5.0.1
resolution: "redux@npm:5.0.1"
@ -11903,78 +11703,6 @@ __metadata:
languageName: node
linkType: hard
"rollup@npm:^4.20.0":
version: 4.30.1
resolution: "rollup@npm:4.30.1"
dependencies:
"@rollup/rollup-android-arm-eabi": "npm:4.30.1"
"@rollup/rollup-android-arm64": "npm:4.30.1"
"@rollup/rollup-darwin-arm64": "npm:4.30.1"
"@rollup/rollup-darwin-x64": "npm:4.30.1"
"@rollup/rollup-freebsd-arm64": "npm:4.30.1"
"@rollup/rollup-freebsd-x64": "npm:4.30.1"
"@rollup/rollup-linux-arm-gnueabihf": "npm:4.30.1"
"@rollup/rollup-linux-arm-musleabihf": "npm:4.30.1"
"@rollup/rollup-linux-arm64-gnu": "npm:4.30.1"
"@rollup/rollup-linux-arm64-musl": "npm:4.30.1"
"@rollup/rollup-linux-loongarch64-gnu": "npm:4.30.1"
"@rollup/rollup-linux-powerpc64le-gnu": "npm:4.30.1"
"@rollup/rollup-linux-riscv64-gnu": "npm:4.30.1"
"@rollup/rollup-linux-s390x-gnu": "npm:4.30.1"
"@rollup/rollup-linux-x64-gnu": "npm:4.30.1"
"@rollup/rollup-linux-x64-musl": "npm:4.30.1"
"@rollup/rollup-win32-arm64-msvc": "npm:4.30.1"
"@rollup/rollup-win32-ia32-msvc": "npm:4.30.1"
"@rollup/rollup-win32-x64-msvc": "npm:4.30.1"
"@types/estree": "npm:1.0.6"
fsevents: "npm:~2.3.2"
dependenciesMeta:
"@rollup/rollup-android-arm-eabi":
optional: true
"@rollup/rollup-android-arm64":
optional: true
"@rollup/rollup-darwin-arm64":
optional: true
"@rollup/rollup-darwin-x64":
optional: true
"@rollup/rollup-freebsd-arm64":
optional: true
"@rollup/rollup-freebsd-x64":
optional: true
"@rollup/rollup-linux-arm-gnueabihf":
optional: true
"@rollup/rollup-linux-arm-musleabihf":
optional: true
"@rollup/rollup-linux-arm64-gnu":
optional: true
"@rollup/rollup-linux-arm64-musl":
optional: true
"@rollup/rollup-linux-loongarch64-gnu":
optional: true
"@rollup/rollup-linux-powerpc64le-gnu":
optional: true
"@rollup/rollup-linux-riscv64-gnu":
optional: true
"@rollup/rollup-linux-s390x-gnu":
optional: true
"@rollup/rollup-linux-x64-gnu":
optional: true
"@rollup/rollup-linux-x64-musl":
optional: true
"@rollup/rollup-win32-arm64-msvc":
optional: true
"@rollup/rollup-win32-ia32-msvc":
optional: true
"@rollup/rollup-win32-x64-msvc":
optional: true
fsevents:
optional: true
bin:
rollup: dist/bin/rollup
checksum: 10c0/a318c57e2ca9741e1503bcd75483949c6e83edd72234a468010a3098a34248f523e44f7ad4fde90dc5c2da56abc1b78ac42a9329e1dbd708682728adbd8df7cc
languageName: node
linkType: hard
"run-parallel@npm:^1.1.9":
version: 1.2.0
resolution: "run-parallel@npm:1.2.0"
@ -12269,13 +11997,6 @@ __metadata:
languageName: node
linkType: hard
"siginfo@npm:^2.0.0":
version: 2.0.0
resolution: "siginfo@npm:2.0.0"
checksum: 10c0/3def8f8e516fbb34cb6ae415b07ccc5d9c018d85b4b8611e3dc6f8be6d1899f693a4382913c9ed51a06babb5201639d76453ab297d1c54a456544acf5c892e34
languageName: node
linkType: hard
"signal-exit@npm:^3.0.3, signal-exit@npm:^3.0.7":
version: 3.0.7
resolution: "signal-exit@npm:3.0.7"
@ -12449,13 +12170,6 @@ __metadata:
languageName: node
linkType: hard
"stackback@npm:0.0.2":
version: 0.0.2
resolution: "stackback@npm:0.0.2"
checksum: 10c0/89a1416668f950236dd5ac9f9a6b2588e1b9b62b1b6ad8dff1bfc5d1a15dbf0aafc9b52d2226d00c28dffff212da464eaeebfc6b7578b9d180cef3e3782c5983
languageName: node
linkType: hard
"stacktrace-parser@npm:^0.1.10":
version: 0.1.10
resolution: "stacktrace-parser@npm:0.1.10"
@ -12465,7 +12179,7 @@ __metadata:
languageName: node
linkType: hard
"std-env@npm:^3.7.0, std-env@npm:^3.8.0":
"std-env@npm:^3.7.0":
version: 3.8.0
resolution: "std-env@npm:3.8.0"
checksum: 10c0/f560a2902fd0fa3d648d7d0acecbd19d664006f7372c1fba197ed4c216b4c9e48db6e2769b5fe1616d42a9333c9f066c5011935035e85c59f45dc4f796272040
@ -12862,6 +12576,7 @@ __metadata:
"@mdx-js/loader": "npm:^3.1.0"
"@mdx-js/react": "npm:^3.1.0"
"@microsoft/eslint-formatter-sarif": "npm:^3.1.0"
"@neshca/cache-handler": "npm:^1.9.0"
"@next/eslint-plugin-next": "npm:15.1.5"
"@next/mdx": "npm:^15.1.5"
"@prisma/client": "npm:^6.2.1"
@ -12919,6 +12634,7 @@ __metadata:
react: "npm:^19.0.0"
react-day-picker: "npm:^9.5.0"
react-dom: "npm:^19.0.0"
redis: "npm:^4.7.0"
sharp: "npm:^0.33.5"
sonner: "npm:^1.7.2"
stripe: "npm:^17.4.0"
@ -12929,8 +12645,6 @@ __metadata:
typescript: "npm:^5.7.3"
unsplash-js: "npm:^7.0.19"
usehooks-ts: "npm:^3.1.0"
vite-tsconfig-paths: "npm:^5.1.4"
vitest: "npm:^2.1.8"
zod: "npm:^3.24.1"
zustand: "npm:^5.0.3"
languageName: unknown
@ -12979,20 +12693,6 @@ __metadata:
languageName: node
linkType: hard
"tinybench@npm:^2.9.0":
version: 2.9.0
resolution: "tinybench@npm:2.9.0"
checksum: 10c0/c3500b0f60d2eb8db65250afe750b66d51623057ee88720b7f064894a6cb7eb93360ca824a60a31ab16dab30c7b1f06efe0795b352e37914a9d4bad86386a20c
languageName: node
linkType: hard
"tinyexec@npm:^0.3.1":
version: 0.3.2
resolution: "tinyexec@npm:0.3.2"
checksum: 10c0/3efbf791a911be0bf0821eab37a3445c2ba07acc1522b1fa84ae1e55f10425076f1290f680286345ed919549ad67527d07281f1c19d584df3b74326909eb1f90
languageName: node
linkType: hard
"tinyglobby@npm:^0.2.5":
version: 0.2.10
resolution: "tinyglobby@npm:0.2.10"
@ -13003,27 +12703,6 @@ __metadata:
languageName: node
linkType: hard
"tinypool@npm:^1.0.1":
version: 1.0.2
resolution: "tinypool@npm:1.0.2"
checksum: 10c0/31ac184c0ff1cf9a074741254fe9ea6de95026749eb2b8ec6fd2b9d8ca94abdccda731f8e102e7f32e72ed3b36d32c6975fd5f5523df3f1b6de6c3d8dfd95e63
languageName: node
linkType: hard
"tinyrainbow@npm:^1.2.0":
version: 1.2.0
resolution: "tinyrainbow@npm:1.2.0"
checksum: 10c0/7f78a4b997e5ba0f5ecb75e7ed786f30bab9063716e7dff24dd84013fb338802e43d176cb21ed12480561f5649a82184cf31efb296601a29d38145b1cdb4c192
languageName: node
linkType: hard
"tinyspy@npm:^3.0.2":
version: 3.0.2
resolution: "tinyspy@npm:3.0.2"
checksum: 10c0/55ffad24e346622b59292e097c2ee30a63919d5acb7ceca87fc0d1c223090089890587b426e20054733f97a58f20af2c349fb7cc193697203868ab7ba00bcea0
languageName: node
linkType: hard
"tmpl@npm:1.0.5":
version: 1.0.5
resolution: "tmpl@npm:1.0.5"
@ -13143,20 +12822,6 @@ __metadata:
languageName: node
linkType: hard
"tsconfck@npm:^3.0.3":
version: 3.1.4
resolution: "tsconfck@npm:3.1.4"
peerDependencies:
typescript: ^5.0.0
peerDependenciesMeta:
typescript:
optional: true
bin:
tsconfck: bin/tsconfck.js
checksum: 10c0/5120e91b3388574b449d57d08f45d05d9966cf4b9d6aa1018652c1fff6d7d37b1ed099b07e6ebf6099aa40b8a16968dd337198c55b7274892849112b942861ed
languageName: node
linkType: hard
"tsconfig-paths@npm:^3.15.0":
version: 3.15.0
resolution: "tsconfig-paths@npm:3.15.0"
@ -13656,130 +13321,6 @@ __metadata:
languageName: node
linkType: hard
"vite-node@npm:2.1.8":
version: 2.1.8
resolution: "vite-node@npm:2.1.8"
dependencies:
cac: "npm:^6.7.14"
debug: "npm:^4.3.7"
es-module-lexer: "npm:^1.5.4"
pathe: "npm:^1.1.2"
vite: "npm:^5.0.0"
bin:
vite-node: vite-node.mjs
checksum: 10c0/cb28027a7425ba29780e216164c07d36a4ff9eb60d83afcad3bc222fd5a5f3e36030071c819edd6d910940f502d49e52f7564743617bc1c5875485b0952c72d5
languageName: node
linkType: hard
"vite-tsconfig-paths@npm:^5.1.4":
version: 5.1.4
resolution: "vite-tsconfig-paths@npm:5.1.4"
dependencies:
debug: "npm:^4.1.1"
globrex: "npm:^0.1.2"
tsconfck: "npm:^3.0.3"
peerDependencies:
vite: "*"
peerDependenciesMeta:
vite:
optional: true
checksum: 10c0/6228f23155ea25d92b1e1702284cf8dc52ad3c683c5ca691edd5a4c82d2913e7326d00708cef1cbfde9bb226261df0e0a12e03ef1d43b6a92d8f02b483ef37e3
languageName: node
linkType: hard
"vite@npm:^5.0.0":
version: 5.4.11
resolution: "vite@npm:5.4.11"
dependencies:
esbuild: "npm:^0.21.3"
fsevents: "npm:~2.3.3"
postcss: "npm:^8.4.43"
rollup: "npm:^4.20.0"
peerDependencies:
"@types/node": ^18.0.0 || >=20.0.0
less: "*"
lightningcss: ^1.21.0
sass: "*"
sass-embedded: "*"
stylus: "*"
sugarss: "*"
terser: ^5.4.0
dependenciesMeta:
fsevents:
optional: true
peerDependenciesMeta:
"@types/node":
optional: true
less:
optional: true
lightningcss:
optional: true
sass:
optional: true
sass-embedded:
optional: true
stylus:
optional: true
sugarss:
optional: true
terser:
optional: true
bin:
vite: bin/vite.js
checksum: 10c0/d536bb7af57dd0eca2a808f95f5ff1d7b7ffb8d86e17c6893087680a0448bd0d15e07475270c8a6de65cb5115592d037130a1dd979dc76bcef8c1dda202a1874
languageName: node
linkType: hard
"vitest@npm:^2.1.8":
version: 2.1.8
resolution: "vitest@npm:2.1.8"
dependencies:
"@vitest/expect": "npm:2.1.8"
"@vitest/mocker": "npm:2.1.8"
"@vitest/pretty-format": "npm:^2.1.8"
"@vitest/runner": "npm:2.1.8"
"@vitest/snapshot": "npm:2.1.8"
"@vitest/spy": "npm:2.1.8"
"@vitest/utils": "npm:2.1.8"
chai: "npm:^5.1.2"
debug: "npm:^4.3.7"
expect-type: "npm:^1.1.0"
magic-string: "npm:^0.30.12"
pathe: "npm:^1.1.2"
std-env: "npm:^3.8.0"
tinybench: "npm:^2.9.0"
tinyexec: "npm:^0.3.1"
tinypool: "npm:^1.0.1"
tinyrainbow: "npm:^1.2.0"
vite: "npm:^5.0.0"
vite-node: "npm:2.1.8"
why-is-node-running: "npm:^2.3.0"
peerDependencies:
"@edge-runtime/vm": "*"
"@types/node": ^18.0.0 || >=20.0.0
"@vitest/browser": 2.1.8
"@vitest/ui": 2.1.8
happy-dom: "*"
jsdom: "*"
peerDependenciesMeta:
"@edge-runtime/vm":
optional: true
"@types/node":
optional: true
"@vitest/browser":
optional: true
"@vitest/ui":
optional: true
happy-dom:
optional: true
jsdom:
optional: true
bin:
vitest: vitest.mjs
checksum: 10c0/e70631bad5662d6c60c5cf836a4baf58b890db6654fef1f608fe6a86aa49a2b9f078aac74b719d4d3c87c5c781968cc73590a7935277b48f3d8b6fb9c5b4d276
languageName: node
linkType: hard
"w3c-xmlserializer@npm:^4.0.0":
version: 4.0.0
resolution: "w3c-xmlserializer@npm:4.0.0"
@ -13951,18 +13492,6 @@ __metadata:
languageName: node
linkType: hard
"why-is-node-running@npm:^2.3.0":
version: 2.3.0
resolution: "why-is-node-running@npm:2.3.0"
dependencies:
siginfo: "npm:^2.0.0"
stackback: "npm:0.0.2"
bin:
why-is-node-running: cli.js
checksum: 10c0/1cde0b01b827d2cf4cb11db962f3958b9175d5d9e7ac7361d1a7b0e2dc6069a263e69118bd974c4f6d0a890ef4eedfe34cf3d5167ec14203dbc9a18620537054
languageName: node
linkType: hard
"word-wrap@npm:^1.2.5":
version: 1.2.5
resolution: "word-wrap@npm:1.2.5"
@ -14059,6 +13588,13 @@ __metadata:
languageName: node
linkType: hard
"yallist@npm:4.0.0, yallist@npm:^4.0.0":
version: 4.0.0
resolution: "yallist@npm:4.0.0"
checksum: 10c0/2286b5e8dbfe22204ab66e2ef5cc9bbb1e55dfc873bbe0d568aa943eb255d131890dfd5bf243637273d31119b870f49c18fcde2c6ffbb7a7a092b870dc90625a
languageName: node
linkType: hard
"yallist@npm:^3.0.2":
version: 3.1.1
resolution: "yallist@npm:3.1.1"
@ -14066,13 +13602,6 @@ __metadata:
languageName: node
linkType: hard
"yallist@npm:^4.0.0":
version: 4.0.0
resolution: "yallist@npm:4.0.0"
checksum: 10c0/2286b5e8dbfe22204ab66e2ef5cc9bbb1e55dfc873bbe0d568aa943eb255d131890dfd5bf243637273d31119b870f49c18fcde2c6ffbb7a7a092b870dc90625a
languageName: node
linkType: hard
"yallist@npm:^5.0.0":
version: 5.0.0
resolution: "yallist@npm:5.0.0"