UNPKG

jsstore

Version:

Harness the power of JsStore to streamline database operations in your web applications. With its SQL-like API, JsStore simplifies IndexedDB interactions, enabling developers to easily query, filter, and manipulate data with familiar syntax and efficiency

1,416 lines (1,343 loc) 175 kB
/*! * @license :jsstore - V4.9.0 - 16/12/2024 * https://github.com/ujjwalguptaofficial/JsStore * Copyright (c) 2024 @Ujjwal Gupta; Licensed MIT */ var JsStoreWorker; /******/ (() => { // webpackBootstrap /******/ "use strict"; /******/ // The require scope /******/ var __webpack_require__ = {}; /******/ /************************************************************************/ /******/ /* 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__ = {}; // ESM COMPAT FLAG __webpack_require__.r(__webpack_exports__); // EXPORTS __webpack_require__.d(__webpack_exports__, { QueryManager: () => (/* reexport */ QueryManager) }); ;// ./src/common/utils/promise_resolve.ts var promiseResolve = function (value) { return Promise.resolve(value); }; ;// ./src/common/utils/promise.ts var promise = function (cb) { return new Promise(cb); }; ;// ./src/common/enums.ts var ERROR_TYPE = { InvalidUpdateColumn: "invalid_update_column", UndefinedColumn: "undefined_column", UndefinedValue: "undefined_value", UndefinedColumnName: "undefined_column_name", UndefinedDbName: "undefined_database_name", UndefinedColumnValue: "undefined_column_value", NotArray: "not_array", NoValueSupplied: "no_value_supplied", ColumnNotExist: "column_not_exist", NoIndexFound: "no_index_found", InvalidOp: "invalid_operator", NullValue: "null_value", WrongDataType: "wrong_data_type", TableNotExist: "table_not_exist", DbNotExist: "db_not_exist", ConnectionAborted: "connection_aborted", ConnectionClosed: "connection_closed", NotObject: "not_object", InvalidConfig: "invalid_config", DbBlocked: "Db_blocked", IndexedDbNotSupported: "indexeddb_not_supported", NullValueInWhere: "null_value_in_where", InvalidJoinQuery: 'invalid_join_query', InvalidQuery: 'invalid_query', ImportScriptsFailed: 'import_scripts_failed', MethodNotExist: 'method_not_exist', Unknown: "unknown", InvalidMiddleware: "invalid_middleware", InvalidOrderQuery: 'invalid_order_query', InvalidGroupQuery: 'invalid_group_query', NoPrimaryKey: 'no_primary_key' }; var WORKER_STATUS; (function (WORKER_STATUS) { WORKER_STATUS["Registered"] = "registerd"; WORKER_STATUS["Failed"] = "failed"; WORKER_STATUS["NotStarted"] = "not_started"; })(WORKER_STATUS || (WORKER_STATUS = {})); var DATA_TYPE; (function (DATA_TYPE) { DATA_TYPE["String"] = "string"; DATA_TYPE["Object"] = "object"; DATA_TYPE["Array"] = "array"; DATA_TYPE["Number"] = "number"; DATA_TYPE["Boolean"] = "boolean"; DATA_TYPE["Null"] = "null"; DATA_TYPE["DateTime"] = "date_time"; })(DATA_TYPE || (DATA_TYPE = {})); var API; (function (API) { API["InitDb"] = "init_db"; API["MapGet"] = "map_get"; API["MapSet"] = "map_set"; API["MapHas"] = "map_has"; API["MapDelete"] = "map_delete"; API["Select"] = "select"; API["Insert"] = "insert"; API["Update"] = "update"; API["Remove"] = "remove"; API["OpenDb"] = "open_db"; API["Clear"] = "clear"; API["DropDb"] = "drop_db"; API["Count"] = "count"; API["ChangeLogStatus"] = "change_log_status"; API["Terminate"] = "terminate"; API["Transaction"] = "transaction"; API["CloseDb"] = "close_db"; API["Union"] = "union"; API["Intersect"] = "intersect"; API["ImportScripts"] = "import_scripts"; API["Middleware"] = "middleware"; })(API || (API = {})); var EVENT; (function (EVENT) { EVENT["RequestQueueEmpty"] = "requestQueueEmpty"; EVENT["RequestQueueFilled"] = "requestQueueFilled"; EVENT["Upgrade"] = "upgrade"; EVENT["Create"] = "create"; EVENT["Open"] = "open"; })(EVENT || (EVENT = {})); var QUERY_OPTION; (function (QUERY_OPTION) { QUERY_OPTION["Where"] = "where"; QUERY_OPTION["Like"] = "like"; QUERY_OPTION["Regex"] = "regex"; QUERY_OPTION["In"] = "in"; QUERY_OPTION["Equal"] = "="; QUERY_OPTION["Between"] = "-"; QUERY_OPTION["GreaterThan"] = ">"; QUERY_OPTION["LessThan"] = "<"; QUERY_OPTION["GreaterThanEqualTo"] = ">="; QUERY_OPTION["LessThanEqualTo"] = "<="; QUERY_OPTION["NotEqualTo"] = "!="; QUERY_OPTION["Aggregate"] = "aggregate"; QUERY_OPTION["Max"] = "max"; QUERY_OPTION["Min"] = "min"; QUERY_OPTION["Avg"] = "avg"; QUERY_OPTION["Count"] = "count"; QUERY_OPTION["Sum"] = "sum"; QUERY_OPTION["List"] = "list"; QUERY_OPTION["Or"] = "or"; QUERY_OPTION["Skip"] = "skip"; QUERY_OPTION["Limit"] = "limit"; QUERY_OPTION["And"] = "and"; QUERY_OPTION["IgnoreCase"] = "ignoreCase"; QUERY_OPTION["Then"] = "then"; })(QUERY_OPTION || (QUERY_OPTION = {})); var IDB_MODE; (function (IDB_MODE) { IDB_MODE["ReadOnly"] = "readonly"; IDB_MODE["ReadWrite"] = "readwrite"; })(IDB_MODE || (IDB_MODE = {})); var OCCURENCE; (function (OCCURENCE) { OCCURENCE["First"] = "f"; OCCURENCE["Last"] = "l"; OCCURENCE["Any"] = "a"; })(OCCURENCE || (OCCURENCE = {})); var CONNECTION_STATUS; (function (CONNECTION_STATUS) { CONNECTION_STATUS["Connected"] = "connected"; CONNECTION_STATUS["Closed"] = "closed"; CONNECTION_STATUS["NotStarted"] = "not_started"; CONNECTION_STATUS["UnableToStart"] = "unable_to_start"; CONNECTION_STATUS["ClosedByJsStore"] = "closed_by_jsstore"; })(CONNECTION_STATUS || (CONNECTION_STATUS = {})); ;// ./src/worker/model/table_meta.ts var TableMeta = /** @class */ (function () { function TableMeta(table) { this.columns = []; this.autoIncColumnValue = {}; this.columns = this.setColumn(table.columns); this.name = table.name; this.alter = table.alter || {}; } TableMeta.prototype.setColumn = function (tableColumns) { var columns = []; var _loop_1 = function (columnName) { var column = tableColumns[columnName]; column.name = columnName; if (column.autoIncrement) { this_1.autoIncColumnValue[columnName] = 0; } if (column.primaryKey) { this_1.primaryKey = columnName; this_1.keypath = column.keyPath || columnName; } column.enableSearch = column.enableSearch == null ? true : column.enableSearch; var existingColumnIndex = this_1.columns.indexOf(function (q) { return q.name === columnName; }); if (existingColumnIndex < 0) { columns.push(column); } else { var existingColumn = this_1.columns[existingColumnIndex]; Object.assign(existingColumn, column); } }; var this_1 = this; for (var columnName in tableColumns) { _loop_1(columnName); } return columns; }; return TableMeta; }()); ;// ./src/worker/meta_helper.ts var MetaHelper = /** @class */ (function () { function MetaHelper() { } MetaHelper.autoIncrementKey = function (tableName, columnName) { return "JsStore_".concat(tableName, "_").concat(columnName, "_Value"); }; MetaHelper.getStore = function (util) { if (!util.tx) { util.createTransaction([MetaHelper.tableName]); } return util.objectStore(MetaHelper.tableName); }; MetaHelper.set = function (key, value, util) { var store = MetaHelper.getStore(util); return promise(function (res, rej) { var req = store.put({ key: key, value: value }); req.onsuccess = function () { res(); }; req.onerror = rej; }); }; MetaHelper.get = function (key, util) { var store = MetaHelper.getStore(util); return promise(function (res, rej) { var req = store.get(util.keyRange(key)); req.onsuccess = function () { var result = req.result; res(result && result.value); }; req.onerror = rej; }); }; MetaHelper.remove = function (key, util) { var store = MetaHelper.getStore(util); return promise(function (res, rej) { var req = store.delete(util.keyRange(key)); req.onsuccess = function () { res(); }; req.onerror = rej; }); }; MetaHelper.has = function (key, util) { var store = MetaHelper.getStore(util); return promise(function (res, rej) { var req = store.count(util.keyRange(key)); req.onsuccess = function () { var result = req.result; res(result > 0); }; req.onerror = rej; }); }; MetaHelper.tableName = "JsStore_Meta"; MetaHelper.dbSchema = "JsStore_DbSchema"; return MetaHelper; }()); ;// ./src/worker/model/db_meta.ts var DbMeta = /** @class */ (function () { function DbMeta(db) { this.name = db.name; this.version = db.version || 1; db.tables.push({ name: MetaHelper.tableName, columns: { key: { primaryKey: true }, value: { enableSearch: false } }, }); this.tables = db.tables.map(function (table) { return new TableMeta(table); }); } return DbMeta; }()); ;// ./src/common/utils/for_obj.ts var forObj = function (obj, cb) { for (var key in obj) { cb(key, obj[key]); } }; ;// ./src/worker/utils/log_helper.ts var LogHelper = /** @class */ (function () { function LogHelper(type, info) { this.type = type; this.info_ = info; this.message = this.getMsg_(); } LogHelper.prototype.log = function (msg) { if (this.status) { console.log(msg); } }; LogHelper.prototype.throw = function () { throw this.get(); }; LogHelper.prototype.logError = function () { console.error(this.get()); }; LogHelper.prototype.get = function () { return { message: this.message, type: this.type }; }; LogHelper.prototype.warn = function () { console.warn(this.get()); }; LogHelper.prototype.getMsg_ = function () { var _a, _b; var errMsg; var info = this.info_; var errorHandler = (_a = {}, _a[ERROR_TYPE.NotArray] = function () { errMsg = "Supplied value is not an array"; }, _a[ERROR_TYPE.UndefinedColumn] = function () { errMsg = "Column is undefined in Where"; }, _a[ERROR_TYPE.UndefinedValue] = function () { errMsg = "Value is undefined in Where"; }, _a[ERROR_TYPE.UndefinedColumnName] = function () { errMsg = "Column name is undefined '" + info['TableName'] + "'"; }, _a[ERROR_TYPE.UndefinedDbName] = function () { errMsg = "Database name is not supplied"; }, _a[ERROR_TYPE.UndefinedColumnValue] = function () { errMsg = "Column value is undefined"; }, _a[ERROR_TYPE.NoValueSupplied] = function () { errMsg = "No value is supplied"; }, _a[ERROR_TYPE.InvalidOp] = function () { errMsg = "Invalid Op Value '" + info['Op'] + "'"; }, _a[ERROR_TYPE.ColumnNotExist] = function () { var column = info['column']; errMsg = info['isOrder'] ? ( true && info.isJoin ? "Column '".concat(column, "' in order query is invalid. Please use '<table>.<column>' format for specifying a column in join query.") : "Column '".concat(column, "' in order query does not exist")) : "Column '".concat(column, "' does not exist"); }, _a[ERROR_TYPE.NoIndexFound] = function () { errMsg = "No index found for column '" + info['column'] + "'. Query can not be executed without index."; }, _a[ERROR_TYPE.NullValue] = function () { errMsg = "Null value is not allowed for column '" + info['ColumnName'] + "'"; }, _a[ERROR_TYPE.WrongDataType] = function () { errMsg = "Expected data type for the column ".concat(info['column'], " is ").concat(info['expected'], ", but received a ").concat(info['received'], "."); // errMsg = "Supplied value for column '" + info['column'] + // "' have wrong data type"; }, _a[ERROR_TYPE.TableNotExist] = function () { errMsg = "Table '" + info['tableName'] + "' does not exist"; }, _a[ERROR_TYPE.DbNotExist] = function () { errMsg = "Database with name ".concat(info['dbName'], " does not exist"); }, _a[ERROR_TYPE.NotObject] = function () { errMsg = "supplied value is not object"; }, _a[ERROR_TYPE.InvalidConfig] = function () { errMsg = "Invalid Config '" + info['Config'] + " '"; }, _a[ERROR_TYPE.DbBlocked] = function () { errMsg = "database is blocked, cant be deleted right now"; }, _a[ERROR_TYPE.NullValueInWhere] = function () { errMsg = "Null/undefined is not allowed in where. Column '".concat(info['column'], "' has null"); }, _a[ERROR_TYPE.MethodNotExist] = function () { errMsg = "method '".concat(info, "' does not exist."); }, _a[ERROR_TYPE.IndexedDbNotSupported] = function () { errMsg = "Browser does not support indexeddb"; }, _a.getInfo = function () { errMsg = info; }, _a[ERROR_TYPE.InvalidJoinQuery] = function () { errorHandler.getInfo(); }, _a[ERROR_TYPE.ImportScriptsFailed] = function () { errorHandler.getInfo(); }, _a[ERROR_TYPE.InvalidMiddleware] = function () { errMsg = "No function ".concat(info, " is found."); }, _a); if (true) { Object.assign(errorHandler, (_b = {}, _b[ERROR_TYPE.InvalidOrderQuery] = function () { errorHandler.getInfo(); }, _b[ERROR_TYPE.InvalidGroupQuery] = function () { errorHandler.getInfo(); }, _b[ERROR_TYPE.NoPrimaryKey] = function () { errMsg = "No primary key exists for the query table. The query ".concat(JSON.stringify(info), " will not yield proper output."); }, _b)); } var errorType = this.type; var method = errorHandler[errorType]; if (method) { method(); } else { if (!errorType) { this.type = ERROR_TYPE.Unknown; } errMsg = this.message; } return errMsg; }; return LogHelper; }()); ;// ./src/worker/idbutil/index.ts var IDBUtil = /** @class */ (function () { function IDBUtil() { this.logger = new LogHelper(null); } IDBUtil.prototype.emptyTx = function () { if (!this.tx) return; this.tx.oncomplete = null; this.tx.onabort = null; this.tx.onerror = null; this.tx = null; }; IDBUtil.prototype.createTransactionIfNotExist = function (tables, mode) { if (!this.tx) { this.createTransaction(tables, mode); } }; IDBUtil.prototype.createTransaction = function (tables, mode) { var _this = this; if (mode === void 0) { mode = IDB_MODE.ReadWrite; } this.tx = this.con.transaction(tables, mode); return promise(function (res, rej) { _this.tx.oncomplete = res; _this.tx.onabort = res; _this.tx.onerror = rej; }); }; IDBUtil.prototype.keyRange = function (value, op) { var keyRange; switch (op) { case QUERY_OPTION.Between: keyRange = IDBKeyRange.bound(value.low, value.high, false, false); break; case QUERY_OPTION.GreaterThan: keyRange = IDBKeyRange.lowerBound(value, true); break; case QUERY_OPTION.GreaterThanEqualTo: keyRange = IDBKeyRange.lowerBound(value); break; case QUERY_OPTION.LessThan: keyRange = IDBKeyRange.upperBound(value, true); break; case QUERY_OPTION.LessThanEqualTo: keyRange = IDBKeyRange.upperBound(value); break; default: keyRange = IDBKeyRange.only(value); break; } return keyRange; }; IDBUtil.prototype.objectStore = function (name) { return this.tx.objectStore(name); }; IDBUtil.prototype.abortTransaction = function () { if (this.tx) { this.tx.abort(); } }; IDBUtil.prototype.close = function () { var _this = this; if (this.con) { this.con.close(); } // wait for 100 ms before success return promise(function (res) { _this.con = null; setTimeout(res, 100); }); }; IDBUtil.prototype.initDb = function (db) { var _this = this; var isDbCreated = false; var dbVersion = db.version; var oldVersion; var initLogic = function (res, rej) { var dbOpenRequest = indexedDB.open(db.name, dbVersion); dbOpenRequest.onsuccess = function () { _this.con = dbOpenRequest.result; _this.con.onversionchange = function (e) { // if (e.newVersion === null) { // An attempt is made to delete the db e.target.close(); // Manually close our connection to the db // } }; res({ isCreated: isDbCreated, oldVersion: oldVersion, newVersion: dbVersion }); }; dbOpenRequest.onerror = function (e) { console.error("error", e); rej(e); }; dbOpenRequest.onupgradeneeded = function (e) { oldVersion = e.oldVersion; var target = e.target; var upgradeConnection = target.result; isDbCreated = true; var transaction = target.transaction; var storeNames = upgradeConnection.objectStoreNames; var createObjectStore = function (table) { var option = table.primaryKey ? { keyPath: table.keypath, } : { autoIncrement: true }; var store = upgradeConnection.createObjectStore(table.name, option); table.columns.forEach(function (column) { addColumn(store, column); }); }; var addColumn = function (store, column) { var columnName = column.name; if (column.enableSearch && !store.indexNames.contains(columnName)) { var options = column.primaryKey ? { unique: true } : { unique: column.unique }; options['multiEntry'] = column.multiEntry; var keyPath = column.keyPath == null ? columnName : column.keyPath; store.createIndex(columnName, keyPath, options); } }; var deleteColumn = function (store, table, columnName) { var index = table.columns.findIndex(function (q) { return q.name === columnName; }); if (index >= 0) { table.columns.splice(index, 1); store.deleteIndex(columnName); } }; db.tables.forEach(function (table) { if (!storeNames.contains(table.name)) { createObjectStore(table); } var store = transaction.objectStore(table.name); for (var i = oldVersion + 1; i <= dbVersion; i++) { var alterQuery = table.alter[i]; if (alterQuery) { // handle new column add if (alterQuery.add) { var newColumns = table.setColumn(alterQuery.add); newColumns.forEach(function (column) { addColumn(store, column); table.columns.push(column); }); } // handle delete column add forObj(alterQuery.drop || {}, (function (columnName) { deleteColumn(store, table, columnName); })); // handle modify column forObj(alterQuery.modify || {}, (function (columnName, column) { var shouldDelete = column.multiEntry || column.keyPath || column.unique; var targetColumn = table.columns.find(function (q) { return q.name === columnName; }); var newColumn = Object.assign(targetColumn, column); newColumn.name = columnName; if (shouldDelete) { deleteColumn(store, table, columnName); addColumn(store, newColumn); table.columns.push(newColumn); } })); } } }); var _loop_1 = function (i, length_1) { var storeName = storeNames.item(i); var tableIndex = db.tables.findIndex(function (qry) { return qry.name === storeName; }); if (tableIndex < 0) { upgradeConnection.deleteObjectStore(storeName); } }; for (var i = 0, length_1 = storeNames.length; i < length_1; i++) { _loop_1(i, length_1); } }; }; return promise(initLogic); }; return IDBUtil; }()); ;// ./src/common/utils/promise_all.ts var promiseAll = function (promises) { return Promise.all(promises); }; ;// ./src/worker/utils/promise_reject.ts var promiseReject = function (value) { return Promise.reject(value); }; ;// ./src/worker/utils/get_error.ts var getError = function (e) { var customError = e instanceof LogHelper; if (customError) { e.logError(); return e.get(); } else { var error = void 0; if (e.name) { error = new LogHelper(e.name); error.message = e.message; } else { error = new LogHelper(e.target.error.name); error.message = e.target.error.message; } if (true) { error.logError(); } return error.get(); } }; ;// ./src/worker/utils/get_error_from_exception.ts var getErrorFromException = function (ex, type) { if (type === void 0) { type = ERROR_TYPE.InvalidQuery; } ex.name = type; return getError(ex); }; ;// ./src/worker/executors/base.ts var Base = /** @class */ (function () { function Base() { this.rowAffected = 0; this.isTxQuery = false; this.results = []; } Object.defineProperty(Base.prototype, "db", { get: function () { return this.util.db; }, enumerable: false, configurable: true }); Base.prototype.table = function (name) { var tableName = name || this.tableName; var table = this.db.tables.find(function (q) { return q.name === tableName; }); if (true) { if (!table) { console.warn("No table found with name ".concat(tableName)); } } return table; }; Base.prototype.primaryKey = function (tableName) { var query = this.query; if (!query.from && query.store && query.meta) { var primaryKey = query.meta.primaryKey; if (true) { if (primaryKey == null) { delete query.store; console.warn("no primary key found for query - ".concat(JSON.stringify(this.query))); } } return primaryKey; } var table = this.table(tableName); if (true) { if (table == null && query.store) { delete query.store; var metaValue = query.meta; if (!metaValue || !metaValue.primaryKey) { console.warn("no primary key found for query - ".concat(JSON.stringify(this.query), ". Please supply primary key in meta field.")); } } } return table.primaryKey; }; Base.prototype.getColumnInfo = function (columnName, tableName) { return this.table(tableName).columns.find(function (column) { return column.name === columnName; }); }; Base.prototype.onException = function (ex, type) { console.error(ex); this.util.abortTransaction(); return promiseReject(getErrorFromException(ex, type)); }; return Base; }()); ;// ./src/worker/utils/get_data_type.ts var getDataType = function (value) { if (value == null) { return DATA_TYPE.Null; } var type = typeof value; switch (type) { case 'object': if (Array.isArray(value)) { return DATA_TYPE.Array; } if (value instanceof Date) { return DATA_TYPE.DateTime; } } return type; }; ;// ./src/worker/utils/is_null.ts var isNull = function (value) { if (value == null) { return true; } else { switch (typeof value) { // case 'string': return value.length === 0; case 'number': return isNaN(value); } } return false; }; ;// ./src/worker/executors/insert/values_checker.ts var ValuesChecker = /** @class */ (function () { function ValuesChecker(table, autoIncValues) { this.table = table; this.autoIncrementValue = autoIncValues; } ValuesChecker.prototype.checkAndModifyValues = function (query) { var _this = this; var err; this.query = query; var values = query.values; var ignoreIndexes = []; values.every(function (item, index) { err = _this.checkAndModifyValue(item); if (query.ignore && err) { ignoreIndexes.push(index); err = null; } return err ? false : true; }); ignoreIndexes.forEach(function (index) { values.splice(index, 1); }); return { err: err, values: values }; }; ValuesChecker.prototype.checkAndModifyValue = function (value) { var _this = this; var error; this.table.columns.every(function (column) { error = _this.checkAndModifyColumnValue_(column, value); return error ? false : true; }); return error; }; ValuesChecker.prototype.checkNotNullAndDataType_ = function (column, value) { // check not null schema if (column.notNull && isNull(value[column.name])) { return this.getError(ERROR_TYPE.NullValue, { ColumnName: column.name }); } // check datatype else if (column.dataType && !isNull(value[column.name])) { var receivedType = getDataType(value[column.name]); if (receivedType !== column.dataType) { return this.getError(ERROR_TYPE.WrongDataType, { column: column.name, expected: column.dataType, received: receivedType }); } } }; ValuesChecker.prototype.checkAndModifyColumnValue_ = function (column, value) { var columnValue = value[column.name]; // check auto increment scheme if (column.autoIncrement) { // if value is null, then create the autoincrement value if (isNull(columnValue)) { value[column.name] = ++this.autoIncrementValue[column.name]; } else { if (getDataType(columnValue) === DATA_TYPE.Number) { // if column value is greater than autoincrement value saved, then make the // column value as autoIncrement value if (columnValue > this.autoIncrementValue[column.name]) { this.autoIncrementValue[column.name] = columnValue; } } } } // check Default Schema else if (column.default !== undefined && isNull(columnValue)) { value[column.name] = column.default; } var query = this.query; if (query.validation) { return this.checkNotNullAndDataType_(column, value); } }; ValuesChecker.prototype.getError = function (error, details) { return new LogHelper(error, details); }; return ValuesChecker; }()); ;// ./src/worker/executors/update/schema_checker.ts var SchemaChecker = /** @class */ (function () { function SchemaChecker(table) { this.table = table; } SchemaChecker.prototype.check = function (setValue, tblName) { var _this = this; var log; if (typeof setValue === DATA_TYPE.Object) { if (this.table) { // loop through table column and find data is valid this.table.columns.every(function (column) { if (column.name in setValue) { log = _this.checkByColumn_(column, setValue[column.name]); } return log ? false : true; }); } else { log = new LogHelper(ERROR_TYPE.TableNotExist, { tableName: tblName }); } } else { log = new LogHelper(ERROR_TYPE.NotObject); } return log; }; SchemaChecker.prototype.checkByColumn_ = function (column, value) { // check not null schema if (column.notNull === true && isNull(value)) { return new LogHelper(ERROR_TYPE.NullValue, { ColumnName: column.name }); } // check datatype var type = getDataType(value); var checkFurther = value != null; if (column.dataType && checkFurther) { if (type !== column.dataType && type !== 'object') { return new LogHelper(ERROR_TYPE.WrongDataType, { column: column.name, expected: column.dataType, received: type }); } } // check allowed operators if (checkFurther && type === 'object') { var allowedOp = ['+', '-', '*', '/', '{push}']; for (var prop in value) { if (allowedOp.indexOf(prop) < 0 && column.dataType && type !== column.dataType) { return new LogHelper(ERROR_TYPE.WrongDataType, { column: column.name, expected: column.dataType, received: type }); } } } }; return SchemaChecker; }()); ;// ./src/worker/executors/query_helper.ts var QueryHelper = /** @class */ (function () { function QueryHelper(dbSchema) { this.db = dbSchema; } QueryHelper.prototype.validate = function (api, query) { switch (api) { case API.Select: case API.Remove: case API.Count: return this.checkSelect(query); case API.Insert: return this.checkInsertQuery(query); case API.Update: return this.checkUpdate(query); } }; QueryHelper.prototype.getTable_ = function (tableName) { return this.db.tables.find(function (q) { return q.name === tableName; }); }; QueryHelper.prototype.isInsertQryValid = function (query) { var table = this.getTable_(query.into); var log; if (table) { switch (getDataType(query.values)) { case DATA_TYPE.Array: break; case DATA_TYPE.Null: log = new LogHelper(ERROR_TYPE.NoValueSupplied); break; default: log = new LogHelper(ERROR_TYPE.NotArray); } } else { log = new LogHelper(ERROR_TYPE.TableNotExist, { tableName: query.into }); } return { table: table, log: log }; }; QueryHelper.prototype.checkUpdate = function (query) { var err = new SchemaChecker(this.getTable_(query.in)). check(query.set, query.in); if (err) return err; if (query.where != null) { err = this.checkForNullInWhere_(query); if (err) return err; this.addGreatAndLessToNotOp_(query); } }; QueryHelper.prototype.checkSelect = function (query) { if (!query.store) { var table = this.getTable_(query.from); if (!table) { return new LogHelper(ERROR_TYPE.TableNotExist, { tableName: query.from }); } } if (query.where) { var err = this.checkForNullInWhere_(query); if (err) return err; this.addGreatAndLessToNotOp_(query); } }; QueryHelper.prototype.checkForNullInWhere_ = function (query) { for (var columnName in query.where) { if (query.where[columnName] == null) { return new LogHelper(ERROR_TYPE.NullValueInWhere, { column: columnName }); } } }; QueryHelper.prototype.addGreatAndLessToNotOp_ = function (query) { var whereQuery = query.where; var containsNot = function (qry, keys) { return keys.findIndex(function (key) { return qry[key][QUERY_OPTION.NotEqualTo] != null; }) >= 0; }; var addToSingleQry = function (qry, keys) { var value; keys.forEach(function (prop) { value = qry[prop]; if (value[QUERY_OPTION.NotEqualTo] != null) { qry[prop][QUERY_OPTION.GreaterThan] = value[QUERY_OPTION.NotEqualTo]; if (qry[QUERY_OPTION.Or] === undefined) { qry[QUERY_OPTION.Or] = {}; qry[QUERY_OPTION.Or][prop] = {}; } else if (qry[QUERY_OPTION.Or][prop] === undefined) { qry[QUERY_OPTION.Or][prop] = {}; } qry[QUERY_OPTION.Or][prop][QUERY_OPTION.LessThan] = value[QUERY_OPTION.NotEqualTo]; delete qry[prop][QUERY_OPTION.NotEqualTo]; } }); return qry; }; switch (getDataType(whereQuery)) { case DATA_TYPE.Object: var queryKeys = Object.keys(whereQuery); if (containsNot(whereQuery, queryKeys)) { if (queryKeys.length === 1) { query.where = addToSingleQry(whereQuery, queryKeys); } else { var whereTmpQry_1 = []; queryKeys.forEach(function (prop) { var _a; whereTmpQry_1.push(addToSingleQry((_a = {}, _a[prop] = whereQuery[prop], _a), [prop])); }); query.where = whereTmpQry_1; } } break; default: var whereTmp_1 = []; whereQuery.forEach(function (qry) { var qryKeys = Object.keys(qry); if (containsNot(qry, qryKeys)) { qry = addToSingleQry(qry, qryKeys); } whereTmp_1.push(qry); }); query.where = whereTmp_1; } }; QueryHelper.prototype.checkInsertQuery = function (query) { var validResult = this.isInsertQryValid(query); var table = validResult.table; var error = validResult.log; if (error) return error; if (query.skipDataCheck) return; var valueCheckerInstance = new ValuesChecker(table, table.autoIncColumnValue); var _a = valueCheckerInstance.checkAndModifyValues(query), values = _a.values, err = _a.err; query.values = values; return err; }; return QueryHelper; }()); ;// ./src/worker/executors/insert/index.ts var __extends = (undefined && undefined.__extends) || (function () { var extendStatics = function (d, b) { extendStatics = Object.setPrototypeOf || ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; return extendStatics(d, b); }; return function (d, b) { if (typeof b !== "function" && b !== null) throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); extendStatics(d, b); function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); }; })(); var Insert = /** @class */ (function (_super) { __extends(Insert, _super); function Insert(query, util) { var _this = _super.call(this) || this; _this.valuesAffected_ = []; if (query.validation == null) { query.validation = true; } _this.query = query; _this.util = util; _this.tableName = query.into; return _this; } Insert.prototype.execute = function (beforeInsert) { var _this = this; var db = this.db; var err = new QueryHelper(db).validate(API.Insert, this.query); if (err) return promiseReject(err); return beforeInsert().then(function (_) { return _this.insertData_(db).then(function (_) { return _this.query.return ? _this.valuesAffected_ : _this.rowAffected; }); }).catch(function (err) { _this.util.abortTransaction(); return promiseReject(err); }); }; Insert.prototype.insertData_ = function (db) { var _this = this; var onInsertData; var addMethod; var query = this.query; if (query.return) { onInsertData = function (value) { _this.valuesAffected_.push(value); }; } else { onInsertData = function (value) { ++_this.rowAffected; }; } addMethod = (function () { var idbMethod = query.upsert ? "put" : "add"; if (query.ignore && !_this.isTxQuery) { return function (value) { var tx = _this.util.con.transaction(query.into, IDB_MODE.ReadWrite); var objectStore = tx.objectStore(query.into); return objectStore[idbMethod](value); }; } if (!_this.isTxQuery) { _this.util.createTransaction([query.into, MetaHelper.tableName]); } _this.objectStore = _this.util.objectStore(_this.tableName); return function (value) { return _this.objectStore[idbMethod](value); }; })(); return promiseAll(query.values.map(function (value) { return promise(function (res, rej) { var addResult = addMethod(value); addResult.onerror = function (err) { if (query.ignore) { res(); } else { rej(err); } }; addResult.onsuccess = function () { onInsertData(value); res(); }; }); })).then(function () { return MetaHelper.set(MetaHelper.dbSchema, db, _this.util); }); }; return Insert; }(Base)); ;// ./src/worker/utils/set_cross_browser_idb.ts var setCrossBrowserIndexedDb = function () { try { if (!indexedDB) { indexedDB = self.mozIndexedDB || self.webkitIndexedDB || self.msIndexedDB; } if (indexedDB) { IDBTransaction = IDBTransaction || self.webkitIDBTransaction || self.msIDBTransaction; self.IDBKeyRange = self.IDBKeyRange || self.webkitIDBKeyRange || self.msIDBKeyRange; } else { return false; } } catch (ex) { return false; } return true; }; ;// ./src/worker/constants/index.ts var IS_WORKER = typeof self.alert === 'undefined' && typeof ServiceWorkerGlobalScope === 'undefined'; var IS_IDB_SUPPORTED = setCrossBrowserIndexedDb(); ;// ./src/worker/utils/is_array.ts var isArray = function (value) { return Array.isArray(value); }; ;// ./src/worker/utils/is_object.ts var isObject = function (value) { return typeof value === 'object'; }; ;// ./src/worker/utils/get_keys.ts var getKeys = function (value) { return Object.keys(value); }; ;// ./src/worker/utils/get_length.ts var getLength = function (value) { return getKeys(value).length; }; ;// ./src/worker/executors/select/base_select.ts var setPushResult = function () { var _this = this; var caseQuery = this.query.case; if (caseQuery) { this.pushResult = function (value) { var columnName; _this.thenEvaluator.setCaseAndValue(caseQuery, value); for (columnName in caseQuery) { value[columnName] = _this.thenEvaluator.setColumn(columnName).evaluate(); } _this.results.push(value); }; } else { this.pushResult = function (value) { _this.results.push(value); }; } }; var setLimitAndSkipEvaluationAtEnd = function () { if (this.query.limit) { this.limitAtEnd = true; } if (this.query.skip) { this.skipAtEnd = true; } }; var mergeWithResults = function (from) { var datas = this.results; var key = this.primaryKey(); if ( true && !key) { new LogHelper(ERROR_TYPE.NoPrimaryKey, this.query).warn(); } var lookupObject = new Map(); datas.forEach(function (data) { lookupObject.set(data[key], 1); }); from.forEach(function (item) { if (!lookupObject.has(item[key])) { datas.push(item); } }); }; ;// ./src/worker/executors/select/then_evaluator.ts var ThenEvaluator = /** @class */ (function () { function ThenEvaluator() { } ThenEvaluator.prototype.setCaseAndValue = function (caseQuery, value) { this.caseQuery_ = caseQuery; this.setValue(value); }; ThenEvaluator.prototype.setCaseAndColumn = function (caseQuery, columnName) { this.caseQuery_ = caseQuery; this.setColumn(columnName); return this; }; ThenEvaluator.prototype.setColumn = function (columnName) { this.columnName_ = columnName; this.caseColumnQuery_ = this.caseQuery_[this.columnName_]; this.length_ = this.caseColumnQuery_.length; return this; }; ThenEvaluator.prototype.setValue = function (value) { this.value = value; return this; }; ThenEvaluator.prototype.evaluate = function () { for (var i = 0; i < this.length_; i++) { if (this.checkCase_(this.caseColumnQuery_[i]) === true) { return this.caseColumnQuery_[i].then; } } var lastThen = this.caseColumnQuery_[this.length_ - 1].then; return lastThen == null ? this.value[this.columnName_] : lastThen; }; ThenEvaluator.prototype.checkCase_ = function (cond) { var queryOption; for (queryOption in cond) { switch (queryOption) { case QUERY_OPTION.GreaterThan: if (this.value[this.columnName_] > cond[queryOption]) { return true; } break; case QUERY_OPTION.Equal: if (this.value[this.columnName_] === cond[queryOption]) { return true; } break; case QUERY_OPTION.LessThan: if (this.value[this.columnName_] < cond[queryOption]) { return true; } break; case QUERY_OPTION.GreaterThanEqualTo: if (this.value[this.columnName_] >= cond[queryOption]) { return true; } break; case QUERY_OPTION.LessThanEqualTo: if (this.value[this.columnName_] <= cond[queryOption]) { return true; } break; case QUERY_OPTION.NotEqualTo: if (this.value[this.columnName_] !== cond[queryOption]) { return true; } break; case QUERY_OPTION.Between: if (this.value[this.columnName_] > cond[queryOption].low && this.value[this.columnName_] < cond[queryOption].high) { return true; } break; } return false; } }; return ThenEvaluator; }()); ;// ./src/worker/executors/select/where.ts var getCursorOnSuccess = function (simpleFn, limitFn, skipFn, skipAndLimitFn) { if (this.limitAtEnd === false && this.skipAtEnd === false) { if (this.skipRecord) { return this.limitRecord ? skipAndLimitFn : skipFn; } if (this.limitRecord) { return limitFn; } } return simpleFn; }; var executeWhereLogic = function (column, value, op, dir) { var _this = this; value = op ? value[op] : value; var cursorRequest = this.objectStore.index(column).openCursor(this.util.keyRange(value, op), dir); var onSuccess = getCursorOnSuccess.call(this, executeSimpleForWhere_, executeLimitForWhere_, executeSkipForWhere_, executeSkipAndLimitForWhere_); return promise(function (res, rej) { cursorRequest.onerror = rej; cursorRequest.onsuccess = onSuccess.call(_this, res); }); }; var executeSkipAndLimitForWhere_ = function (onFinish) { var _this = this; var recordSkipped = false; return function (e) { var cursor = e.target.result; if (cursor) { if (recordSkipped && _this.results.length !== _this.limitRecord) { if (_this.shouldAddValue(cursor)) { _this.pushResult(cursor.value); } cursor.continue(); } else { recordSkipped = true; cursor.advance(_this.skipRecord); } } else { onFinish(); } }; }; var executeSkipForWhere_ = function (onFinish) { var _this = this; var recordSkipped = false; return function (e) { var cursor = e.target.result; if (cursor) { if (recordSkipped) {