2024-05-11 10:51:20 +00:00
|
|
|
import * as plugins from './plugins.js';
|
2024-05-13 21:24:08 +00:00
|
|
|
import * as interfaces from '../dist_ts_interfaces/index.js';
|
2024-05-24 23:24:02 +00:00
|
|
|
import { ServiceWorker } from './classes.serviceworker.js';
|
|
|
|
import { logger } from './logging.js';
|
|
|
|
import { CacheManager } from './classes.cachemanager.js';
|
2024-05-11 10:51:20 +00:00
|
|
|
|
|
|
|
export class UpdateManager {
|
|
|
|
public lastUpdateCheck: number = 0;
|
2024-05-13 21:24:08 +00:00
|
|
|
public lastVersionInfo: interfaces.serviceworker.IRequest_Serviceworker_Backend_VersionInfo['response'];
|
2024-05-11 10:51:20 +00:00
|
|
|
|
2024-05-23 13:28:41 +00:00
|
|
|
public serviceworkerRef: ServiceWorker;
|
2024-05-11 10:51:20 +00:00
|
|
|
|
2024-05-23 13:28:41 +00:00
|
|
|
constructor(serviceWorkerRefArg: ServiceWorker) {
|
2024-05-11 10:51:20 +00:00
|
|
|
this.serviceworkerRef = serviceWorkerRefArg;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* checks wether an update is needed
|
|
|
|
*/
|
|
|
|
public async checkUpdate(cacheManager: CacheManager): Promise<boolean> {
|
|
|
|
const lswVersionInfoKey = 'versionInfo';
|
|
|
|
if (!this.lastVersionInfo && !(await this.serviceworkerRef.store.check(lswVersionInfoKey))) {
|
|
|
|
this.lastVersionInfo = {
|
|
|
|
appHash: '',
|
|
|
|
appSemVer: 'v0.0.0',
|
|
|
|
};
|
|
|
|
} else if (
|
|
|
|
!this.lastVersionInfo &&
|
|
|
|
(await this.serviceworkerRef.store.check(lswVersionInfoKey))
|
|
|
|
) {
|
|
|
|
this.lastVersionInfo = await this.serviceworkerRef.store.get(lswVersionInfoKey);
|
|
|
|
}
|
|
|
|
|
|
|
|
const now = Date.now();
|
|
|
|
const millisSinceLastCheck = now - this.lastUpdateCheck;
|
|
|
|
if (millisSinceLastCheck < 100000) {
|
|
|
|
// TODO account for being offline
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
logger.log('info', 'checking for update of the app by comparing app hashes...');
|
|
|
|
this.lastUpdateCheck = now;
|
|
|
|
const currentVersionInfo = await this.getVersionInfoFromServer();
|
|
|
|
logger.log('info', `old versionInfo: ${JSON.stringify(this.lastVersionInfo)}`);
|
|
|
|
logger.log('info', `current versionInfo: ${JSON.stringify(currentVersionInfo)}`);
|
|
|
|
const needsUpdate = this.lastVersionInfo.appHash !== currentVersionInfo.appHash ? true : false;
|
|
|
|
if (needsUpdate) {
|
|
|
|
logger.log('info', 'Caches need to be updated');
|
|
|
|
logger.log('info', 'starting a debounced update task');
|
|
|
|
this.performAsyncUpdateDebouncedTask.trigger();
|
|
|
|
this.lastVersionInfo = currentVersionInfo;
|
|
|
|
await this.serviceworkerRef.store.set(lswVersionInfoKey, this.lastVersionInfo);
|
|
|
|
} else {
|
|
|
|
logger.log('ok', 'caches are still valid, performing revalidation in a bit...');
|
|
|
|
this.performAsyncCacheRevalidationDebouncedTask.trigger();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* gets the apphash from the server
|
|
|
|
*/
|
|
|
|
public async getVersionInfoFromServer() {
|
|
|
|
const getAppHashRequest = new plugins.typedrequest.TypedRequest<
|
2024-05-13 21:24:08 +00:00
|
|
|
interfaces.serviceworker.IRequest_Serviceworker_Backend_VersionInfo
|
2024-05-14 13:28:09 +00:00
|
|
|
>('/sw-typedrequest', 'serviceworker_versionInfo');
|
2024-05-11 10:51:20 +00:00
|
|
|
const result = await getAppHashRequest.fire({});
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
// tasks
|
|
|
|
/**
|
|
|
|
* this task is executed once we know that there is a new version available
|
|
|
|
*/
|
|
|
|
public performAsyncUpdateDebouncedTask = new plugins.taskbuffer.TaskDebounced({
|
|
|
|
name: 'performAsyncUpdate',
|
|
|
|
taskFunction: async () => {
|
|
|
|
logger.log('info', 'trying to update PWA with serviceworker');
|
|
|
|
await this.serviceworkerRef.cacheManager.cleanCaches('a new app version has been communicated by the server.');
|
|
|
|
// lets notify all current clients about the update
|
|
|
|
await this.serviceworkerRef.leleServiceWorkerBackend.triggerReloadAll();
|
|
|
|
},
|
|
|
|
debounceTimeInMillis: 2000,
|
|
|
|
});
|
|
|
|
|
|
|
|
public performAsyncCacheRevalidationDebouncedTask = new plugins.taskbuffer.TaskDebounced({
|
|
|
|
name: 'performAsyncCacheRevalidation',
|
|
|
|
taskFunction: async () => {
|
|
|
|
await this.serviceworkerRef.cacheManager.revalidateCache();
|
|
|
|
},
|
|
|
|
debounceTimeInMillis: 6000
|
|
|
|
});
|
|
|
|
}
|