packages/db-main-prisma/src/prisma-manager.ts
/**
* Convenience singleton to deal with fast-refresh
* and connection limits in development mode.
*/
import type {
PrismaDbMain as Prisma,
PrismaClientDbMain as PrismaClient,
} from './index';
export type PrismaClientOptions = Prisma.PrismaClientOptions;
declare let global: {
// eslint-disable-next-line @typescript-eslint/naming-convention
__PRISMA_INSTANCES__: Record<string, PrismaClient> | undefined;
};
export class PrismaManager {
private static instances?: Record<string, PrismaClient>;
private constructor() {}
/**
* Create and maintain a prismaClient instance that avoids issues with
* db connections limit exhaustion in dev mode.
*
* In dev mode the prisma instance is kept unique by using a `global` reference
* preventing issues with Fast-Refresh / Hot-Module-Replacement (HMR) strategies
*
* @see {@link https://pris.ly/d/help/next-js-best-practices|Prisma NextJs Best Practices}
*/
static getDevSafeInstance(
instanceKey: string,
prismaClientFactory: () => PrismaClient
): PrismaClient {
if (process.env.NODE_ENV === 'production') {
if (!PrismaManager.instances?.[instanceKey]) {
PrismaManager.instances ??= {};
PrismaManager.instances[instanceKey] = prismaClientFactory();
}
return PrismaManager.instances[instanceKey]!;
} else {
// PrismaClient is attached to the `global` object in development to prevent
// exhausting your database connection limit.
if (!global.__PRISMA_INSTANCES__?.[instanceKey]) {
global.__PRISMA_INSTANCES__ ??= {};
global.__PRISMA_INSTANCES__[instanceKey] = prismaClientFactory();
console.debug(
'[PrismaFactory.createDevSafeInstance]: Dev instance created and preserved globally.'
);
}
return global.__PRISMA_INSTANCES__[instanceKey]!;
}
}
}