Files
the_order/packages/database/src/query-cache.js
defiQUG 92cc41d26d Add Legal Office seal and complete Azure CDN deployment
- Add Legal Office of the Master seal (SVG design with Maltese Cross, scales of justice, legal scroll)
- Create legal-office-manifest-template.json for Legal Office credentials
- Update SEAL_MAPPING.md and DESIGN_GUIDE.md with Legal Office seal documentation
- Complete Azure CDN infrastructure deployment:
  - Resource group, storage account, and container created
  - 17 PNG seal files uploaded to Azure Blob Storage
  - All manifest templates updated with Azure URLs
  - Configuration files generated (azure-cdn-config.env)
- Add comprehensive Azure CDN setup scripts and documentation
- Fix manifest URL generation to prevent double slashes
- Verify all seals accessible via HTTPS
2025-11-12 22:03:42 -08:00

93 lines
3.0 KiB
JavaScript

/**
* Database query caching with Redis
* Implements query result caching with automatic invalidation
*
* Note: This module uses optional dynamic import for @the-order/cache
* to avoid requiring it as a direct dependency. If cache is not available,
* queries will execute directly without caching.
*/
import { query } from './client';
// Cache client instance (lazy-loaded via dynamic import)
let cacheClientPromise = null;
/**
* Get cache client (lazy-loaded via dynamic import)
* Returns null if cache module is not available
*/
async function getCacheClient() {
if (cacheClientPromise === null) {
cacheClientPromise = (async () => {
try {
// Use dynamic import with a string literal that TypeScript can't resolve at compile time
// This is done by constructing the import path dynamically
const cacheModulePath = '@the-order/cache';
// eslint-disable-next-line @typescript-eslint/no-implied-eval
const importFunc = new Function('specifier', 'return import(specifier)');
const cacheModule = await importFunc(cacheModulePath);
return cacheModule.getCacheClient();
}
catch {
// Cache module not available - caching will be disabled
return null;
}
})();
}
return cacheClientPromise;
}
/**
* Execute a query with caching
*/
export async function cachedQuery(sql, params, options = {}) {
const { ttl = 3600, keyPrefix = 'db:query:', enabled = true } = options;
if (!enabled) {
return query(sql, params);
}
const cache = await getCacheClient();
if (!cache) {
// Cache not available - execute query directly
return query(sql, params);
}
const cacheKey = `${keyPrefix}${sql}:${JSON.stringify(params || [])}`;
// Try to get from cache
const cached = await cache.get(cacheKey);
if (cached) {
return cached;
}
// Execute query
const result = await query(sql, params);
// Cache result
await cache.set(cacheKey, result, ttl);
return result;
}
/**
* Invalidate cache for a pattern
*/
export async function invalidateCache(pattern) {
const cache = await getCacheClient();
if (!cache) {
return 0;
}
return cache.invalidate(`db:query:${pattern}*`);
}
/**
* Invalidate cache for a specific query
*/
export async function invalidateQueryCache(sql, params) {
const cache = await getCacheClient();
if (!cache) {
return;
}
const cacheKey = `db:query:${sql}:${JSON.stringify(params || [])}`;
await cache.delete(cacheKey);
}
/**
* Cache decorator for database functions
* Note: This is a simplified implementation. In production, you'd need to
* extract SQL and params from the function or pass them as metadata.
*/
export function cached(fn) {
return (async (...args) => {
const result = await fn(...args);
return result;
});
}
//# sourceMappingURL=query-cache.js.map