55 lines
1.8 KiB
TypeScript
55 lines
1.8 KiB
TypeScript
import { createSharedStore, type SharedStore } from "@hivegrid/shared-store";
|
|
|
|
/**
|
|
* Singleton SharedStore for the web process. Tenant-scoped caches,
|
|
* cross-replica rate limits, and MFA challenge state migrated as part
|
|
* of task #38 all use this instance so a single Redis connection is
|
|
* reused across the web lifetime.
|
|
*/
|
|
let cachedStore: SharedStore | null = null;
|
|
let crossAppCacheStore: SharedStore | null = null;
|
|
let factory: () => SharedStore = () => createSharedStore({ namespace: "web", redisUrl: process.env.REDIS_URL });
|
|
|
|
export function getSharedStore(): SharedStore {
|
|
if (cachedStore === null) {
|
|
cachedStore = factory();
|
|
}
|
|
return cachedStore;
|
|
}
|
|
|
|
/** Shared cache-invalidation namespace used by both the API and web apps. */
|
|
export function getCrossAppCacheStore(): SharedStore {
|
|
if (crossAppCacheStore === null) {
|
|
crossAppCacheStore = createSharedStore({ namespace: "cross-app-cache", adapter: getSharedStore().adapter });
|
|
}
|
|
return crossAppCacheStore;
|
|
}
|
|
|
|
/** Close the singleton adapter for short-lived processes such as DB seeding. */
|
|
export async function closeSharedStores(): Promise<void> {
|
|
const stores = [cachedStore, crossAppCacheStore].filter((store): store is SharedStore => store !== null);
|
|
cachedStore = null;
|
|
crossAppCacheStore = null;
|
|
|
|
const seenAdapters = new Set<SharedStore["adapter"]>();
|
|
await Promise.all(
|
|
stores.map(async (store) => {
|
|
if (seenAdapters.has(store.adapter)) return;
|
|
seenAdapters.add(store.adapter);
|
|
await store.close();
|
|
}),
|
|
);
|
|
}
|
|
|
|
export function __setSharedStoreFactoryForTests(next: () => SharedStore): void {
|
|
factory = next;
|
|
cachedStore = null;
|
|
crossAppCacheStore = null;
|
|
}
|
|
|
|
export function __resetSharedStoreForTests(): void {
|
|
factory = () => createSharedStore({ namespace: "web", redisUrl: process.env.REDIS_URL });
|
|
cachedStore = null;
|
|
crossAppCacheStore = null;
|
|
}
|