the statusphere demo reworked into a vite/react app in a monorepo

explicit exit, fix error in ingestor

Changed files
+8 -2
packages
appview
src
+2 -1
packages/appview/src/index.ts
··· 120 120 async close() { 121 121 this.ctx.logger.info('sigint received, shutting down') 122 122 await this.ctx.ingester.destroy() 123 - return new Promise<void>((resolve) => { 123 + await new Promise<void>((resolve) => { 124 124 this.server.close(() => { 125 125 this.ctx.logger.info('server closed') 126 126 resolve() ··· 135 135 const onCloseSignal = async () => { 136 136 setTimeout(() => process.exit(1), 10000).unref() // Force shutdown after 10s 137 137 await server.close() 138 + process.exit(0) 138 139 } 139 140 140 141 process.on('SIGINT', onCloseSignal)
+6 -1
packages/appview/src/ingestors/jetstream.ts
··· 93 93 private cursor?: number 94 94 private ws?: WebSocket 95 95 private isStarted = false 96 + private isDestroyed = false 96 97 private wantedCollections: string[] 97 98 98 99 constructor({ ··· 133 134 start() { 134 135 if (this.isStarted) return 135 136 this.isStarted = true 137 + this.isDestroyed = false 136 138 this.ws = new WebSocket(this.constructUrlWithQuery()) 137 139 138 140 this.ws.on('open', () => { ··· 159 161 }) 160 162 161 163 this.ws.on('close', (code, reason) => { 162 - this.logger.error(`Jetstream closed. Code: ${code}, Reason: ${reason}`) 164 + if (!this.isDestroyed) { 165 + this.logger.error(`Jetstream closed. Code: ${code}, Reason: ${reason}`) 166 + } 163 167 this.isStarted = false 164 168 }) 165 169 } 166 170 167 171 destroy() { 168 172 if (this.ws) { 173 + this.isDestroyed = true 169 174 this.ws.close() 170 175 this.isStarted = false 171 176 }