/******/ (() => { // webpackBootstrap /******/ "use strict"; /******/ var __webpack_modules__ = ({ /***/ "./src/database_wrapper.mjs": /*!**********************************!*\ !*** ./src/database_wrapper.mjs ***! \**********************************/ /***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "DatabaseWrapper": () => (/* binding */ DatabaseWrapper) /* harmony export */ }); /* harmony import */ var _transaction_manager_mjs__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./transaction_manager.mjs */ "./src/transaction_manager.mjs"); class DatabaseWrapper { constructor(dbName, version) { this.name = dbName; this.db = openDatabase(this.name, version, "", 5 * 1024 * 1024); this.transManager = new _transaction_manager_mjs__WEBPACK_IMPORTED_MODULE_0__.TransactionManager(this.db); } sql(sql, ...args) { const reg = /^\s*(BEGIN|END|COMMIT|ROLLBACK)(?:[^A-Z]|$)/i; const match = reg.exec(sql); if (match) { const statement = match[1].toUpperCase(); switch(statement) { case "BEGIN": return this.transManager.begin(); case "END": case "COMMIT": return this.transManager.commit(); case "ROLLBACK": return this.transManager.rollback(); } } else { return this.transManager.sql(sql, args); } } } /***/ }), /***/ "./src/log.mjs": /*!*********************!*\ !*** ./src/log.mjs ***! \*********************/ /***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "log": () => (/* binding */ log), /* harmony export */ "enableDebug": () => (/* binding */ enableDebug) /* harmony export */ }); let DEBUG = false; function log(...args) { if (DEBUG) { console.log(...args); } } function enableDebug(active) { DEBUG = !!active; log("PawSQLite-WebSQL-Adapter: debugging " + ( DEBUG ? "enabled" : "disabled") ); } /***/ }), /***/ "./src/response_wrapper.mjs": /*!**********************************!*\ !*** ./src/response_wrapper.mjs ***! \**********************************/ /***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "ResponseWrapper": () => (/* binding */ ResponseWrapper) /* harmony export */ }); const ResponseWrapper = { success: (obj = {}) => ({ success: true, ...obj }) }; /***/ }), /***/ "./src/result_mapper.mjs": /*!*******************************!*\ !*** ./src/result_mapper.mjs ***! \*******************************/ /***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "mapResult": () => (/* binding */ mapResult) /* harmony export */ }); function mapResult(originalResult) { const newResult = {}; if (!originalResult) { return newResult; } try { newResult.insertId = originalResult.insertId; } catch (e) {} newResult.rowsAffected = originalResult.rowsAffected; if ("rows" in originalResult) { newResult.rows = []; for (let i = 0; i < originalResult.rows.length; i++) { newResult.rows.push(originalResult.rows.item(i)); } } return newResult; } /***/ }), /***/ "./src/transaction_manager.mjs": /*!*************************************!*\ !*** ./src/transaction_manager.mjs ***! \*************************************/ /***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "TransactionManager": () => (/* binding */ TransactionManager) /* harmony export */ }); /* harmony import */ var _websql_adapter_error_mjs__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./websql_adapter_error.mjs */ "./src/websql_adapter_error.mjs"); /* harmony import */ var _result_mapper_mjs__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./result_mapper.mjs */ "./src/result_mapper.mjs"); /* harmony import */ var _log_mjs__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./log.mjs */ "./src/log.mjs"); class Task { constructor(job, startsTransaction=false, endsTransaction=false) { this._job = job; if (startsTransaction && endsTransaction) { throw new Error("Task cannot start and end a transaction."); } this.startsTransaction = startsTransaction; this.endsTransaction = endsTransaction; this.result = new Promise ((resolve, reject) => { this._resolve = resolve; this._reject = reject; }); } run(tx) { return this._job(tx).then((result) => { this._resolve(result); return result; }, (e) => { this._reject(e); }); } } class TransactionManager { constructor(db) { this.db = db; this._txCount = 0; this._tasks = []; this._processing = false; } begin() { return this._addTask(new Task((tx) => { return new Promise((resolve, reject) => { if (tx) { reject(new _websql_adapter_error_mjs__WEBPACK_IMPORTED_MODULE_0__.WebSQLAdapterError("BEGIN called with an active " + "transaction. This should not happen")); return; } this.db.transaction((tx) => { resolve(tx); }); }); }, true)).then(() => (0,_result_mapper_mjs__WEBPACK_IMPORTED_MODULE_1__.mapResult)()); } sql(sql, args = []) { return this._addTask(new Task((tx) => { return this._executeSql(tx, sql, args); })); } commit() { return this._addTask(new Task((tx) => { return Promise.resolve((0,_result_mapper_mjs__WEBPACK_IMPORTED_MODULE_1__.mapResult)()); }, false, true)); } rollback() { // Hack to manually cause rollback: // Intentionally cause an error with rollbackOnError set to true return this._addTask(new Task((tx) => { return this._executeSql(tx, "", [], true).catch(() => (0,_result_mapper_mjs__WEBPACK_IMPORTED_MODULE_1__.mapResult)()); }, false, true)); } async _process() { if (this._processing) { return; } this._processing = true; let tx = null; let keepaliveCount = 0; while (true) { const tasks = this._tasks; this._tasks = []; if (tasks.length) { const promises = []; for (const task of tasks) { const promise = task.run(tx); if (task.startsTransaction) { tx = await promise; this._txCount++; } else { if (task.endsTransaction) { tx = null; keepaliveCount = 0; } promises.push(promise); } } await Promise.all(promises); } else { if (tx) { await this._nop(tx); keepaliveCount++; if (keepaliveCount % 5000 === 0) { (0,_log_mjs__WEBPACK_IMPORTED_MODULE_2__.log)(`Transaction: ${ this._txCount } Keepalive: #${ keepaliveCount }`); } } else { break; } } } this._processing = false; } _addTask(task) { this._tasks.push(task); this._process(); return task.result; } _executeSql(tx, sql, sqlArgs = [], rollbackOnError = false) { return new Promise((resolve, reject) => { if (!tx) { reject(new _websql_adapter_error_mjs__WEBPACK_IMPORTED_MODULE_0__.WebSQLAdapterError("No transaction. This should not be " + " possible")); return; } tx.executeSql(sql, sqlArgs, (tx, result) => { resolve((0,_result_mapper_mjs__WEBPACK_IMPORTED_MODULE_1__.mapResult)(result)); }, (tx, e) => { reject(_websql_adapter_error_mjs__WEBPACK_IMPORTED_MODULE_0__.WebSQLAdapterError.from(e)); return rollbackOnError; }); }); } _nop(tx) { return this._executeSql(tx, "SELECT 1"); } } /***/ }), /***/ "./src/websql_adapter_error.mjs": /*!**************************************!*\ !*** ./src/websql_adapter_error.mjs ***! \**************************************/ /***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "WebSQLAdapterError": () => (/* binding */ WebSQLAdapterError) /* harmony export */ }); class WebSQLAdapterError extends Error { static from(e) { let message = ""; if (e && e.message) { message = e.message; } return new WebSQLAdapterError(message); } } /***/ }) /******/ }); /************************************************************************/ /******/ // The module cache /******/ var __webpack_module_cache__ = {}; /******/ /******/ // The require function /******/ function __webpack_require__(moduleId) { /******/ // Check if module is in cache /******/ if(__webpack_module_cache__[moduleId]) { /******/ return __webpack_module_cache__[moduleId].exports; /******/ } /******/ // Create a new module (and put it into the cache) /******/ var module = __webpack_module_cache__[moduleId] = { /******/ // no module.id needed /******/ // no module.loaded needed /******/ exports: {} /******/ }; /******/ /******/ // Execute the module function /******/ __webpack_modules__[moduleId](module, module.exports, __webpack_require__); /******/ /******/ // Return the exports of the module /******/ return module.exports; /******/ } /******/ /************************************************************************/ /******/ /* webpack/runtime/define property getters */ /******/ (() => { /******/ // define getter functions for harmony exports /******/ __webpack_require__.d = (exports, definition) => { /******/ for(var key in definition) { /******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) { /******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] }); /******/ } /******/ } /******/ }; /******/ })(); /******/ /******/ /* webpack/runtime/hasOwnProperty shorthand */ /******/ (() => { /******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop)) /******/ })(); /******/ /******/ /* webpack/runtime/make namespace object */ /******/ (() => { /******/ // define __esModule on exports /******/ __webpack_require__.r = (exports) => { /******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { /******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); /******/ } /******/ Object.defineProperty(exports, '__esModule', { value: true }); /******/ }; /******/ })(); /******/ /************************************************************************/ var __webpack_exports__ = {}; // This entry need to be wrapped in an IIFE because it need to be isolated against other modules in the chunk. (() => { /*!********************************!*\ !*** ./src/websql_adapter.mjs ***! \********************************/ __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "PawSQLiteWebSQLAdapter": () => (/* binding */ PawSQLiteWebSQLAdapter) /* harmony export */ }); /* harmony import */ var _websql_adapter_error_mjs__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./websql_adapter_error.mjs */ "./src/websql_adapter_error.mjs"); /* harmony import */ var _database_wrapper_mjs__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./database_wrapper.mjs */ "./src/database_wrapper.mjs"); /* harmony import */ var _response_wrapper_mjs__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./response_wrapper.mjs */ "./src/response_wrapper.mjs"); /* harmony import */ var _log_mjs__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./log.mjs */ "./src/log.mjs"); const databases = new Map(); const PawSQLiteWebSQLAdapter = { name: "PawSQLiteWebSQLAdapter", open: async (dbName) => { const version = "1.0"; if (!databases.has(dbName)) { databases.set(dbName, new _database_wrapper_mjs__WEBPACK_IMPORTED_MODULE_1__.DatabaseWrapper(dbName, version)); } return _response_wrapper_mjs__WEBPACK_IMPORTED_MODULE_2__.ResponseWrapper.success({ version }); }, close: async (dbName) => { databases.delete(dbName); return _response_wrapper_mjs__WEBPACK_IMPORTED_MODULE_2__.ResponseWrapper.success(); }, sql: async (dbName, sql, ...args) => { (0,_log_mjs__WEBPACK_IMPORTED_MODULE_3__.log)(sql); const db = databases.get(dbName); if (!db) { throw new _websql_adapter_error_mjs__WEBPACK_IMPORTED_MODULE_0__.WebSQLAdapterError("Database not open"); } const result = await db.sql(sql, ...args); return _response_wrapper_mjs__WEBPACK_IMPORTED_MODULE_2__.ResponseWrapper.success(result); }, delete: async (dbName) => { throw new _websql_adapter_error_mjs__WEBPACK_IMPORTED_MODULE_0__.WebSQLAdapterError("Delete not implemented"); }, debug: _log_mjs__WEBPACK_IMPORTED_MODULE_3__.enableDebug }; })(); module.exports = __webpack_exports__.PawSQLiteWebSQLAdapter; /******/ })() ; //# sourceMappingURL=pawsqlite-websql-adapter.js.map