typedserver/ts_web/index.ts
2023-04-10 00:55:16 +02:00

153 lines
5.0 KiB
TypeScript

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<interfaces.IReq_PushLatestServerChangeTime>(
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<interfaces.IReq_GetLatestServerChangeTime>(
'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();