Monorepo for wisp.place. A static site hosting service built on top of the AT Protocol.
wisp.place
1/**
2 * Site caching management utilities
3 */
4
5import { createLogger } from '@wisp/observability';
6import { fetchSiteRecord, getPdsForDid, downloadAndCacheSite, isCached } from './utils';
7import { markSiteAsBeingCached, unmarkSiteAsBeingCached } from './cache';
8import type { RedirectRule } from './redirects';
9
10const logger = createLogger('hosting-service');
11
12// Cache for redirect rules (per site)
13const redirectRulesCache = new Map<string, RedirectRule[]>();
14
15/**
16 * Clear redirect rules cache for a specific site
17 * Should be called when a site is updated/recached
18 */
19export function clearRedirectRulesCache(did: string, rkey: string) {
20 const cacheKey = `${did}:${rkey}`;
21 redirectRulesCache.delete(cacheKey);
22}
23
24/**
25 * Get redirect rules from cache
26 */
27export function getRedirectRulesFromCache(did: string, rkey: string): RedirectRule[] | undefined {
28 const cacheKey = `${did}:${rkey}`;
29 return redirectRulesCache.get(cacheKey);
30}
31
32/**
33 * Set redirect rules in cache
34 */
35export function setRedirectRulesInCache(did: string, rkey: string, rules: RedirectRule[]) {
36 const cacheKey = `${did}:${rkey}`;
37 redirectRulesCache.set(cacheKey, rules);
38}
39
40/**
41 * Helper to ensure site is cached
42 * Returns true if site is successfully cached, false otherwise
43 */
44export async function ensureSiteCached(did: string, rkey: string): Promise<boolean> {
45 if (isCached(did, rkey)) {
46 return true;
47 }
48
49 // Fetch and cache the site
50 const siteData = await fetchSiteRecord(did, rkey);
51 if (!siteData) {
52 logger.error('Site record not found', null, { did, rkey });
53 return false;
54 }
55
56 const pdsEndpoint = await getPdsForDid(did);
57 if (!pdsEndpoint) {
58 logger.error('PDS not found for DID', null, { did });
59 return false;
60 }
61
62 // Mark site as being cached to prevent serving stale content during update
63 markSiteAsBeingCached(did, rkey);
64
65 try {
66 await downloadAndCacheSite(did, rkey, siteData.record, pdsEndpoint, siteData.cid);
67 // Clear redirect rules cache since the site was updated
68 clearRedirectRulesCache(did, rkey);
69 logger.info('Site cached successfully', { did, rkey });
70 return true;
71 } catch (err) {
72 logger.error('Failed to cache site', err, { did, rkey });
73 return false;
74 } finally {
75 // Always unmark, even if caching fails
76 unmarkSiteAsBeingCached(did, rkey);
77 }
78}
79