"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.LocalStore = exports.SYSTEM_DATABASE_VERSION_KEY = void 0;
const database_1 = require("./database");
exports.SYSTEM_DATABASE_VERSION_KEY = 'SYSTEM_DATABASE_VERSION_KEY';
class LocalStore {
    constructor(system, name) {
        this._db = () => {
            return (0, database_1.connect)(this._system, database_1.DATABASE_NAME, undefined).then((db) => {
                if (db.objectStoreNames.contains(this._name)) {
                    return db;
                }
                else {
                    let db_version;
                    const db_version_str = localStorage.getItem(exports.SYSTEM_DATABASE_VERSION_KEY);
                    if (db_version_str === null) {
                        db_version = db.version;
                    }
                    else {
                        db_version = Number.parseInt(db_version_str);
                    }
                    db_version++;
                    localStorage.setItem(exports.SYSTEM_DATABASE_VERSION_KEY, `${db_version}`);
                    return (0, database_1.connect)(this._system, database_1.DATABASE_NAME, db_version, (db) => {
                        if (!db.objectStoreNames.contains(this._name)) {
                            db.createObjectStore(this._name, {});
                        }
                    });
                }
            });
        };
        this._store = (mode) => {
            return this._db().then((db) => {
                const transaction = db.transaction(this._name, mode);
                const idb_store = transaction.objectStore(this._name);
                return idb_store;
            });
        };
        this._system = system;
        this._name = name;
    }
    _promisify_request(request) {
        return new Promise((resolve, reject) => {
            request.onsuccess = (event) => {
                const result = event.target.result;
                resolve(result);
            };
            request.onerror = (event) => {
                // @ts-ignore
                reject(event.target.errorCode);
            };
        });
    }
    async get(id) {
        const store = await this._store('readonly');
        const request = store.get(id);
        const entry = await this._promisify_request(request);
        return entry;
    }
    async getAll() {
        return new Promise(async (resolve, reject) => {
            let store;
            try {
                store = await this._store('readonly');
            }
            catch (err) {
                reject(err);
                return;
            }
            const all = {};
            const request = store.openCursor();
            request.onsuccess = (event) => {
                const cursor = event.target.result;
                if (cursor) {
                    const { key, value } = cursor;
                    all[key.toString()] = value;
                    cursor.continue();
                }
                else {
                    resolve(all);
                }
            };
            request.onerror = (event) => {
                // @ts-ignore
                reject(event.target.errorCode);
            };
        });
    }
    async reset(data) {
        const store = await this._store('readwrite');
        const promise = this._clear(store).then(() => this._addAll(store, data));
        return promise;
    }
    async clear() {
        const store = await this._store('readonly');
        return this._clear(store);
    }
    async _clear(store) {
        const request = store.clear();
        return this._promisify_request(request);
    }
    async add(id, data) {
        const store = await this._store('readwrite');
        const request = store.add(data, id);
        await this._promisify_request(request);
        return data;
    }
    async addAll(data) {
        const store = await this._store('readwrite');
        return this._addAll(store, data);
    }
    async _addAll(store, data) {
        const all = [];
        for (const id in data) {
            const entry = data[id];
            const request = store.add(entry, id);
            const request_promise = this._promisify_request(request);
            all.push(request_promise);
        }
        return Promise.all(all);
    }
    async put(id, data) {
        const store = await this._store('readwrite');
        const request = store.put(data, id);
        const entry = await this._promisify_request(request);
        return data;
    }
    async delete(id) {
        const store = await this._store('readwrite');
        const request = store.delete(id);
        await this._promisify_request(request);
    }
}
exports.LocalStore = LocalStore;
//# sourceMappingURL=store.js.map