Monorepo for wisp.place. A static site hosting service built on top of the AT Protocol. wisp.place

have main-app use new sites-cache table

+98 -3
+2 -2
apps/main-app/public/editor/editor.tsx
··· 520 520 <span> 521 521 Built by{' '} 522 522 <a 523 - href="https://bsky.app/profile/nekomimi.pet" 523 + href="https://bsky.app/profile/null.namespaces.me" 524 524 target="_blank" 525 525 rel="noopener noreferrer" 526 526 className="text-accent hover:text-accent/80 transition-colors" 527 527 > 528 - @nekomimi.pet 528 + @null.namespaces.me 529 529 </a> 530 530 </span> 531 531 <span>
+18
apps/main-app/src/lib/db.ts
··· 512 512 } 513 513 }; 514 514 515 + export const upsertSiteCache = async (did: string, rkey: string, recordCid: string, fileCids: Record<string, string> = {}) => { 516 + try { 517 + await db` 518 + INSERT INTO site_cache (did, rkey, record_cid, file_cids, cached_at, updated_at) 519 + VALUES (${did}, ${rkey}, ${recordCid}, ${JSON.stringify(fileCids)}, EXTRACT(EPOCH FROM NOW()), EXTRACT(EPOCH FROM NOW())) 520 + ON CONFLICT (did, rkey) 521 + DO UPDATE SET 522 + record_cid = EXCLUDED.record_cid, 523 + file_cids = EXCLUDED.file_cids, 524 + updated_at = EXTRACT(EPOCH FROM NOW()) 525 + `; 526 + return { success: true }; 527 + } catch (err) { 528 + console.error('Failed to upsert site cache', err); 529 + return { success: false, error: err }; 530 + } 531 + }; 532 + 515 533 // Get all domains (wisp + custom) mapped to a specific site 516 534 export const getDomainsBySite = async (did: string, rkey: string) => { 517 535 const domains: Array<{
+78 -1
apps/main-app/src/routes/wisp.ts
··· 22 22 extractSubfsUris 23 23 } from '@wispplace/atproto-utils' 24 24 import { createManifest } from '@wispplace/fs-utils' 25 - import { upsertSite } from '../lib/db' 25 + import { upsertSite, getDomainByDid, updateWispDomainSite, getWispDomainSite, upsertSiteCache } from '../lib/db' 26 26 import { createLogger } from '@wispplace/observability' 27 27 // import { validateRecord, type Directory } from '@wispplace/lexicons/types/place/wisp/fs' 28 28 import { type Directory } from '@wispplace/lexicons/types/place/wisp/fs' ··· 311 311 }); 312 312 313 313 await upsertSite(did, rkey, siteName); 314 + 315 + // Cache the empty site for the hosting service 316 + try { 317 + await upsertSiteCache(did, rkey, record.data.cid, {}); 318 + } catch (err) { 319 + // Don't fail the upload if caching fails 320 + logger.warn('Failed to cache site', err); 321 + } 322 + 323 + // Auto-map claimed domain to this site if user has a claimed domain with no rkey 324 + try { 325 + const existingDomain = await getDomainByDid(did); 326 + if (existingDomain) { 327 + const currentSiteMapping = await getWispDomainSite(did); 328 + if (!currentSiteMapping) { 329 + // Domain is claimed but not mapped to any site, map it to this new site 330 + await updateWispDomainSite(existingDomain, rkey); 331 + logger.info(`Auto-mapped domain ${existingDomain} to new site ${siteName}`); 332 + } 333 + } 334 + } catch (err) { 335 + // Don't fail the upload if domain mapping fails 336 + logger.warn('Failed to auto-map domain to new site', err); 337 + } 314 338 315 339 completeUploadJob(jobId, { 316 340 success: true, ··· 854 878 // Store site in database cache 855 879 await upsertSite(did, rkey, siteName); 856 880 881 + // Cache the site files for the hosting service 882 + try { 883 + const fileCids: Record<string, string> = {}; 884 + for (const blob of uploadedBlobs) { 885 + const normalizedPath = blob.filePath.replace(/^[^\/]*\//, ''); 886 + fileCids[normalizedPath] = blob.result.hash; 887 + } 888 + await upsertSiteCache(did, rkey, record.data.cid, fileCids); 889 + } catch (err) { 890 + // Don't fail the upload if caching fails 891 + logger.warn('Failed to cache site files', err); 892 + } 893 + 894 + // Auto-map claimed domain to this site if user has a claimed domain with no rkey 895 + try { 896 + const existingDomain = await getDomainByDid(did); 897 + if (existingDomain) { 898 + const currentSiteMapping = await getWispDomainSite(did); 899 + if (!currentSiteMapping) { 900 + // Domain is claimed but not mapped to any site, map it to this new site 901 + await updateWispDomainSite(existingDomain, rkey); 902 + logger.info(`Auto-mapped domain ${existingDomain} to new site ${siteName}`); 903 + } 904 + } 905 + } catch (err) { 906 + // Don't fail the upload if domain mapping fails 907 + logger.warn('Failed to auto-map domain to new site', err); 908 + } 909 + 857 910 // Clean up old subfs records if we had any 858 911 if (oldSubfsUris.length > 0) { 859 912 console.log(`Cleaning up ${oldSubfsUris.length} old subfs records...`); ··· 1076 1129 }); 1077 1130 1078 1131 await upsertSite(auth.did, rkey, siteName); 1132 + 1133 + // Cache the empty site for the hosting service 1134 + try { 1135 + await upsertSiteCache(auth.did, rkey, record.data.cid, {}); 1136 + } catch (err) { 1137 + // Don't fail the upload if caching fails 1138 + logger.warn('Failed to cache site', err); 1139 + } 1140 + 1141 + // Auto-map claimed domain to this site if user has a claimed domain with no rkey 1142 + try { 1143 + const existingDomain = await getDomainByDid(auth.did); 1144 + if (existingDomain) { 1145 + const currentSiteMapping = await getWispDomainSite(auth.did); 1146 + if (!currentSiteMapping) { 1147 + // Domain is claimed but not mapped to any site, map it to this new site 1148 + await updateWispDomainSite(existingDomain, rkey); 1149 + logger.info(`Auto-mapped domain ${existingDomain} to new site ${siteName}`); 1150 + } 1151 + } 1152 + } catch (err) { 1153 + // Don't fail the upload if domain mapping fails 1154 + logger.warn('Failed to auto-map domain to new site', err); 1155 + } 1079 1156 1080 1157 return { 1081 1158 success: true,