UNPKG

@synerty/vortexjs

Version:

Custom observable data serialisation and routing based on Angular 2+

123 lines 16.6 kB
import { __decorate, __param } from "tslib"; import { Inject } from "@angular/core"; import { random, SqlApiABC } from "./sql-api-abc"; import { dateStr } from "../UtilMisc"; const RETRY_NO_SPACE = "there was not enough remaining storage space"; const RETRY_DISK_ERROR = "unable to begin transaction (3850 disk I/O error)"; export let WebSqlApi = class WebSqlApi extends SqlApiABC { constructor(dbName, dbSchema) { super(dbName, dbSchema); } async isOpen() { return this.db != null; } async close() { this.db = null; } async _openDb() { let retries = 5; while (true) { try { return await this._openWrapped(); } catch (err) { err = err.message ? err.message : err; if (retries >= 0 && WebSqlApi.checkRetryMessage(err)) { retries--; await new Promise((r) => setTimeout(() => r(), 100 + random())); continue; } throw new Error(err); } } } async _openWrapped() { if (await this.isOpen()) { return; } this.db = openDatabase(this.dbName, "1", this.dbName, 4 * 1024 * 1024); await this.installSchema(); } async transaction(executeData, isQuery) { if (!(await this.isOpen())) await this.open(); let retries = 5; while (true) { try { return await this._transactionInner(executeData, isQuery); } catch (e) { if (retries >= 0 && (WebSqlApi.checkRetryMessage(e) || WebSqlApi.isLockedMsg(e))) { retries--; await new Promise((r) => setTimeout(() => r(), 100 + random())); continue; } throw new Error(e); } } } async _transactionInner(executeData, isQuery) { executeData = [...executeData]; const data = []; await new Promise((resolve, reject) => { this.db.transaction((t) => { const execSql = () => { const ed = executeData.pop(); if (ed == null) { resolve(); return; } t.executeSql(ed.sql, ed.bindParams, (transaction, results) => { /* * results:(SQLResultSet) { * insertId:0, * rows:(SQLResultSetRowList){ * length:0 * }, * rowsAffected:0 * } */ if (isQuery) { // ALL GOOD, Return the rows for (let i = 0; i < results.rows.length; ++i) { data.push(results.rows.item(i)); } } if (executeData.length === 0) { resolve(); } else { execSql(); } }, (tx, err) => { err = err == null ? tx : err; // Sometimes tx is the err reject(err.message ? err.message : err); }); }; execSql(); }); }); return isQuery ? data : null; } static checkRetryMessage(message) { if (message.indexOf(RETRY_NO_SPACE) !== -1) return true; return message.indexOf(RETRY_DISK_ERROR) !== -1; } static isLockedMsg(err) { const msg = err.toString(); const hasNsSqlError = msg.indexOf("SQLITE.ALL - Database Error5") !== -1; // unable to begin transaction (5 database is locked) const hasWebSqlError = msg.indexOf("5 database is locked") !== -1; if (hasNsSqlError || hasWebSqlError) return true; console.log(`${dateStr()} WebSQL: Found error message that isn't a lock : ${msg}`); return false; } }; WebSqlApi = __decorate([ __param(0, Inject("")), __param(1, Inject([])) ], WebSqlApi); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid2ViLXNxbC1hcGkuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9zcmMvdm9ydGV4L3N0b3JhZ2UtYXBpL3dlYi1zcWwtYXBpLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQSxPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ3ZDLE9BQU8sRUFBRSxNQUFNLEVBQUUsU0FBUyxFQUFrQixNQUFNLGVBQWUsQ0FBQztBQUNsRSxPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0sYUFBYSxDQUFDO0FBSXRDLE1BQU0sY0FBYyxHQUFHLDhDQUE4QyxDQUFDO0FBQ3RFLE1BQU0sZ0JBQWdCLEdBQUcsbURBQW1ELENBQUM7QUFFdEUsV0FBTSxTQUFTLEdBQWYsTUFBTSxTQUFVLFNBQVEsU0FBUztJQUNwQyxZQUF3QixNQUFjLEVBQWMsUUFBa0I7UUFDbEUsS0FBSyxDQUFDLE1BQU0sRUFBRSxRQUFRLENBQUMsQ0FBQztJQUM1QixDQUFDO0lBRUQsS0FBSyxDQUFDLE1BQU07UUFDUixPQUFPLElBQUksQ0FBQyxFQUFFLElBQUksSUFBSSxDQUFDO0lBQzNCLENBQUM7SUFFRCxLQUFLLENBQUMsS0FBSztRQUNQLElBQUksQ0FBQyxFQUFFLEdBQUcsSUFBSSxDQUFDO0lBQ25CLENBQUM7SUFFUyxLQUFLLENBQUMsT0FBTztRQUNuQixJQUFJLE9BQU8sR0FBRyxDQUFDLENBQUM7UUFDaEIsT0FBTyxJQUFJLEVBQUU7WUFDVCxJQUFJO2dCQUNBLE9BQU8sTUFBTSxJQUFJLENBQUMsWUFBWSxFQUFFLENBQUM7YUFDcEM7WUFBQyxPQUFPLEdBQUcsRUFBRTtnQkFDVixHQUFHLEdBQUcsR0FBRyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDO2dCQUN0QyxJQUFJLE9BQU8sSUFBSSxDQUFDLElBQUksU0FBUyxDQUFDLGlCQUFpQixDQUFDLEdBQUcsQ0FB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QUFzQixDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUM7UUFFbEUsSUFBSSxhQUFhLElBQUksY0FBYztZQUFFLE9BQU8sSUFBSSxDQUFDO1FBRWpELE9BQU8sQ0FBQyxHQUFHLENBQ1AsR0FBRyxPQUFPLEVBQUUsb0RBQW9ELEdBQUcsRUFBRSxDQUN4RSxDQUFDO1FBQ0YsT0FBTyxLQUFLLENBQUM7SUFDakIsQ0FBQztDQUNKLENBQUE7QUFqSlksU0FBUztJQUNMLFdBQUEsTUFBTSxDQUFDLEVBQUUsQ0FBQyxDQUFBO0lBQWtCLFdBQUEsTUFBTSxDQUFDLEVBQUUsQ0FBQyxDQUFBO0dBRDFDLFNBQVMsQ0FpSnJCIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgSW5qZWN0IH0gZnJvbSBcIkBhbmd1bGFyL2NvcmVcIjtcbmltcG9ydCB7IHJhbmRvbSwgU3FsQXBpQUJDLCBTcWxFeGVjdXRlRGF0YSB9IGZyb20gXCIuL3NxbC1hcGktYWJjXCI7XG5pbXBvcnQgeyBkYXRlU3RyIH0gZnJvbSBcIi4uL1V0aWxNaXNjXCI7XG5cbmRlY2xhcmUgbGV0IG9wZW5EYXRhYmFzZTogYW55O1xuXG5jb25zdCBSRVRSWV9OT19TUEFDRSA9IFwidGhlcmUgd2FzIG5vdCBlbm91Z2ggcmVtYWluaW5nIHN0b3JhZ2Ugc3BhY2VcIjtcbmNvbnN0IFJFVFJZX0RJU0tfRVJST1IgPSBcInVuYWJsZSB0byBiZWdpbiB0cmFuc2FjdGlvbiAoMzg1MCBkaXNrIEkvTyBlcnJvcilcIjtcblxuZXhwb3J0IGNsYXNzIFdlYlNxbEFwaSBleHRlbmRzIFNxbEFwaUFCQyB7XG4gICAgY29uc3RydWN0b3IoQEluamVjdChcIlwiKSBkYk5hbWU6IHN0cmluZywgQEluamVjdChbXSkgZGJTY2hlbWE6IHN0cmluZ1tdKSB7XG4gICAgICAgIHN1cGVyKGRiTmFtZSwgZGJTY2hlbWEpO1xuICAgIH1cblxuICAgIGFzeW5jIGlzT3BlbigpOiBQcm9taXNlPGJvb2xlYW4+IHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZGIgIT0gbnVsbDtcbiAgICB9XG5cbiAgICBhc3luYyBjbG9zZSgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgdGhpcy5kYiA9IG51bGw7XG4gICAgfVxuXG4gICAgcHJvdGVjdGVkIGFzeW5jIF9vcGVuRGIoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIGxldCByZXRyaWVzID0gNTtcbiAgICAgICAgd2hpbGUgKHRydWUpIHtcbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGF3YWl0IHRoaXMuX29wZW5XcmFwcGVkKCk7XG4gICAgICAgICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgICAgICAgICBlcnIgPSBlcnIubWVzc2FnZSA/IGVyci5tZXNzYWdlIDogZXJyO1xuICAgICAgICAgICAgICAgIGlmIChyZXRyaWVzID49IDAgJiYgV2ViU3FsQXBpLmNoZWNrUmV0cnlNZXNzYWdlKGVycikpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0cmllcy0tO1xuICAgICAgICAgICAgICAgICAgICBhd2FpdCBuZXcgUHJvbWlzZTx2b2lkPigocikgPT5cbiAgICAgICAgICAgICAgICAgICAgICAgIHNldFRpbWVvdXQoKCkgPT4gcigpLCAxMDAgKyByYW5kb20oKSlcbiAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGVycik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIGFzeW5jIF9vcGVuV3JhcHBlZCgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgaWYgKGF3YWl0IHRoaXMuaXNPcGVuKCkpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuZGIgPSBvcGVuRGF0YWJhc2UodGhpcy5kYk5hbWUsIFwiMVwiLCB0aGlzLmRiTmFtZSwgNCAqIDEwMjQgKiAxMDI0KTtcblxuICAgICAgICBhd2FpdCB0aGlzLmluc3RhbGxTY2hlbWEoKTtcbiAgICB9XG5cbiAgICBwcm90ZWN0ZWQgYXN5bmMgdHJhbnNhY3Rpb24oXG4gICAgICAgIGV4ZWN1dGVEYXRhOiBTcWxFeGVjdXRlRGF0YVtdLFxuICAgICAgICBpc1F1ZXJ5OiBib29sZWFuXG4gICAgKTogUHJvbWlzZTxhbnlbXSB8IG51bGw+IHtcbiAgICAgICAgaWYgKCEoYXdhaXQgdGhpcy5pc09wZW4oKSkpIGF3YWl0IHRoaXMub3BlbigpO1xuXG4gICAgICAgIGxldCByZXRyaWVzID0gNTtcbiAgICAgICAgd2hpbGUgKHRydWUpIHtcbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGF3YWl0IHRoaXMuX3RyYW5zYWN0aW9uSW5uZXIoZXhlY3V0ZURhdGEsIGlzUXVlcnkpO1xuICAgICAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICAgICAgICAgcmV0cmllcyA+PSAwICYmXG4gICAgICAgICAgICAgICAgICAgIChXZWJTcWxBcGkuY2hlY2tSZXRyeU1lc3NhZ2UoZSkgfHwgV2ViU3FsQXBpLmlzTG9ja2VkTXNnKGUpKVxuICAgICAgICAgICAgICAgICkge1xuICAgICAgICAgICAgICAgICAgICByZXRyaWVzLS07XG4gICAgICAgICAgICAgICAgICAgIGF3YWl0IG5ldyBQcm9taXNlPHZvaWQ+KChyKSA9PlxuICAgICAgICAgICAgICAgICAgICAgICAgc2V0VGltZW91dCgoKSA9PiByKCksIDEwMCArIHJhbmRvbSgpKVxuICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIGFzeW5jIF90cmFuc2FjdGlvbklubmVyKFxuICAgICAgICBleGVjdXRlRGF0YTogU3FsRXhlY3V0ZURhdGFbXSxcbiAgICAgICAgaXNRdWVyeTogYm9vbGVhblxuICAgICk6IFByb21pc2U8YW55W10gfCBudWxsPiB7XG4gICAgICAgIGV4ZWN1dGVEYXRhID0gWy4uLmV4ZWN1dGVEYXRhXTtcbiAgICAgICAgY29uc3QgZGF0YTogYW55W10gPSBbXTtcbiAgICAgICAgYXdhaXQgbmV3IFByb21pc2U8dm9pZD4oKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5kYi50cmFuc2FjdGlvbigodCkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IGV4ZWNTcWwgPSAoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGVkID0gZXhlY3V0ZURhdGEucG9wKCk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChlZCA9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgdC5leGVjdXRlU3FsKFxuICAgICAgICAgICAgICAgICAgICAgICAgZWQuc3FsLFxuICAgICAgICAgICAgICAgICAgICAgICAgZWQuYmluZFBhcmFtcyxcbiAgICAgICAgICAgICAgICAgICAgICAgICh0cmFuc2FjdGlvbiwgcmVzdWx0cykgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICogcmVzdWx0czooU1FMUmVzdWx0U2V0KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICogICAgICBpbnNlcnRJZDowLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqICAgICAgcm93czooU1FMUmVzdWx0U2V0Um93TGlzdCl7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICogICAgICAgICAgbGVuZ3RoOjBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKiAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICogICAgICByb3dzQWZmZWN0ZWQ6MFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICovXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGlzUXVlcnkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gQUxMIEdPT0QsIFJldHVybiB0aGUgcm93c1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHJlc3VsdHMucm93cy5sZW5ndGg7ICsraSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGF0YS5wdXNoKHJlc3VsdHMucm93cy5pdGVtKGkpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChleGVjdXRlRGF0YS5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV4ZWNTcWwoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICAgICAgKHR4LCBlcnIpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnIgPSBlcnIgPT0gbnVsbCA/IHR4IDogZXJyOyAvLyBTb21ldGltZXMgdHggaXMgdGhlIGVyclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnIubWVzc2FnZSA/IGVyci5tZXNzYWdlIDogZXJyKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIGV4ZWNTcWwoKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcblxuICAgICAgICByZXR1cm4gaXNRdWVyeSA/IGRhdGEgOiBudWxsO1xuICAgIH1cblxuICAgIHByaXZhdGUgc3RhdGljIGNoZWNrUmV0cnlNZXNzYWdlKG1lc3NhZ2U6IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgICAgICBpZiAobWVzc2FnZS5pbmRleE9mKFJFVFJZX05PX1NQQUNFKSAhPT0gLTEpIHJldHVybiB0cnVlO1xuXG4gICAgICAgIHJldHVybiBtZXNzYWdlLmluZGV4T2YoUkVUUllfRElTS19FUlJPUikgIT09IC0xO1xuICAgIH1cblxuICAgIHByaXZhdGUgc3RhdGljIGlzTG9ja2VkTXNnKGVycjogYW55KTogYm9vbGVhbiB7XG4gICAgICAgIGNvbnN0IG1zZyA9IGVyci50b1N0cmluZygpO1xuXG4gICAgICAgIGNvbnN0IGhhc05zU3FsRXJyb3IgPVxuICAgICAgICAgICAgbXNnLmluZGV4T2YoXCJTUUxJVEUuQUxMIC0gRGF0YWJhc2UgRXJyb3I1XCIpICE9PSAtMTtcblxuICAgICAgICAvLyB1bmFibGUgdG8gYmVnaW4gdHJhbnNhY3Rpb24gKDUgZGF0YWJhc2UgaXMgbG9ja2VkKVxuICAgICAgICBjb25zdCBoYXNXZWJTcWxFcnJvciA9IG1zZy5pbmRleE9mKFwiNSBkYXRhYmFzZSBpcyBsb2NrZWRcIikgIT09IC0xO1xuXG4gICAgICAgIGlmIChoYXNOc1NxbEVycm9yIHx8IGhhc1dlYlNxbEVycm9yKSByZXR1cm4gdHJ1ZTtcblxuICAgICAgICBjb25zb2xlLmxvZyhcbiAgICAgICAgICAgIGAke2RhdGVTdHIoKX0gV2ViU1FMOiBGb3VuZCBlcnJvciBtZXNzYWdlIHRoYXQgaXNuJ3QgYSBsb2NrIDogJHttc2d9YFxuICAgICAgICApO1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxufVxuIl19