52 lines
1.4 KiB
TypeScript
52 lines
1.4 KiB
TypeScript
// app/lib/settings.server.ts
|
|
import { PrismaClient } from '@prisma/client';
|
|
import EventEmitter from 'events';
|
|
|
|
const prisma = new PrismaClient();
|
|
|
|
type JSONValue = any;
|
|
|
|
class SettingsService extends EventEmitter {
|
|
private cache: Map<string, JSONValue> = new Map();
|
|
private initialized = false;
|
|
|
|
async init() {
|
|
if (this.initialized) return;
|
|
const rows = await prisma.appSetting.findMany();
|
|
rows.forEach(r => {
|
|
try {
|
|
this.cache.set(r.key, JSON.parse(r.value));
|
|
} catch (e) {
|
|
// fall back to raw string if parse fails
|
|
this.cache.set(r.key, r.value);
|
|
}
|
|
});
|
|
this.initialized = true;
|
|
}
|
|
|
|
async get(key: string) {
|
|
if (!this.initialized) await this.init();
|
|
return this.cache.has(key) ? this.cache.get(key) : null;
|
|
}
|
|
|
|
async set(key: string, value: JSONValue, updatedBy?: string) {
|
|
if (!this.initialized) await this.init();
|
|
const valueStr = typeof value === 'string' ? value : JSON.stringify(value);
|
|
await prisma.appSetting.upsert({
|
|
where: { key },
|
|
update: { value: valueStr, updatedBy },
|
|
create: { key, value: valueStr, updatedBy },
|
|
});
|
|
this.cache.set(key, value);
|
|
this.emit('update', { key, value });
|
|
return { key, value };
|
|
}
|
|
|
|
subscribe(fn: (payload: { key: string; value: any }) => void) {
|
|
this.on('update', fn);
|
|
return () => this.off('update', fn);
|
|
}
|
|
}
|
|
|
|
export const settingsService = new SettingsService();
|