/******/ (() => { // webpackBootstrap /******/ "use strict"; /******/ var __webpack_modules__ = ({ /***/ "./src/adapter_wrapper.mjs": /*!*********************************!*\ !*** ./src/adapter_wrapper.mjs ***! \*********************************/ /***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "wrapAdapter": () => (/* binding */ wrapAdapter) /* harmony export */ }); /* harmony import */ var _pawsqlite_error_mjs__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./pawsqlite_error.mjs */ "./src/pawsqlite_error.mjs"); function wrapAdapter(adapter) { const wrapped = {}; ["name", "open", "close", "delete", "sql"].forEach((prop) => { if (!(prop in adapter)) { throw new _pawsqlite_error_mjs__WEBPACK_IMPORTED_MODULE_0__.PawSQLiteError(`Invalid adapter: missing property: ${ prop }`); } if ( prop === "name" && !( typeof adapter[prop] === "string" || adapter[prop] instanceof String ) || prop !== "name" && ( typeof adapter[prop] !== "function" ) ) { throw new _pawsqlite_error_mjs__WEBPACK_IMPORTED_MODULE_0__.PawSQLiteError("Invalid adapter: invalid type for property: " + prop); } if (typeof adapter[prop] === "function") { wrapped[prop] = async (...args) => { try { return await adapter[prop](...args); } catch (err) { throw _pawsqlite_error_mjs__WEBPACK_IMPORTED_MODULE_0__.PawSQLiteError.from(err); } }; } else { wrapped[prop] = adapter[prop]; } }); return wrapped; } /***/ }), /***/ "./src/database.mjs": /*!**************************!*\ !*** ./src/database.mjs ***! \**************************/ /***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "Database": () => (/* binding */ Database) /* harmony export */ }); /* harmony import */ var _transaction_manager_mjs__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./transaction_manager.mjs */ "./src/transaction_manager.mjs"); class Database { constructor(dbName, adapter) { this.dbName = dbName; this.adapter = adapter; this.version = null; this.path = null; this.transactionManager = new _transaction_manager_mjs__WEBPACK_IMPORTED_MODULE_0__.TransactionManager(dbName, this.adapter); } async open() { let response = await this.adapter.open(this.dbName); if (response) { if (response.hasOwnProperty('version')) { this.version = response.version; } if (response.hasOwnProperty('path')) { this.path = response.path; } } // Allow chaining return this; } close() { return this.adapter.close(this.dbName); } transaction() { return this.transactionManager.transaction(); } async autoTransaction(cb, inheritTx) { let tx = inheritTx || this.transaction(); let result; try { result = await cb(tx); } catch (e) { if (!inheritTx) { await tx.rollback(); } throw e; } if (!inheritTx) { await tx.commit(); } return result; } // Helper method to start a transaction and execute a single SQL statement sql(sql, ...args) { return this.autoTransaction((tx) => tx.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: debugging " + (DEBUG ? "enabled" : "disabled")); if (DEBUG) { log("You might also want to enable debugging for the adapter that you " + "are using"); } } /***/ }), /***/ "./src/pawsqlite_error.mjs": /*!*********************************!*\ !*** ./src/pawsqlite_error.mjs ***! \*********************************/ /***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "PawSQLiteError": () => (/* binding */ PawSQLiteError) /* harmony export */ }); class PawSQLiteError extends Error { static from(err) { const p_err = new PawSQLiteError(err.toString()); p_err.cause = err; return p_err; } constructor(message) { super(message); this.name = "PawSQLiteError"; } } /***/ }), /***/ "./src/result.mjs": /*!************************!*\ !*** ./src/result.mjs ***! \************************/ /***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "Result": () => (/* binding */ Result) /* harmony export */ }); /* harmony import */ var _pawsqlite_error_mjs__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./pawsqlite_error.mjs */ "./src/pawsqlite_error.mjs"); class Result extends Array { constructor(result) { if (result.hasOwnProperty("rows")) { super(...result.rows); } else { super(); } if (result.hasOwnProperty("insertId")) { this.insertId = result.insertId; } if (result.hasOwnProperty("rowsAffected")) { this.rowsAffected = result.rowsAffected; } } } /***/ }), /***/ "./src/transaction.mjs": /*!*****************************!*\ !*** ./src/transaction.mjs ***! \*****************************/ /***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "Transaction": () => (/* binding */ Transaction) /* harmony export */ }); /* harmony import */ var _result_mjs__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./result.mjs */ "./src/result.mjs"); /* harmony import */ var _pawsqlite_error_mjs__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./pawsqlite_error.mjs */ "./src/pawsqlite_error.mjs"); class Transaction { constructor(dbName, adapter, enqueue, rollbackOnError=false) { this.dbName = dbName; this.adapter = adapter; this._rollbackOnError = rollbackOnError; this._enqueue = enqueue; this._completeCb = null; this._readyWait = null; this._ready = false; this._finalized = false; } async sql(sql, ...args) { if (this._finalized) { throw new _pawsqlite_error_mjs__WEBPACK_IMPORTED_MODULE_1__.PawSQLiteError("Transaction has already completed"); } if (!this._ready) { await this._waitUntilReady(); } try { return await this._executeSQL(sql, ...args); } catch (e) { if (this._rollbackOnError) { await this.rollback(); } throw e; } } // Allow for slightly more complex parameter substitution. // Instances of "???" will be replaced by the same number of comma-separated // question marks as items in the corresponding nested parateter array // eg. buildQuery("SELECT (???) FROM ?", [["col1", "col2"], "table1"]) // would output: ["SELECT (?, ?) FROM ?", ["col1", "col2", "table1"]] buildQuery(sql, ...args) { const parts = sql.split("???"); const subParamLengths = args .filter(Array.isArray) .map((a) => a.length); if (parts.length !== subParamLengths.length + 1) { throw new _pawsqlite_error_mjs__WEBPACK_IMPORTED_MODULE_1__.PawSQLiteError("Unable to build query: sub-" + "paramters do not match sub-paramters in query"); } const newQuery = parts.reduce((p1, p2, i) => { const length = subParamLengths[i - 1]; return p1 + new Array(length).fill("?").join(", ") + p2; }); const flatParams = args.reduce((acc, v) => { if (Array.isArray(v)) { Array.prototype.push.apply(acc, v); } else { acc.push(v); } return acc; }, []); return [newQuery, ...flatParams]; } commit() { return this._complete("COMMIT"); } rollback() { return this._complete("ROLLBACK"); } async _waitUntilReady() { if (!this._readyWait) { this._readyWait = (async () => { this._completeCb = await this._enqueue(); await this._begin(); this._ready = true; })(); } await this._readyWait; } async _executeSQL(sql, ...args) { const reg = /^\s*(BEGIN|END|COMMIT|ROLLBACK)(?:[^A-Z]|$)/i; const match = reg.exec(sql); if (match) { const statement = match[1].toUpperCase(); throw new _pawsqlite_error_mjs__WEBPACK_IMPORTED_MODULE_1__.PawSQLiteError("Manually managing transactions is " + "forbidden. Found: \"" + statement + "\" statement."); } const result = await this.adapter.sql(this.dbName, ...this.buildQuery(sql, ...args)); return new _result_mjs__WEBPACK_IMPORTED_MODULE_0__.Result(result); } async _begin() { const result = await this.adapter.sql(this.dbName, "BEGIN"); } async _complete(sql) { if (this._finalized) { throw new _pawsqlite_error_mjs__WEBPACK_IMPORTED_MODULE_1__.PawSQLiteError("Transaction has already completed"); } this._finalized = true; if (!this._readyWait) { // Transaction was unused return; } else if (!this._ready) { await this._waitUntilReady(); } let result; let error; try { result = await this.adapter.sql(this.dbName, sql); } catch (e) { error = e; } this._completeCb(); if (error) { throw error; } return new _result_mjs__WEBPACK_IMPORTED_MODULE_0__.Result(result); } } /***/ }), /***/ "./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 _transaction_mjs__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./transaction.mjs */ "./src/transaction.mjs"); class TransactionManager { constructor(dbName, adapter) { this.dbName = dbName; this.adapter = adapter; this._queue = []; this._inTransaction = false; } transaction() { return new _transaction_mjs__WEBPACK_IMPORTED_MODULE_0__.Transaction(this.dbName, this.adapter, this.enqueue.bind(this)); } enqueue() { let completeSignal; let transactionComplete = new Promise((r, _) => { completeSignal = r; }); let readySignal; let dbReady = new Promise((r, _) => { readySignal = () => { r(completeSignal); }; }); this._queue.push({readySignal, transactionComplete}); this._processQueue(); return dbReady; } async _processQueue() { // We're already processing the queue if (this._inTransaction) { return; } while (true) { let item = this._queue.shift(); if (!item) { return; } this._inTransaction = true; item.readySignal(); await item.transactionComplete; this._inTransaction = false; } } } /***/ }) /******/ }); /************************************************************************/ /******/ // 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/pawsqlite.mjs ***! \***************************/ __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__) /* harmony export */ }); /* harmony import */ var _database_mjs__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./database.mjs */ "./src/database.mjs"); /* harmony import */ var _adapter_wrapper_mjs__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./adapter_wrapper.mjs */ "./src/adapter_wrapper.mjs"); /* harmony import */ var _pawsqlite_error_mjs__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./pawsqlite_error.mjs */ "./src/pawsqlite_error.mjs"); /* harmony import */ var _log_mjs__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./log.mjs */ "./src/log.mjs"); const adapters = []; /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = ({ open: async function(dbName, options = {}) { const adapter = getAdapter(options.adapter); let db = new _database_mjs__WEBPACK_IMPORTED_MODULE_0__.Database(dbName, adapter); await db.open(); return db; }, delete: function(dbName, options = {}) { const adapter = getAdapter(options.adapter); return adapter.delete(dbName); }, registerAdapter: function(adapter) { if (!adapter) { throw new _pawsqlite_error_mjs__WEBPACK_IMPORTED_MODULE_2__.PawSQLiteError("Invalid adapter"); } const wrapped = (0,_adapter_wrapper_mjs__WEBPACK_IMPORTED_MODULE_1__.wrapAdapter)(adapter); if (getAdapter(wrapped.name, true)) { throw new _pawsqlite_error_mjs__WEBPACK_IMPORTED_MODULE_2__.PawSQLiteError(`An adapter with the name: ${ wrapped.name } ` + `Already exists`); } (0,_log_mjs__WEBPACK_IMPORTED_MODULE_3__.log)(`Registered adapter: ${ wrapped.name }`); adapters.push(wrapped); }, debug: _log_mjs__WEBPACK_IMPORTED_MODULE_3__.enableDebug, Error: _pawsqlite_error_mjs__WEBPACK_IMPORTED_MODULE_2__.PawSQLiteError }); function getAdapter(adapterName, silent=false) { const adapter = adapters.find((a) => a.name === adapterName); if (!(silent || adapter)) { throw new _pawsqlite_error_mjs__WEBPACK_IMPORTED_MODULE_2__.PawSQLiteError(`Unknown Adapter: ${adapterName}`); } return adapter; } })(); module.exports = __webpack_exports__.default; /******/ })() ; //# sourceMappingURL=pawsqlite.js.map