Monorepo for wisp.place. A static site hosting service built on top of the AT Protocol. wisp.place
1import app from './server'; 2import { serve } from '@hono/node-server'; 3import { FirehoseWorker } from './lib/firehose'; 4import { logger } from './lib/observability'; 5import { mkdirSync, existsSync } from 'fs'; 6import { backfillCache } from './lib/backfill'; 7import { startDomainCacheCleanup, stopDomainCacheCleanup, setCacheOnlyMode } from './lib/db'; 8 9const PORT = process.env.PORT ? parseInt(process.env.PORT) : 3001; 10const CACHE_DIR = process.env.CACHE_DIR || './cache/sites'; 11 12// Parse CLI arguments 13const args = process.argv.slice(2); 14const hasBackfillFlag = args.includes('--backfill'); 15const backfillOnStartup = hasBackfillFlag || process.env.BACKFILL_ON_STARTUP === 'true'; 16 17// Cache-only mode: service will only cache files locally, no DB writes 18const hasCacheOnlyFlag = args.includes('--cache-only'); 19export const CACHE_ONLY_MODE = hasCacheOnlyFlag || process.env.CACHE_ONLY_MODE === 'true'; 20 21// Configure cache-only mode in database module 22if (CACHE_ONLY_MODE) { 23 setCacheOnlyMode(true); 24} 25 26// Ensure cache directory exists 27if (!existsSync(CACHE_DIR)) { 28 mkdirSync(CACHE_DIR, { recursive: true }); 29 console.log('Created cache directory:', CACHE_DIR); 30} 31 32// Start domain cache cleanup 33startDomainCacheCleanup(); 34 35// Start firehose worker with observability logger 36const firehose = new FirehoseWorker((msg, data) => { 37 logger.info(msg, data); 38}); 39 40firehose.start(); 41 42// Run backfill if requested 43if (backfillOnStartup) { 44 console.log('🔄 Backfill requested, starting cache backfill...'); 45 backfillCache({ 46 skipExisting: true, 47 concurrency: 3, 48 }).then((stats) => { 49 console.log('✅ Cache backfill completed'); 50 }).catch((err) => { 51 console.error('❌ Cache backfill error:', err); 52 }); 53} 54 55// Add health check endpoint 56app.get('/health', (c) => { 57 const firehoseHealth = firehose.getHealth(); 58 return c.json({ 59 status: 'ok', 60 firehose: firehoseHealth, 61 }); 62}); 63 64// Start HTTP server with Node.js adapter 65const server = serve({ 66 fetch: app.fetch, 67 port: PORT, 68}); 69 70console.log(` 71Wisp Hosting Service 72 73Server: http://localhost:${PORT} 74Health: http://localhost:${PORT}/health 75Cache: ${CACHE_DIR} 76Firehose: Connected to Firehose 77Cache-Only: ${CACHE_ONLY_MODE ? 'ENABLED (no DB writes)' : 'DISABLED'} 78`); 79 80// Graceful shutdown 81process.on('SIGINT', async () => { 82 console.log('\n🛑 Shutting down...'); 83 firehose.stop(); 84 stopDomainCacheCleanup(); 85 server.close(); 86 process.exit(0); 87}); 88 89process.on('SIGTERM', async () => { 90 console.log('\n🛑 Shutting down...'); 91 firehose.stop(); 92 stopDomainCacheCleanup(); 93 server.close(); 94 process.exit(0); 95});