Files
Jyotisha/frontend/src/lib/feature-flags.ts
T

41 lines
1.3 KiB
TypeScript

import "server-only";
import { queryAdminRows } from "@/lib/admin/database";
type FeatureFlagRow = {
flag_key: string;
enabled: boolean;
rollout_percentage: number;
config: Record<string, unknown>;
};
export type RuntimeFeatureFlag = {
enabled: boolean;
config: Record<string, unknown>;
};
type Cache = { expiresAt: number; flags: Map<string, RuntimeFeatureFlag> };
const state = globalThis as typeof globalThis & { jyotishaFeatureFlagCache?: Cache };
const cacheTtlMs = 15_000;
export async function loadRuntimeFeatureFlags(keys: readonly string[]) {
const cached = state.jyotishaFeatureFlagCache;
if (cached && cached.expiresAt > Date.now() && keys.every((key) => cached.flags.has(key))) return cached.flags;
const rows = await queryAdminRows<FeatureFlagRow>(`
select flag_key,enabled,rollout_percentage,config
from public.feature_flags
where status='published' and flag_key=any($1::text[])
`, [keys]);
const flags = new Map<string, RuntimeFeatureFlag>();
for (const key of keys) flags.set(key, { enabled: false, config: {} });
for (const row of rows) {
flags.set(row.flag_key, {
enabled: row.enabled && row.rollout_percentage === 100,
config: row.config,
});
}
state.jyotishaFeatureFlagCache = { expiresAt: Date.now() + cacheTtlMs, flags };
return flags;
}