import * as plugins from './typedserver_web.plugins.js'; import * as interfaces from '../ts/interfaces/index.js'; import { logger } from './typedserver_web.logger.js'; logger.log('info', `TypedServer-Devtools initialized!`); import { TypedserverInfoscreen } from './typedserver_web.infoscreen.js'; export class ReloadChecker { public reloadJustified = false; public backendConnectionLost = false; public infoscreen = new TypedserverInfoscreen(); public store = new plugins.webstore.WebStore({ dbName: 'apiglobal__typedserver', storeName: 'apiglobal__typedserver', }); public storeKey = 'lastServerChange'; public typedsocket: plugins.typedsocket.TypedSocket; public typedrouter = new plugins.typedrequest.TypedRouter(); constructor() {} public async reload() { // this looks a bit hacky, but apparently is the safest way to really reload stuff window.location.reload(); } /** * starts the reload checker */ public async performHttpRequest() { logger.log('info', 'performing http check...'); (await this.store.get(this.storeKey)) ? null : await this.store.set(this.storeKey, globalThis.typedserver.lastReload); let response: Response; try { const controller = new AbortController(); plugins.smartdelay.delayFor(5000).then(() => { controller.abort(); }); response = await fetch('/typedserver/reloadcheck', { method: 'POST', signal: controller.signal, }); } catch (err: any) {} if (response?.status !== 200) { this.backendConnectionLost = true; logger.log('warn', `got a status ${response?.status}.`); this.infoscreen.setText(`backend connection lost... Status ${response?.status}`); } if (response?.status === 200 && this.backendConnectionLost) { this.backendConnectionLost = false; this.infoscreen.setSuccess('regained connection to backend...'); } return response; } public async checkReload(lastServerChange: number) { let reloadJustified = false; let storedLastServerChange = await this.store.get(this.storeKey); if (storedLastServerChange && storedLastServerChange !== lastServerChange) { reloadJustified = true; } else { } if (reloadJustified) { this.store.set(this.storeKey, lastServerChange); const reloadText = `upgrading... ${ globalThis.globalSw ? '(purging the sw cache first...)' : '' }`; this.infoscreen.setText(reloadText); if (globalThis.globalSw?.purgeCache) { await globalThis.globalSw.purgeCache(); } else { console.log('globalThis.globalSw not found...'); } this.infoscreen.setText(`cleaned caches`); await plugins.smartdelay.delayFor(200); this.reload(); return; } else { if (this.infoscreen) { this.infoscreen.hide(); } return; } } public async connectTypedsocket() { if (!this.typedsocket) { this.typedrouter.addTypedHandler( new plugins.typedrequest.TypedHandler('pushLatestServerChangeTime', async (dataArg) => { this.checkReload(dataArg.time); return {}; }) ); this.typedsocket = await plugins.typedsocket.TypedSocket.createClient( this.typedrouter, plugins.typedsocket.TypedSocket.useWindowLocationOriginUrl() ); this.typedsocket.addTag('typedserver_frontend', {}); this.typedsocket.eventSubject.subscribe(async (eventArg) => { console.log(`typedsocket event subscription: ${eventArg}`); if ( eventArg === 'disconnected' || eventArg === 'disconnecting' || eventArg === 'timedOut' ) { this.backendConnectionLost = true; this.infoscreen.setText(`typedsocket ${eventArg}!`); } else if (eventArg === 'connected' && this.backendConnectionLost) { this.backendConnectionLost = false; this.infoscreen.setSuccess('typedsocket connected!'); // lets check if a reload is necessary const getLatestServerChangeTime = this.typedsocket.createTypedRequest( 'getLatestServerChangeTime' ); const response = await getLatestServerChangeTime.fire({}); this.checkReload(response.time); } }); logger.log('success', `ReloadChecker connected through typedsocket!`); } } public started = false; public async start() { this.started = true; logger.log('info', `starting ReloadChecker...`); while (this.started) { const response = await this.performHttpRequest(); if (response.status === 200) { logger.log('info', `ReloadChecker reached backend!`); await this.checkReload(parseInt(await response.text())); await this.connectTypedsocket(); } await plugins.smartdelay.delayFor(120000); } } public async stop() { this.started = false; } } const reloadCheckInstance = new ReloadChecker(); reloadCheckInstance.start();