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

CLI v0.4.1 release

nekomimi.pet 0172a31f 0bbe78d5

verified
Changed files
+53 -28
apps
hosting-service
src
main-app
public
editor
tabs
src
binaries
docs
src
content
docs
+4 -3
README.md
··· 22 23 ## Architecture 24 25 - - **`/src`** - Main backend (OAuth, site management, custom domains) 26 - - **`/hosting-service`** - Microservice that serves cached sites from disk 27 - **`/cli`** - Rust CLI for direct PDS uploads 28 - - **`/public`** - React frontend 29 30 ### How it works 31
··· 22 23 ## Architecture 24 25 + - **`/apps/main-app`** - Main backend (OAuth, site management, custom domains) 26 + - **`/apps/hosting-service`** - Microservice that serves cached sites from disk 27 - **`/cli`** - Rust CLI for direct PDS uploads 28 + - **`/apps/main-app/public`** - React frontend 29 + - **`/packages`** - Shared packages 30 31 ### How it works 32
+22
apps/hosting-service/src/lib/firehose.ts
··· 20 private idResolver: IdResolver 21 private isShuttingDown = false 22 private lastEventTime = Date.now() 23 24 constructor( 25 private logger?: (msg: string, data?: Record<string, unknown>) => void 26 ) { 27 this.idResolver = new IdResolver() 28 } 29 30 private log(msg: string, data?: Record<string, unknown>) { ··· 32 log(`[FirehoseWorker] ${msg}`, data || {}) 33 } 34 35 start() { 36 this.log('Starting firehose worker') 37 this.connect() ··· 40 stop() { 41 this.log('Stopping firehose worker') 42 this.isShuttingDown = true 43 44 if (this.firehose) { 45 this.firehose.destroy()
··· 20 private idResolver: IdResolver 21 private isShuttingDown = false 22 private lastEventTime = Date.now() 23 + private cacheCleanupInterval: NodeJS.Timeout | null = null 24 25 constructor( 26 private logger?: (msg: string, data?: Record<string, unknown>) => void 27 ) { 28 this.idResolver = new IdResolver() 29 + this.startCacheCleanup() 30 } 31 32 private log(msg: string, data?: Record<string, unknown>) { ··· 34 log(`[FirehoseWorker] ${msg}`, data || {}) 35 } 36 37 + private startCacheCleanup() { 38 + // Clear IdResolver cache every hour to prevent unbounded memory growth 39 + // The IdResolver has an internal cache that never expires and can cause heap exhaustion 40 + this.cacheCleanupInterval = setInterval(() => { 41 + if (this.isShuttingDown) return 42 + 43 + this.log('Clearing IdResolver cache to prevent memory leak') 44 + 45 + // Recreate the IdResolver to clear its internal cache 46 + this.idResolver = new IdResolver() 47 + 48 + this.log('IdResolver cache cleared') 49 + }, 60 * 60 * 1000) // Every hour 50 + } 51 + 52 start() { 53 this.log('Starting firehose worker') 54 this.connect() ··· 57 stop() { 58 this.log('Stopping firehose worker') 59 this.isShuttingDown = true 60 + 61 + if (this.cacheCleanupInterval) { 62 + clearInterval(this.cacheCleanupInterval) 63 + this.cacheCleanupInterval = null 64 + } 65 66 if (this.firehose) { 67 this.firehose.destroy()
+6 -6
apps/main-app/public/editor/tabs/CLITab.tsx
··· 17 <div className="flex items-center gap-2 mb-2"> 18 <CardTitle>Wisp CLI Tool</CardTitle> 19 <Badge variant="secondary" className="text-xs"> 20 - v0.4.0 21 </Badge> 22 <Badge variant="outline" className="text-xs"> 23 Alpha ··· 55 </div> 56 57 <div className="space-y-3"> 58 - <h3 className="text-sm font-semibold">Download v0.4.0</h3> 59 <div className="grid gap-2"> 60 <div className="p-3 bg-muted/50 hover:bg-muted rounded-lg transition-colors border border-border"> 61 <a ··· 71 </a> 72 <div className="text-xs text-muted-foreground"> 73 <span className="font-mono"> 74 - SHA-1: 2b5c1d6d0e21f9d764dd66ef869bfcd348e8a111 75 </span> 76 </div> 77 </div> ··· 87 </a> 88 <div className="text-xs text-muted-foreground"> 89 <span className="font-mono"> 90 - SHA-1: 68d4a3831c07d2f32fdde8d3e809af1ab79e804e 91 </span> 92 </div> 93 </div> ··· 103 </a> 104 <div className="text-xs text-muted-foreground"> 105 <span className="font-mono"> 106 - SHA-1: 86e89f592b0ec53239c082f502cbe7a47ed8bbec 107 </span> 108 </div> 109 </div> ··· 119 </a> 120 <div className="text-xs text-muted-foreground"> 121 <span className="font-mono"> 122 - SHA-1: 227b735911ad260cff5af3ca3beefa4e1e3956a8 123 </span> 124 </div> 125 </div>
··· 17 <div className="flex items-center gap-2 mb-2"> 18 <CardTitle>Wisp CLI Tool</CardTitle> 19 <Badge variant="secondary" className="text-xs"> 20 + v0.4.1 21 </Badge> 22 <Badge variant="outline" className="text-xs"> 23 Alpha ··· 55 </div> 56 57 <div className="space-y-3"> 58 + <h3 className="text-sm font-semibold">Download v0.4.1</h3> 59 <div className="grid gap-2"> 60 <div className="p-3 bg-muted/50 hover:bg-muted rounded-lg transition-colors border border-border"> 61 <a ··· 71 </a> 72 <div className="text-xs text-muted-foreground"> 73 <span className="font-mono"> 74 + SHA-1: 69de880e160a2f26e3c26b7c28030457913754dc 75 </span> 76 </div> 77 </div> ··· 87 </a> 88 <div className="text-xs text-muted-foreground"> 89 <span className="font-mono"> 90 + SHA-1: 026189f2c10077a2be4705102e169e66cb207f84 91 </span> 92 </div> 93 </div> ··· 103 </a> 104 <div className="text-xs text-muted-foreground"> 105 <span className="font-mono"> 106 + SHA-1: 4777cff07558906717402484a3313359880eae96 107 </span> 108 </div> 109 </div> ··· 119 </a> 120 <div className="text-xs text-muted-foreground"> 121 <span className="font-mono"> 122 + SHA-1: d6bc789d7fd7c787e5520eb476cee70c97ccb3ce 123 </span> 124 </div> 125 </div>
+9 -7
apps/main-app/src/index.ts
··· 148 } 149 }) 150 .get('/api/screenshots', async () => { 151 - const { Glob } = await import('bun') 152 - const glob = new Glob('*.png') 153 - 154 - // Convert async iterator to array using Array.fromAsync 155 - const files = glob.scan('./apps/main-app/public/screenshots') 156 - const screenshots = await Array.fromAsync(files) 157 158 - return { screenshots } 159 }) 160 .get('/api/admin/test', () => { 161 return { message: 'Admin routes test works!' }
··· 148 } 149 }) 150 .get('/api/screenshots', async () => { 151 + const fs = await import('fs/promises') 152 153 + try { 154 + const screenshotsDir = './apps/main-app/public/screenshots' 155 + const files = await fs.readdir(screenshotsDir) 156 + const screenshots = files.filter(file => file.endsWith('.png')) 157 + return { screenshots } 158 + } catch (error) { 159 + return { screenshots: [] } 160 + } 161 }) 162 .get('/api/admin/test', () => { 163 return { message: 'Admin routes test works!' }
+6 -6
binaries/index.html
··· 234 </head> 235 <body> 236 <div class="container"> 237 - <h1>Wisp CLI <span style="font-size: 1.5rem; color: var(--demo-text-secondary);">v0.4.0</span></h1> 238 <p class="subtitle">Deploy static sites to the AT Protocol</p> 239 240 <div class="description"> ··· 256 </div> 257 258 <div class="downloads"> 259 - <h2>Download v0.4.0</h2> 260 <a href="https://sites.wisp.place/nekomimi.pet/wisp-cli-binaries/wisp-cli-aarch64-darwin" class="download-link" download> 261 <span class="platform">macOS (Apple Silicon):</span> wisp-cli-aarch64-darwin 262 </a> ··· 271 </a> 272 273 <h3 style="margin-top: 1.5rem; margin-bottom: 0.5rem;">SHA-1 Checksums</h3> 274 - <pre style="font-size: 0.75rem; padding: 1rem;"><code class="language-bash">2b5c1d6d0e21f9d764dd66ef869bfcd348e8a111 wisp-cli-aarch64-darwin 275 - 68d4a3831c07d2f32fdde8d3e809af1ab79e804e wisp-cli-aarch64-linux 276 - 86e89f592b0ec53239c082f502cbe7a47ed8bbec wisp-cli-x86_64-linux 277 - 227b735911ad260cff5af3ca3beefa4e1e3956a8 wisp-cli-x86_64-windows.exe</code></pre> 278 </div> 279 280 <div class="cicd-section">
··· 234 </head> 235 <body> 236 <div class="container"> 237 + <h1>Wisp CLI <span style="font-size: 1.5rem; color: var(--demo-text-secondary);">v0.4.1</span></h1> 238 <p class="subtitle">Deploy static sites to the AT Protocol</p> 239 240 <div class="description"> ··· 256 </div> 257 258 <div class="downloads"> 259 + <h2>Download v0.4.1</h2> 260 <a href="https://sites.wisp.place/nekomimi.pet/wisp-cli-binaries/wisp-cli-aarch64-darwin" class="download-link" download> 261 <span class="platform">macOS (Apple Silicon):</span> wisp-cli-aarch64-darwin 262 </a> ··· 271 </a> 272 273 <h3 style="margin-top: 1.5rem; margin-bottom: 0.5rem;">SHA-1 Checksums</h3> 274 + <pre style="font-size: 0.75rem; padding: 1rem;"><code class="language-bash">69de880e160a2f26e3c26b7c28030457913754dc wisp-cli-aarch64-darwin 275 + 026189f2c10077a2be4705102e169e66cb207f84 wisp-cli-aarch64-linux 276 + 4777cff07558906717402484a3313359880eae96 wisp-cli-x86_64-linux 277 + d6bc789d7fd7c787e5520eb476cee70c97ccb3ce wisp-cli-x86_64-windows.exe</code></pre> 278 </div> 279 280 <div class="cicd-section">
binaries/wisp-cli-aarch64-darwin

This is a binary file and will not be displayed.

binaries/wisp-cli-aarch64-linux

This is a binary file and will not be displayed.

binaries/wisp-cli-x86_64-linux

This is a binary file and will not be displayed.

binaries/wisp-cli-x86_64-windows.exe

This is a binary file and will not be displayed.

+6 -6
docs/src/content/docs/cli.md
··· 1 --- 2 - title: Wisp CLI 0.4.0 (alpha) 3 description: Command-line tool for deploying static sites to the AT Protocol 4 --- 5 ··· 19 20 <div class="downloads"> 21 22 - <h2>Download v0.4.0</h2> 23 24 <a href="https://sites.wisp.place/nekomimi.pet/wisp-cli-binaries/wisp-cli-aarch64-darwin" class="download-link" download=""> 25 ··· 48 <h3 style="margin-top: 1.5rem; margin-bottom: 0.5rem;">SHA-1 Checksums</h3> 49 50 <pre style="font-size: 0.75rem; padding: 1rem;" class="language-bash" tabindex="0"><code class="language-bash"> 51 - 2b5c1d6d0e21f9d764dd66ef869bfcd348e8a111 wisp-cli-aarch64-darwin 52 53 - 68d4a3831c07d2f32fdde8d3e809af1ab79e804e wisp-cli-aarch64-linux 54 55 - 86e89f592b0ec53239c082f502cbe7a47ed8bbec wisp-cli-x86_64-linux 56 57 - 227b735911ad260cff5af3ca3beefa4e1e3956a8 wisp-cli-x86_64-windows.exe 58 </code></pre> 59 60 </div>
··· 1 --- 2 + title: Wisp CLI 0.4.1 (alpha) 3 description: Command-line tool for deploying static sites to the AT Protocol 4 --- 5 ··· 19 20 <div class="downloads"> 21 22 + <h2>Download v0.4.1</h2> 23 24 <a href="https://sites.wisp.place/nekomimi.pet/wisp-cli-binaries/wisp-cli-aarch64-darwin" class="download-link" download=""> 25 ··· 48 <h3 style="margin-top: 1.5rem; margin-bottom: 0.5rem;">SHA-1 Checksums</h3> 49 50 <pre style="font-size: 0.75rem; padding: 1rem;" class="language-bash" tabindex="0"><code class="language-bash"> 51 + 69de880e160a2f26e3c26b7c28030457913754dc wisp-cli-aarch64-darwin 52 53 + 026189f2c10077a2be4705102e169e66cb207f84 wisp-cli-aarch64-linux 54 55 + 4777cff07558906717402484a3313359880eae96 wisp-cli-x86_64-linux 56 57 + d6bc789d7fd7c787e5520eb476cee70c97ccb3ce wisp-cli-x86_64-windows.exe 58 </code></pre> 59 60 </div>