landsbankinn-exporter/src/state/level.ts

60 lines
1.9 KiB
TypeScript

import { Level } from 'level';
import { ExporterState, PartialStateUpdate, Status } from './index';
import Config from '../config';
type LevelError = Error | null | undefined;
//@ts-ignore
const errorNotFound = (err: LevelError) => err.code && err.code == 'LEVEL_NOT_FOUND';
class LevelState {
private _db = new Level('landsbankinn-exporter', { valueEncoding: 'json' });
private currentTTLHandle: number | undefined = -1;
constructor() {
function creator(err: Error | null | undefined) {
if (err) {
if (errorNotFound(err)) {
console.info('Creating initial empty state');
//@ts-ignore
this._db.put('state', {});
}
}
}
const self = this;
this.prepTTL().then(() => self._db.get('state', {}, creator.bind(self)));
}
get current(): Promise<ExporterState> {
return this._db.get('state') as unknown as Promise<ExporterState>;
}
async clear() {
console.info('Cleared state');
return await this._db.put('state', { status: Status.NotReady } as any);
}
private async clearTTL() {
if (this.currentTTLHandle) {
window.clearTimeout(this.currentTTLHandle);
}
}
private async prepTTL() {
console.info(`Will clear state in ${Config.StateTTL} milliseconds`);
this.currentTTLHandle = window.setTimeout(async () => await this.clear(), Config.StateTTL);
}
async update(stateUpdate: ExporterState | PartialStateUpdate): Promise<ExporterState> {
this.clearTTL();
const currentState: ExporterState = await this.current;
let newState = { ...currentState, ...stateUpdate };
await this._db.put('state', newState as any);
this.prepTTL();
return this.current;
}
}
export const State: LevelState = new LevelState();