From 142e19a8b102d9e9339bc475b36b609ed80ac11f Mon Sep 17 00:00:00 2001 From: kevinnwang Date: Wed, 22 Feb 2017 17:10:28 +0800 Subject: [PATCH 1/6] fix protocol indexeddb api keep, range calc errors --- package.json | 8 ++++---- src/logline.js | 23 +++++++++++------------ src/protocols/indexeddb.js | 27 ++++++++------------------- src/protocols/websql.js | 18 ++++-------------- 4 files changed, 27 insertions(+), 49 deletions(-) diff --git a/package.json b/package.json index 4ad51f7..02abf22 100644 --- a/package.json +++ b/package.json @@ -4,10 +4,10 @@ "description": "logs for the frontend", "main": "dist/logline.min.js", "scripts": { - "test": "./node_modules/.bin/phantomjs ./node_modules/mocha-phantomjs-core/mocha-phantomjs-core.js test/index.html", - "configure": "./node_modules/.bin/gulp configure", - "build:dev": "./node_modules/.bin/rollup -c", - "build:prod": "NODE_ENV=production ./node_modules/.bin/rollup -c", + "test": "phantomjs ./node_modules/mocha-phantomjs-core/mocha-phantomjs-core.js test/index.html", + "configure": "gulp configure", + "build:dev": "rollup -c", + "build:prod": "NODE_ENV=production rollup -c", "build": "npm run build:dev && npm run build:prod && npm run test" }, "repository": { diff --git a/src/logline.js b/src/logline.js index 55666f6..f9e64ef 100644 --- a/src/logline.js +++ b/src/logline.js @@ -62,21 +62,20 @@ class Logline { * @param {Function} readyFn - function to call back with logs as parameter */ static get(from, to, readyFn) { - var now = Date.now(); Logline._checkProtocol(); switch (arguments.length) { - case 1: - readyFn = from; - from = undefined; - break; - case 2: - readyFn = to; - to = undefined; - break; - case 3: - default: - break; + case 1: + readyFn = from; + from = undefined; + break; + case 2: + readyFn = to; + to = undefined; + break; + case 3: + default: + break; } Logline._protocol.get(from, to, readyFn); diff --git a/src/protocols/indexeddb.js b/src/protocols/indexeddb.js index e8b3737..3c6a241 100644 --- a/src/protocols/indexeddb.js +++ b/src/protocols/indexeddb.js @@ -26,9 +26,7 @@ export default class IndexedDBLogger extends LoggerInterface { */ _record(level, descriptor, data) { if (IndexedDBLogger.status !== LoggerInterface.STATUS.INITED) { - IndexedDBLogger._pool.push(() => { - this._record(level, descriptor, data); - }); + IndexedDBLogger._pool.push(() => this._record(level, descriptor, data)); if (IndexedDBLogger.status !== LoggerInterface.STATUS.INITING) { IndexedDBLogger.init(); } @@ -101,10 +99,7 @@ export default class IndexedDBLogger extends LoggerInterface { */ static get(from, to, readyFn) { if (IndexedDBLogger.status !== super.STATUS.INITED) { - IndexedDBLogger._pool.push(() => { - IndexedDBLogger.get(from, to, readyFn); - }); - return; + return IndexedDBLogger._pool.push(() => IndexedDBLogger.get(from, to, readyFn)); } from = LoggerInterface.transTimeFormat(from); @@ -145,10 +140,7 @@ export default class IndexedDBLogger extends LoggerInterface { */ static keep(daysToMaintain) { if (IndexedDBLogger.status !== super.STATUS.INITED) { - IndexedDBLogger._pool.push(() => { - IndexedDBLogger.keep(daysToMaintain); - }); - return; + return IndexedDBLogger._pool.push(() => IndexedDBLogger.keep(daysToMaintain)); } let store = IndexedDBLogger._getTransactionStore(IDBTransaction.READ_WRITE); @@ -156,11 +148,11 @@ export default class IndexedDBLogger extends LoggerInterface { let request = store.clear().onerror = event => util.throwError(event.target.error); } else { - let range = IDBKeyRange.upperBound((Date.now() - (daysToMaintain || 2) * 24 * 3600 * 1000), true); - let request = store.openCursor(range); + let range = (Date.now() - (daysToMaintain || 2) * 24 * 3600 * 1000); + let request = store.openCursor(); request.onsuccess = event => { let cursor = event.target.result; - if (cursor) { + if (cursor && cursor.value.time < range) { store.delete(cursor.primaryKey); cursor.continue(); } @@ -176,10 +168,7 @@ export default class IndexedDBLogger extends LoggerInterface { */ static clean() { if (IndexedDBLogger.status !== super.STATUS.INITED) { - IndexedDBLogger._pool.push(() => { - IndexedDBLogger.clean(); - }); - return; + return IndexedDBLogger._pool.push(() => IndexedDBLogger.clean()); } // database can be removed only after all connections are closed @@ -208,7 +197,7 @@ export default class IndexedDBLogger extends LoggerInterface { return transaction.objectStore('logs'); } else { - util.throwError('log database is not created or connections is closed, considering init it.'); + util.throwError('log database is not created or connections are closed, considering init it.'); } } diff --git a/src/protocols/websql.js b/src/protocols/websql.js index 9a62f0e..04ebedb 100644 --- a/src/protocols/websql.js +++ b/src/protocols/websql.js @@ -26,9 +26,7 @@ export default class WebsqlLogger extends LoggerInterface { */ _record(level, descriptor, data) { if (WebsqlLogger.status !== LoggerInterface.STATUS.INITED) { - WebsqlLogger._pool.push(() => { - this._record(level, descriptor, data); - }); + WebsqlLogger._pool.push(() => this._record(level, descriptor, data)); if (WebsqlLogger.status !== LoggerInterface.STATUS.INITING) { WebsqlLogger.init(); } @@ -94,10 +92,7 @@ export default class WebsqlLogger extends LoggerInterface { */ static get(from, to, readyFn) { if (WebsqlLogger.status !== super.STATUS.INITED) { - WebsqlLogger._pool.push(() => { - WebsqlLogger.get(from, to, readyFn); - }); - return; + return WebsqlLogger._pool.push(() => WebsqlLogger.get(from, to, readyFn)); } from = LoggerInterface.transTimeFormat(from); @@ -139,10 +134,7 @@ export default class WebsqlLogger extends LoggerInterface { */ static keep(daysToMaintain) { if (WebsqlLogger.status !== super.STATUS.INITED) { - WebsqlLogger._pool.push(() => { - WebsqlLogger.keep(daysToMaintain); - }); - return; + return WebsqlLogger._pool.push(() => WebsqlLogger.keep(daysToMaintain)); } try { @@ -173,9 +165,7 @@ export default class WebsqlLogger extends LoggerInterface { */ static clean() { if (WebsqlLogger.status !== super.STATUS.INITED) { - WebsqlLogger._pool.push(() => { - WebsqlLogger.clean(); - }); + WebsqlLogger._pool.push(() => WebsqlLogger.clean()); return; } From a1510c74e174168b3fa39434f55827450af5e802 Mon Sep 17 00:00:00 2001 From: kevinnwang Date: Wed, 22 Feb 2017 17:12:48 +0800 Subject: [PATCH 2/6] build for 1.0.5-pre.1 --- dist/logline.js | 59 +++++++++++++++++++---------------------- dist/logline.min.js | 2 +- dist/logline.min.js.map | 2 +- src/logline.js | 23 ++++++++-------- 4 files changed, 42 insertions(+), 44 deletions(-) diff --git a/dist/logline.js b/dist/logline.js index 06573aa..1ca3225 100644 --- a/dist/logline.js +++ b/dist/logline.js @@ -392,7 +392,7 @@ var IndexedDBLogger = function (_LoggerInterface) { if (IndexedDBLogger.status !== Interface.STATUS.INITED) { IndexedDBLogger._pool.push(function () { - _this2._record(level, descriptor, data); + return _this2._record(level, descriptor, data); }); if (IndexedDBLogger.status !== Interface.STATUS.INITING) { IndexedDBLogger.init(); @@ -481,10 +481,9 @@ var IndexedDBLogger = function (_LoggerInterface) { key: 'get', value: function get$$1(from, to, readyFn) { if (IndexedDBLogger.status !== get(IndexedDBLogger.__proto__ || Object.getPrototypeOf(IndexedDBLogger), 'STATUS', this).INITED) { - IndexedDBLogger._pool.push(function () { - IndexedDBLogger.get(from, to, readyFn); + return IndexedDBLogger._pool.push(function () { + return IndexedDBLogger.get(from, to, readyFn); }); - return; } from = Interface.transTimeFormat(from); @@ -529,10 +528,9 @@ var IndexedDBLogger = function (_LoggerInterface) { key: 'keep', value: function keep(daysToMaintain) { if (IndexedDBLogger.status !== get(IndexedDBLogger.__proto__ || Object.getPrototypeOf(IndexedDBLogger), 'STATUS', this).INITED) { - IndexedDBLogger._pool.push(function () { - IndexedDBLogger.keep(daysToMaintain); + return IndexedDBLogger._pool.push(function () { + return IndexedDBLogger.keep(daysToMaintain); }); - return; } var store = IndexedDBLogger._getTransactionStore(IDBTransaction.READ_WRITE); @@ -541,18 +539,20 @@ var IndexedDBLogger = function (_LoggerInterface) { return throwError(event.target.error); }; } else { - var range = IDBKeyRange.upperBound(Date.now() - (daysToMaintain || 2) * 24 * 3600 * 1000, true); - var _request = store.openCursor(range); - _request.onsuccess = function (event) { - var cursor = event.target.result; - if (cursor) { - store.delete(cursor.primaryKey); - cursor.continue(); - } - }; - _request.onerror = function (event) { - return throwError('unable to locate logs earlier than ' + daysToMaintain + 'd.'); - }; + (function () { + var range = Date.now() - (daysToMaintain || 2) * 24 * 3600 * 1000; + var request = store.openCursor(); + request.onsuccess = function (event) { + var cursor = event.target.result; + if (cursor && cursor.value.time < range) { + store.delete(cursor.primaryKey); + cursor.continue(); + } + }; + request.onerror = function (event) { + return throwError('unable to locate logs earlier than ' + daysToMaintain + 'd.'); + }; + })(); } } @@ -566,10 +566,9 @@ var IndexedDBLogger = function (_LoggerInterface) { key: 'clean', value: function clean() { if (IndexedDBLogger.status !== get(IndexedDBLogger.__proto__ || Object.getPrototypeOf(IndexedDBLogger), 'STATUS', this).INITED) { - IndexedDBLogger._pool.push(function () { - IndexedDBLogger.clean(); + return IndexedDBLogger._pool.push(function () { + return IndexedDBLogger.clean(); }); - return; } // database can be removed only after all connections are closed @@ -604,7 +603,7 @@ var IndexedDBLogger = function (_LoggerInterface) { }; return transaction.objectStore('logs'); } else { - throwError('log database is not created or connections is closed, considering init it.'); + throwError('log database is not created or connections are closed, considering init it.'); } } @@ -809,7 +808,7 @@ var WebsqlLogger = function (_LoggerInterface) { if (WebsqlLogger.status !== Interface.STATUS.INITED) { WebsqlLogger._pool.push(function () { - _this2._record(level, descriptor, data); + return _this2._record(level, descriptor, data); }); if (WebsqlLogger.status !== Interface.STATUS.INITING) { WebsqlLogger.init(); @@ -881,10 +880,9 @@ var WebsqlLogger = function (_LoggerInterface) { key: 'get', value: function get$$1(from, to, readyFn) { if (WebsqlLogger.status !== get(WebsqlLogger.__proto__ || Object.getPrototypeOf(WebsqlLogger), 'STATUS', this).INITED) { - WebsqlLogger._pool.push(function () { - WebsqlLogger.get(from, to, readyFn); + return WebsqlLogger._pool.push(function () { + return WebsqlLogger.get(from, to, readyFn); }); - return; } from = Interface.transTimeFormat(from); @@ -933,10 +931,9 @@ var WebsqlLogger = function (_LoggerInterface) { key: 'keep', value: function keep(daysToMaintain) { if (WebsqlLogger.status !== get(WebsqlLogger.__proto__ || Object.getPrototypeOf(WebsqlLogger), 'STATUS', this).INITED) { - WebsqlLogger._pool.push(function () { - WebsqlLogger.keep(daysToMaintain); + return WebsqlLogger._pool.push(function () { + return WebsqlLogger.keep(daysToMaintain); }); - return; } try { @@ -967,7 +964,7 @@ var WebsqlLogger = function (_LoggerInterface) { value: function clean() { if (WebsqlLogger.status !== get(WebsqlLogger.__proto__ || Object.getPrototypeOf(WebsqlLogger), 'STATUS', this).INITED) { WebsqlLogger._pool.push(function () { - WebsqlLogger.clean(); + return WebsqlLogger.clean(); }); return; } diff --git a/dist/logline.min.js b/dist/logline.min.js index f4e3a6c..2041704 100644 --- a/dist/logline.min.js +++ b/dist/logline.min.js @@ -4,5 +4,5 @@ * MIT license */ -!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):t.Logline=e()}(this,function(){"use strict";function t(t){throw new Error("Logline: "+t)}var e=function(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")},o=function(){function t(t,e){for(var o=0;oo)&&n.continue(),u.push({time:n.value.time,namespace:n.value.namespace,descriptor:n.value.descriptor,data:n.value.data}),n.continue()):r(u)},c.onerror=function(e){return t("failed to literat on logs from database.")}}},{key:"keep",value:function(e){if(s.status!==n(s.__proto__||Object.getPrototypeOf(s),"STATUS",this).INITED)return void s._pool.push(function(){s.keep(e)});var o=s._getTransactionStore(IDBTransaction.READ_WRITE);if(e){var r=IDBKeyRange.upperBound(Date.now()-24*(e||2)*3600*1e3,!0),a=o.openCursor(r);a.onsuccess=function(t){var e=t.target.result;e&&(o.delete(e.primaryKey),e.continue())},a.onerror=function(o){return t("unable to locate logs earlier than "+e+"d.")}}else{o.clear().onerror=function(e){return t(e.target.error)}}}},{key:"clean",value:function(){if(s.status!==n(s.__proto__||Object.getPrototypeOf(s),"STATUS",this).INITED)return void s._pool.push(function(){s.clean()});s.db.close();var e=window.indexedDB.deleteDatabase(s._database);e.onerror=function(e){return t(e.target.error)},e.onsuccess=function(t){delete s.status,delete s.db}}},{key:"_getTransactionStore",value:function(e){if(s.db){var o=s.db.transaction(["logs"],e||IDBTransaction.READ_WRITE||"readwrite");return o.onerror=function(e){return t(e.target.error)},o.objectStore("logs")}t("log database is not created or connections is closed, considering init it.")}},{key:"support",get:function(){return!!(window.indexedDB&&window.IDBTransaction&&window.IDBKeyRange)}}]),s}(i),s=function(c){function u(){var t;e(this,u);for(var o=arguments.length,n=Array(o),r=0;re||(r[n]={time:r[n][0],namespace:r[n][1],level:r[n][2],descriptor:r[n][3],data:r[n][4]});o(r)}},{key:"keep",value:function(t){var e=t?(window.localStorage.getItem(u._database)?JSON.parse(window.localStorage.getItem(u._database)):[]).filter(function(e){return e.time>=Date.now()-24*(t||2)*3600*1e3}):[];window.localStorage.setItem(u._database,JSON.stringify(e))}},{key:"clean",value:function(){delete u.status,window.localStorage.removeItem(u._database)}},{key:"support",get:function(){return"localStorage"in window}}]),u}(i),l=function(u){function s(){var t;e(this,s);for(var o=arguments.length,n=Array(o),r=0;r=0;)if(i=n.rows.item(u),!(e&&i.timeo)){a=JSON.parse(JSON.stringify(i));try{a.data=JSON.parse(a.data)}catch(t){}c.push(a)}r(c)},function(t,e){throw e.message})})}catch(e){t("unable to collect logs from database.")}}},{key:"keep",value:function(e){if(s.status!==n(s.__proto__||Object.getPrototypeOf(s),"STATUS",this).INITED)return void s._pool.push(function(){s.keep(e)});try{s._db.transaction(function(t){e?t.executeSql("DELETE FROM logs WHERE time < ?",[Date.now()-24*(e||2)*3600*1e3],function(){},function(t,e){throw e.message}):t.executeSql("DELETE FROM logs",[],function(){},function(t,e){throw e.message})})}catch(e){t("unable to clean logs from database.")}}},{key:"clean",value:function(){if(s.status!==n(s.__proto__||Object.getPrototypeOf(s),"STATUS",this).INITED)return void s._pool.push(function(){s.clean()});try{s._db.transaction(function(t){t.executeSql("DROP TABLE logs",[],function(){delete s.status},function(t,e){throw e.message})})}catch(e){t("unable to clean log database.")}}},{key:"support",get:function(){return"openDatabase"in window}}]),s}(i),f=function(){function n(t){return e(this,n),n._checkProtocol(),new n._protocol(t)}return o(n,null,[{key:"_initProtocol",value:function(t){n._protocol=t,n._protocol.init(n._database||"logline")}},{key:"_checkProtocol",value:function(){if(!n._protocol){for(var t=Object.keys(n.PROTOCOL),e=void 0;e=n.PROTOCOL[t.shift()];)if(e.support)return void n._initProtocol(e);throw new Error(t.join(", ").toLowerCase()+" protocols are not supported on this platform")}}},{key:"get",value:function(t,e,o){Date.now();switch(n._checkProtocol(),arguments.length){case 1:o=t,t=void 0;break;case 2:o=e,e=void 0;break;case 3:}n._protocol.get(t,e,o)}},{key:"all",value:function(t){n.get(t)}},{key:"keep",value:function(t){return n._checkProtocol(),n._protocol.keep(t),this}},{key:"clean",value:function(){return n._checkProtocol(),n._protocol.clean(),this}},{key:"using",value:function(e,o){return-1===[u,s,l].indexOf(e)&&t("specialfied protocol "+(e?e+" ":"")+"is not available"),n._protocol?this:(n.database(o||n._database),n._initProtocol(e),this)}},{key:"database",value:function(t){n._database=t}}]),n}();return f.PROTOCOL={INDEXEDDB:u,LOCALSTORAGE:s,WEBSQL:l},f.INTERFACE=Object.freeze(i),f}); +!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):t.Logline=e()}(this,function(){"use strict";function t(t){throw new Error("Logline: "+t)}var e=function(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")},o=function(){function t(t,e){for(var o=0;oo)&&r.continue(),u.push({time:r.value.time,namespace:r.value.namespace,descriptor:r.value.descriptor,data:r.value.data}),r.continue()):n(u)},c.onerror=function(e){return t("failed to literat on logs from database.")}}},{key:"keep",value:function(e){if(s.status!==r(s.__proto__||Object.getPrototypeOf(s),"STATUS",this).INITED)return s._pool.push(function(){return s.keep(e)});var o=s._getTransactionStore(IDBTransaction.READ_WRITE);if(e)!function(){var r=Date.now()-24*(e||2)*3600*1e3,n=o.openCursor();n.onsuccess=function(t){var e=t.target.result;e&&e.value.timee||(n[r]={time:n[r][0],namespace:n[r][1],level:n[r][2],descriptor:n[r][3],data:n[r][4]});o(n)}},{key:"keep",value:function(t){var e=t?(window.localStorage.getItem(u._database)?JSON.parse(window.localStorage.getItem(u._database)):[]).filter(function(e){return e.time>=Date.now()-24*(t||2)*3600*1e3}):[];window.localStorage.setItem(u._database,JSON.stringify(e))}},{key:"clean",value:function(){delete u.status,window.localStorage.removeItem(u._database)}},{key:"support",get:function(){return"localStorage"in window}}]),u}(i),l=function(u){function s(){var t;e(this,s);for(var o=arguments.length,r=Array(o),n=0;n=0;)if(i=r.rows.item(u),!(e&&i.timeo)){a=JSON.parse(JSON.stringify(i));try{a.data=JSON.parse(a.data)}catch(t){}c.push(a)}n(c)},function(t,e){throw e.message})})}catch(e){t("unable to collect logs from database.")}}},{key:"keep",value:function(e){if(s.status!==r(s.__proto__||Object.getPrototypeOf(s),"STATUS",this).INITED)return s._pool.push(function(){return s.keep(e)});try{s._db.transaction(function(t){e?t.executeSql("DELETE FROM logs WHERE time < ?",[Date.now()-24*(e||2)*3600*1e3],function(){},function(t,e){throw e.message}):t.executeSql("DELETE FROM logs",[],function(){},function(t,e){throw e.message})})}catch(e){t("unable to clean logs from database.")}}},{key:"clean",value:function(){if(s.status!==r(s.__proto__||Object.getPrototypeOf(s),"STATUS",this).INITED)return void s._pool.push(function(){return s.clean()});try{s._db.transaction(function(t){t.executeSql("DROP TABLE logs",[],function(){delete s.status},function(t,e){throw e.message})})}catch(e){t("unable to clean log database.")}}},{key:"support",get:function(){return"openDatabase"in window}}]),s}(i),f=function(){function r(t){return e(this,r),r._checkProtocol(),new r._protocol(t)}return o(r,null,[{key:"_initProtocol",value:function(t){r._protocol=t,r._protocol.init(r._database||"logline")}},{key:"_checkProtocol",value:function(){if(!r._protocol){for(var t=Object.keys(r.PROTOCOL),e=void 0;e=r.PROTOCOL[t.shift()];)if(e.support)return void r._initProtocol(e);throw new Error(t.join(", ").toLowerCase()+" protocols are not supported on this platform")}}},{key:"get",value:function(t,e,o){Date.now();switch(r._checkProtocol(),arguments.length){case 1:o=t,t=void 0;break;case 2:o=e,e=void 0;break;case 3:}r._protocol.get(t,e,o)}},{key:"all",value:function(t){r.get(t)}},{key:"keep",value:function(t){return r._checkProtocol(),r._protocol.keep(t),this}},{key:"clean",value:function(){return r._checkProtocol(),r._protocol.clean(),this}},{key:"using",value:function(e,o){return-1===[u,s,l].indexOf(e)&&t("specialfied protocol "+(e?e+" ":"")+"is not available"),r._protocol?this:(r.database(o||r._database),r._initProtocol(e),this)}},{key:"database",value:function(t){r._database=t}}]),r}();return f.PROTOCOL={INDEXEDDB:u,LOCALSTORAGE:s,WEBSQL:l},f.INTERFACE=Object.freeze(i),f}); //# sourceMappingURL=logline.min.js.map diff --git a/dist/logline.min.js.map b/dist/logline.min.js.map index 94f7993..0add508 100644 --- a/dist/logline.min.js.map +++ b/dist/logline.min.js.map @@ -1 +1 @@ -{"version":3,"file":"logline.min.js","sources":["../src/lib/util.js","../src/protocols/interface.js","../src/lib/pool.js","../src/protocols/indexeddb.js","../src/protocols/localstorage.js","../src/protocols/websql.js","../src/logline.js"],"sourcesContent":["// throw out Errors, with global prefix 'Logline: ' ahead of err.message\nexport function throwError(errMessage) {\n throw new Error('Logline: ' + errMessage);\n}\n","import * as util from '../lib/util';\n\n/**\n * Logline Interface\n * @class Interface\n */\nexport default class Interface {\n /**\n * Logline constructor\n * @constructor\n * @param {String} namespace - namespace to use\n */\n constructor(namespace) {\n this._namesapce = namespace;\n }\n\n /**\n * add a log record\n * @method _reocrd\n * @private\n * @parma {String} level - log level\n * @param {String} descriptor - to speed up search and improve understanding\n * @param {Mixed} [data] - additional data\n */\n _record(level, descriptor, data) {\n util.throwError('method _record is not implemented.');\n }\n\n /**\n * add a level-info record\n * @method info\n * @param {String} descriptor - to speed up search and improve understanding\n * @param {Mixed} [data] - additional data\n */\n info(...args) {\n this._record('info', ...args);\n }\n\n /**\n * add a level-warn record\n * @method warn\n * @param {String} descriptor - to speed up search and improve understanding\n * @param {Mixed} [data] - additional data\n */\n warn(...args) {\n this._record('warn', ...args);\n }\n\n /**\n * add a level-error record\n * @method error\n * @param {String} descriptor - to speed up search and improve understanding\n * @param {Mixed} [data] - additional data\n */\n error(...args) {\n this._record('error', ...args);\n }\n\n /**\n * add a level-critical record\n * @method critical\n * @param {String} descriptor - to speed up search and improve understanding\n * @param {Mixed} [data] - additional data\n */\n critical(...args) {\n this._record('critical', ...args);\n }\n\n /**\n * initialize protocol\n * @method init\n * @static\n * @param {String} database - database name to use\n */\n static init(database) {\n return true;\n }\n\n /**\n * transform human readable time string, such as '3d', '.3' and '1.2' into Unix timestamp\n * the default relative time is Date.now(), if no second parameter is provided\n * @method transTimeFormat\n * @static\n * @param {String} time - time string to transform\n * @param {Number} [relative] - relative time to compare, default Date.now()\n * @return {Number|NaN} timestamp transformed\n */\n static transTimeFormat(time, relative) {\n // if falsy value or timestamp already, pass it through directly,\n if (!time || /^\\d{13}$/.test(time)) {\n return +time;\n }\n // incase relative time isn't unix timestamp format,\n // neither a falsy value which will turned out to be Date.now()\n if (relative && !/^\\d{13}$/.test(relative)) {\n throw new TypeError('relative time should be standard unix timestamp');\n }\n\n return (relative || Date.now()) - time.replace(/d$/, '') * 24 * 3600 * 1000;\n }\n\n /**\n * get logs in range\n * if from and end is not defined, will fetch full log\n * @method get\n * @static\n * @param {String} from - time from, unix timestamp\n * @param {String} to - time end, unix timestamp\n * @param {Function} readyFn - function to call back with logs as parameter\n */\n static get(from, to, readyFn) {\n util.throwError('method get is not implemented.');\n }\n\n /**\n * clean logs = keep limited logs\n * @method keep\n * @static\n * @param {Number} daysToMaintain - keep logs within days\n */\n static keep(daysToMaintain) {\n util.throwError('method keep is not implemented.');\n }\n\n /**\n * delete log database\n * @method clean\n * @static\n */\n static clean() {\n util.throwError('method clean is not implemented.');\n }\n\n /**\n * protocol status map\n * @prop {Object} STATUS\n */\n static get STATUS() {\n return {\n INITING: 1,\n INITED: 2,\n FAILED: 4\n };\n }\n}\n","/**\n * Pool, for storage of async calling\n * @class Pool\n */\nexport default class Pool {\n /**\n * Pool constructor\n * @constructor\n */\n constructor() {\n this._pool = [];\n }\n\n /**\n * add an procedure\n * @method push\n * @param {Function} handler - procedure handler\n * @param {Object} context - procedure context\n */\n push(handler, context) {\n handler.context = context;\n this._pool.push(handler);\n }\n\n /**\n * consume pool\n * @method consume\n */\n consume() {\n var handler;\n while ((handler = this._pool.shift())) {\n handler.call(handler.context);\n }\n }\n}\n","import LoggerInterface from './interface';\nimport Pool from '../lib/pool';\nimport * as util from '../lib/util';\n\n/**\n * IndexedDB protocol\n * @class IndexedDBLogger\n */\nexport default class IndexedDBLogger extends LoggerInterface {\n /**\n * IndexedDB protocol constructor\n * @constructor\n * @param {String} namespace - namespace to use\n */\n constructor(...args) {\n super(...args);\n }\n\n /**\n * add a log record\n * @method _reocrd\n * @private\n * @parma {String} level - log level\n * @param {String} descriptor - to speed up search and improve understanding\n * @param {Mixed} [data] - additional data\n */\n _record(level, descriptor, data) {\n if (IndexedDBLogger.status !== LoggerInterface.STATUS.INITED) {\n IndexedDBLogger._pool.push(() => {\n this._record(level, descriptor, data);\n });\n if (IndexedDBLogger.status !== LoggerInterface.STATUS.INITING) {\n IndexedDBLogger.init();\n }\n return;\n }\n\n let transaction = IndexedDBLogger.db.transaction(['logs'], IDBTransaction.READ_WRITE || 'readwrite');\n transaction.onerror = event => util.throwError(event.target.error);\n\n let store = transaction.objectStore('logs');\n let request = store.add({\n time: Date.now(),\n namespace: this._namesapce,\n descriptor: descriptor,\n data: data\n });\n\n request.onerror = event => {\n IndexedDBLogger.status = LoggerInterface.STATUS.FAILED;\n util.throwError(event.target.error);\n };\n }\n\n /**\n * initialize protocol\n * @method init\n * @static\n * @param {String} database - database name to use\n */\n static init(database) {\n if (!IndexedDBLogger.support) {\n util.throwError('your platform does not support indexeddb protocol.');\n }\n\n if (IndexedDBLogger.status) {\n return false;\n }\n\n IndexedDBLogger._pool = IndexedDBLogger._pool || new Pool();\n IndexedDBLogger._database = database || 'logline';\n IndexedDBLogger.status = super.STATUS.INITING;\n\n IndexedDBLogger.request = window.indexedDB.open(IndexedDBLogger._database);\n IndexedDBLogger.request.onerror = event => util.throwError('protocol indexeddb is prevented.');\n IndexedDBLogger.request.onsuccess = event => {\n IndexedDBLogger.db = event.target.result;\n IndexedDBLogger.status = super.STATUS.INITED;\n IndexedDBLogger._pool.consume();\n // globally handle db request errors\n IndexedDBLogger.db.onerror = event => util.throwError(event.target.error);\n };\n IndexedDBLogger.request.onupgradeneeded = event => {\n // init dabasebase\n let db = event.target.result, store = db.createObjectStore('logs', { autoIncrement: true });\n store.createIndex('namespace', 'namespace', { unique: false });\n store.createIndex('level', 'level', { unique: false });\n store.createIndex('descriptor', 'descriptor', { unique: false });\n store.createIndex('data', 'data', { unique: false });\n };\n }\n\n /**\n * get logs in range\n * if from and end is not defined, will fetch full log\n * @method get\n * @static\n * @param {String} from - time from, unix time stamp or falsy\n * @param {String} to - time end, unix time stamp or falsy\n * @param {Function} readyFn - function to call back with logs as parameter\n */\n static get(from, to, readyFn) {\n if (IndexedDBLogger.status !== super.STATUS.INITED) {\n IndexedDBLogger._pool.push(() => {\n IndexedDBLogger.get(from, to, readyFn);\n });\n return;\n }\n\n from = LoggerInterface.transTimeFormat(from);\n to = LoggerInterface.transTimeFormat(to);\n\n let store = IndexedDBLogger._getTransactionStore(IDBTransaction.READ_ONLY || 'readonly'),\n request = store.openCursor(),\n logs = [];\n\n request.onsuccess = event => {\n var cursor = event.target.result;\n if (cursor) {\n if ((from && cursor.value.time < from) || (to && cursor.value.time > to)) {\n cursor.continue();\n }\n\n logs.push({\n time: cursor.value.time,\n namespace: cursor.value.namespace,\n descriptor: cursor.value.descriptor,\n data: cursor.value.data\n });\n cursor.continue();\n }\n else {\n readyFn(logs);\n }\n };\n\n request.onerror = event => util.throwError('failed to literat on logs from database.');\n }\n\n /**\n * clean logs = keep limited logs\n * @method keep\n * @static\n * @param {Number} daysToMaintain - keep logs within days\n */\n static keep(daysToMaintain) {\n if (IndexedDBLogger.status !== super.STATUS.INITED) {\n IndexedDBLogger._pool.push(() => {\n IndexedDBLogger.keep(daysToMaintain);\n });\n return;\n }\n\n let store = IndexedDBLogger._getTransactionStore(IDBTransaction.READ_WRITE);\n if (!daysToMaintain) {\n let request = store.clear().onerror = event => util.throwError(event.target.error);\n }\n else {\n let range = IDBKeyRange.upperBound((Date.now() - (daysToMaintain || 2) * 24 * 3600 * 1000), true);\n let request = store.openCursor(range);\n request.onsuccess = event => {\n let cursor = event.target.result;\n if (cursor) {\n store.delete(cursor.primaryKey);\n cursor.continue();\n }\n };\n request.onerror = event => util.throwError('unable to locate logs earlier than ' + daysToMaintain + 'd.');\n }\n }\n\n /**\n * delete log database\n * @method clean\n * @static\n */\n static clean() {\n if (IndexedDBLogger.status !== super.STATUS.INITED) {\n IndexedDBLogger._pool.push(() => {\n IndexedDBLogger.clean();\n });\n return;\n }\n\n // database can be removed only after all connections are closed\n IndexedDBLogger.db.close();\n let request = window.indexedDB.deleteDatabase(IndexedDBLogger._database);\n request.onerror = event => util.throwError(event.target.error);\n /* eslint no-unused-vars: \"off\" */\n request.onsuccess = event => {\n delete IndexedDBLogger.status;\n delete IndexedDBLogger.db;\n };\n }\n\n /**\n * get internal transaction store\n * @method _getTransactionStore\n * @private\n * @static\n * @param {String} mode - transaction mode\n * @return {Object} - internal object store\n */\n static _getTransactionStore(mode) {\n if (IndexedDBLogger.db) {\n let transaction = IndexedDBLogger.db.transaction(['logs'], mode || IDBTransaction.READ_WRITE || 'readwrite');\n transaction.onerror = event => util.throwError(event.target.error);\n return transaction.objectStore('logs');\n }\n else {\n util.throwError('log database is not created or connections is closed, considering init it.');\n }\n }\n\n /**\n * detect support situation\n * @prop {Boolean} support\n */\n static get support() {\n return !!(window.indexedDB && window.IDBTransaction && window.IDBKeyRange);\n }\n}\n","import LoggerInterface from './interface';\nimport * as util from '../lib/util';\n\n/**\n * Localstorage protocol\n * @class LocalStorageLogger\n */\nexport default class LocalStorageLogger extends LoggerInterface {\n /**\n * Localstorage protocol constructor\n * @constructor\n * @param {String} namespace - namespace to use\n */\n constructor(...args) {\n super(...args);\n }\n\n /**\n * add a log record\n * @method _reocrd\n * @private\n * @parma {String} level - log level\n * @param {String} descriptor - to speed up search and improve understanding\n * @param {Mixed} [data] - additional data\n */\n _record(level, descriptor, data) {\n var logs = window.localStorage.getItem(LocalStorageLogger._database) ? JSON.parse(window.localStorage.getItem(LocalStorageLogger._database)) : [];\n logs.push([\n Date.now(),\n this._namesapce,\n level,\n descriptor,\n data\n ]);\n try {\n window.localStorage.setItem(LocalStorageLogger._database, JSON.stringify(logs));\n } catch (e) { util.throwError('error inserting record'); }\n }\n\n /**\n * initialize protocol\n * @method init\n * @static\n * @param {String} database - database name to use\n */\n static init(database) {\n if (!LocalStorageLogger.support) {\n util.throwError('your platform does not support localstorage protocol.');\n }\n LocalStorageLogger._database = database || 'logline';\n if (!window.localStorage.getItem(LocalStorageLogger._database)) {\n window.localStorage.setItem(LocalStorageLogger._database, JSON.stringify([]));\n }\n LocalStorageLogger.status = super.STATUS.INITED;\n }\n\n /**\n * get logs in range\n * if from and end is not defined, will fetch full log\n * @method get\n * @static\n * @param {String} from - time from, unix time stamp or falsy\n * @param {String} to - time end, unix time stamp or falsy\n * @param {Function} readyFn - function to call back with logs as parameter\n */\n static get(from, to, readyFn) {\n var logs = JSON.parse(window.localStorage.getItem(LocalStorageLogger._database)), i;\n\n from = LoggerInterface.transTimeFormat(from);\n to = LoggerInterface.transTimeFormat(to);\n\n for (i = 0; i < logs.length; i++) {\n if ((from && logs[i][0] < from) || (to && logs[i][0] > to)) {\n continue;\n }\n\n logs[i] = {\n time: logs[i][0],\n namespace: logs[i][1],\n level: logs[i][2],\n descriptor: logs[i][3],\n data: logs[i][4]\n };\n }\n readyFn(logs);\n }\n\n /**\n * clean logs = keep limited logs\n * @method keep\n * @static\n * @param {Number} daysToMaintain - keep logs within days\n */\n static keep(daysToMaintain) {\n var logs = !daysToMaintain ? [] : (window.localStorage.getItem(LocalStorageLogger._database) ? JSON.parse(window.localStorage.getItem(LocalStorageLogger._database)) : []).filter(log => {\n return log.time >= (Date.now() - (daysToMaintain || 2) * 24 * 3600 * 1000);\n });\n window.localStorage.setItem(LocalStorageLogger._database, JSON.stringify(logs));\n }\n\n /**\n * delete log database\n * @method clean\n * @static\n */\n static clean() {\n delete LocalStorageLogger.status;\n window.localStorage.removeItem(LocalStorageLogger._database);\n }\n\n /**\n * detect support situation\n * @prop {Boolean} support\n */\n static get support() {\n return 'localStorage' in window;\n }\n}\n","import LoggerInterface from './interface';\nimport Pool from '../lib/pool';\nimport * as util from '../lib/util';\n\n/**\n * Websql protocol\n * @class WebsqlLogger\n */\nexport default class WebsqlLogger extends LoggerInterface {\n /**\n * Websql logline constructor\n * @constructor\n * @param {String} namespace - namespace to use\n */\n constructor(...args) {\n super(...args);\n }\n\n /**\n * add a log record\n * @method _reocrd\n * @private\n * @parma {String} level - log level\n * @param {String} descriptor - to speed up search and improve understanding\n * @param {Mixed} [data] - additional data\n */\n _record(level, descriptor, data) {\n if (WebsqlLogger.status !== LoggerInterface.STATUS.INITED) {\n WebsqlLogger._pool.push(() => {\n this._record(level, descriptor, data);\n });\n if (WebsqlLogger.status !== LoggerInterface.STATUS.INITING) {\n WebsqlLogger.init();\n }\n return;\n }\n\n try {\n WebsqlLogger._db.transaction(tx => {\n tx.executeSql(\n 'INSERT INTO logs (time, namespace, level, descriptor, data) VALUES(?, ?, ?, ? ,?)',\n [Date.now(), this._namesapce, level, descriptor, (data === undefined || data === '') ? '' : (JSON.stringify(data) || '')],\n () => {/* empty func */},\n (tx, e) => { throw e.message; }\n );\n });\n } catch (e) { util.throwError('error inserting record'); }\n }\n\n /**\n * initialize protocol\n * @method init\n * @static\n * @param {String} database - database name to use\n */\n static init(database) {\n if (!WebsqlLogger.support) {\n util.throwError(new Error('your platform does not support websql protocol.'));\n }\n\n if (WebsqlLogger.status) {\n return false;\n }\n\n WebsqlLogger._pool = WebsqlLogger._pool || new Pool();\n WebsqlLogger._database = database || 'logline';\n WebsqlLogger.status = super.STATUS.INITING;\n\n try {\n WebsqlLogger._db = window.openDatabase(WebsqlLogger._database, '1.0', 'cats loves logs', 4.85 * 1024 * 1024);\n WebsqlLogger._db.transaction(tx => {\n tx.executeSql(\n 'CREATE TABLE IF NOT EXISTS logs (time, namespace, level, descriptor, data)', [],\n () => {\n WebsqlLogger.status = super.STATUS.INITED;\n WebsqlLogger._pool.consume();\n },\n () => {\n WebsqlLogger.status = super.STATUS.FAILED;\n }\n );\n });\n } catch (e) { util.throwError('unable to init log database.'); }\n }\n\n /**\n * get logs in range\n * if from and end is not defined, will fetch full log\n * @method get\n * @static\n * @param {String} from - time from, unix time stamp or falsy\n * @param {String} to - time end, unix time stamp or falsy\n * @param {Function} readyFn - function to call back with logs as parameter\n */\n static get(from, to, readyFn) {\n if (WebsqlLogger.status !== super.STATUS.INITED) {\n WebsqlLogger._pool.push(() => {\n WebsqlLogger.get(from, to, readyFn);\n });\n return;\n }\n\n from = LoggerInterface.transTimeFormat(from);\n to = LoggerInterface.transTimeFormat(to);\n\n try {\n WebsqlLogger._db.transaction(function(tx) {\n tx.executeSql(\n 'SELECT * FROM logs ORDER BY time DESC', [],\n (tx, res) => {\n var logs = [], line, index = res.rows.length, item;\n while (--index >= 0) {\n item = res.rows.item(index);\n if ((from && item.time < from) || (to && item.time > to)) {\n continue;\n }\n\n // in some devices, properties are configureable: false, writable: false\n // we need deep copy\n line = JSON.parse(JSON.stringify(item));\n // incase data is an object, not a string\n try { line.data = JSON.parse(line.data); }\n catch (e) {/* leave line.data as it be */}\n logs.push(line);\n }\n readyFn(logs);\n },\n (tx, e) => { throw e.message; }\n );\n });\n } catch (e) { util.throwError('unable to collect logs from database.'); }\n }\n\n /**\n * clean logs = keep limited logs\n * @method keep\n * @static\n * @param {Number} daysToMaintain - keep logs within days\n */\n static keep(daysToMaintain) {\n if (WebsqlLogger.status !== super.STATUS.INITED) {\n WebsqlLogger._pool.push(() => {\n WebsqlLogger.keep(daysToMaintain);\n });\n return;\n }\n\n try {\n WebsqlLogger._db.transaction(function(tx) {\n if (daysToMaintain) {\n tx.executeSql(\n 'DELETE FROM logs WHERE time < ?',\n [Date.now() - (daysToMaintain || 2) * 24 * 3600 * 1000],\n function() {/* empty func */},\n function(tx, e) {throw e.message;}\n );\n }\n else {\n tx.executeSql(\n 'DELETE FROM logs', [],\n () => {/* empty func */},\n (tx, e) => { throw e.message; }\n );\n }\n });\n } catch (e) { util.throwError('unable to clean logs from database.'); }\n }\n\n /**\n * delete log database\n * @method clean\n * @static\n */\n static clean() {\n if (WebsqlLogger.status !== super.STATUS.INITED) {\n WebsqlLogger._pool.push(() => {\n WebsqlLogger.clean();\n });\n return;\n }\n\n try {\n WebsqlLogger._db.transaction(tx => {\n tx.executeSql(\n 'DROP TABLE logs', [],\n () => {\n delete WebsqlLogger.status;\n },\n (tx, e) => { throw e.message; }\n );\n });\n } catch (e) { util.throwError('unable to clean log database.'); }\n }\n\n /**\n * detect support situation\n * @prop {Boolean} support\n */\n static get support() {\n return 'openDatabase' in window;\n }\n}\n","import Interface from './protocols/interface';\nimport IndexeddbLogger from './protocols/indexeddb';\nimport LocalstorageLogger from './protocols/localstorage';\nimport WebsqlLogger from './protocols/websql';\nimport * as util from './lib/util';\n\n\nclass Logline {\n /**\n * Logline constructor\n * @constructor\n * @param {String} namespace - namespace to use\n * @return {Object Protocol Instance}\n */\n constructor(namespace) {\n Logline._checkProtocol();\n return new Logline._protocol(namespace);\n }\n\n /**\n * choose a protocol to initialize\n * @method _initProtocol\n * @private\n * @static\n * @param {Object Protocol Class} protocol - protocol to use, must under Logline.PROTOCOL\n * @return {Object} Logline\n */\n static _initProtocol(protocol) {\n Logline._protocol = protocol;\n Logline._protocol.init(Logline._database || 'logline');\n }\n\n /**\n * check protocol\n * if no protocol is chosen, will try to choose an available one automatically\n * if none of the protocols is available, an error will be thrown\n * @method _checkProtocol\n * @private\n * @static\n */\n static _checkProtocol() {\n if (!Logline._protocol) {\n let protocols = Object.keys(Logline.PROTOCOL), protocol;\n while ((protocol = Logline.PROTOCOL[protocols.shift()])) {\n if (protocol.support) {\n Logline._initProtocol(protocol);\n return;\n }\n }\n\n throw new Error(protocols.join(', ').toLowerCase() + ' protocols are not supported on this platform');\n }\n }\n\n /**\n * get logs in range\n * if from and end is not defined, will fetch full log\n * @method get\n * @static\n * @param {String} [from] - time from\n * @param {String} [to] - time end\n * @param {Function} readyFn - function to call back with logs as parameter\n */\n static get(from, to, readyFn) {\n var now = Date.now();\n Logline._checkProtocol();\n\n switch (arguments.length) {\n case 1:\n readyFn = from;\n from = undefined;\n break;\n case 2:\n readyFn = to;\n to = undefined;\n break;\n case 3:\n default:\n break;\n }\n\n Logline._protocol.get(from, to, readyFn);\n }\n\n /**\n * read all logs\n * @method all\n * @static\n * @param {Function} readyFn - function to call back with logs as parameter\n */\n static all(readyFn) {\n Logline.get(readyFn);\n }\n\n /**\n * clean up logs = keep limited logs\n * @method keep\n * @static\n * @param {String} daysToMaintain - specialfy days to keep, support human readable format such as '3d', '.3'\n * @return {Object} Logline\n */\n static keep(daysToMaintain) {\n Logline._checkProtocol();\n Logline._protocol.keep(daysToMaintain);\n return this;\n }\n\n /**\n * delete log database\n * @method clean\n * @static\n * @return {Object} Logline\n */\n static clean() {\n Logline._checkProtocol();\n Logline._protocol.clean();\n return this;\n }\n\n /**\n * choose a protocol\n * @method using\n * @static\n * @param {Object Protocol Class} protocol - wanted protocol, should be on of Logline.PROTOCOL\n * @param {String} [database] - custome database name\n * @return {Object} Logline\n */\n static using(protocol, database) {\n // protocol unavailable is not allowed\n if (-1 === [IndexeddbLogger, LocalstorageLogger, WebsqlLogger].indexOf(protocol)) {\n util.throwError('specialfied protocol ' + (protocol ? (protocol + ' ') : '') + 'is not available');\n }\n\n // once protocol is selected, it shall not be changed during runtime\n if (Logline._protocol) {\n return this;\n }\n\n Logline.database(database || Logline._database);\n Logline._initProtocol(protocol);\n return this;\n }\n\n /**\n * specialfy a custome database name, in case of any conflicts\n * @methd database\n * @static\n * @param {String} name - target database name\n */\n static database(name) {\n Logline._database = name;\n }\n}\n\n// export protocols for modification and mounting\nLogline.PROTOCOL = {\n INDEXEDDB: IndexeddbLogger,\n LOCALSTORAGE: LocalstorageLogger,\n WEBSQL: WebsqlLogger\n};\n\n// export protocol interface for user custom implements\nLogline.INTERFACE = Object.freeze(Interface);\n\nexport default Logline;\n"],"names":["throwError","errMessage","Error","Interface","namespace","_namesapce","level","descriptor","data","args","_record","database","time","relative","test","TypeError","Date","now","replace","from","to","readyFn","daysToMaintain","Pool","_pool","handler","context","push","this","shift","call","IndexedDBLogger","status","LoggerInterface","STATUS","INITED","INITING","init","transaction","db","IDBTransaction","READ_WRITE","onerror","util","event","target","error","store","objectStore","request","add","FAILED","support","_database","babelHelpers.get","window","indexedDB","open","onsuccess","result","consume","onupgradeneeded","createObjectStore","autoIncrement","createIndex","unique","get","transTimeFormat","_getTransactionStore","READ_ONLY","openCursor","logs","cursor","value","continue","keep","range","IDBKeyRange","upperBound","delete","primaryKey","clear","clean","close","deleteDatabase","mode","LocalStorageLogger","localStorage","getItem","JSON","parse","setItem","stringify","e","i","length","filter","log","removeItem","WebsqlLogger","_db","executeSql","_this2","undefined","tx","message","openDatabase","res","line","item","index","rows","Logline","_checkProtocol","_protocol","protocol","protocols","Object","keys","PROTOCOL","_initProtocol","join","toLowerCase","arguments","IndexeddbLogger","LocalstorageLogger","indexOf","name","INTERFACE","freeze"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"logline.min.js","sources":["../src/lib/util.js","../src/protocols/interface.js","../src/lib/pool.js","../src/protocols/indexeddb.js","../src/protocols/localstorage.js","../src/protocols/websql.js","../src/logline.js"],"sourcesContent":["// throw out Errors, with global prefix 'Logline: ' ahead of err.message\nexport function throwError(errMessage) {\n throw new Error('Logline: ' + errMessage);\n}\n","import * as util from '../lib/util';\n\n/**\n * Logline Interface\n * @class Interface\n */\nexport default class Interface {\n /**\n * Logline constructor\n * @constructor\n * @param {String} namespace - namespace to use\n */\n constructor(namespace) {\n this._namesapce = namespace;\n }\n\n /**\n * add a log record\n * @method _reocrd\n * @private\n * @parma {String} level - log level\n * @param {String} descriptor - to speed up search and improve understanding\n * @param {Mixed} [data] - additional data\n */\n _record(level, descriptor, data) {\n util.throwError('method _record is not implemented.');\n }\n\n /**\n * add a level-info record\n * @method info\n * @param {String} descriptor - to speed up search and improve understanding\n * @param {Mixed} [data] - additional data\n */\n info(...args) {\n this._record('info', ...args);\n }\n\n /**\n * add a level-warn record\n * @method warn\n * @param {String} descriptor - to speed up search and improve understanding\n * @param {Mixed} [data] - additional data\n */\n warn(...args) {\n this._record('warn', ...args);\n }\n\n /**\n * add a level-error record\n * @method error\n * @param {String} descriptor - to speed up search and improve understanding\n * @param {Mixed} [data] - additional data\n */\n error(...args) {\n this._record('error', ...args);\n }\n\n /**\n * add a level-critical record\n * @method critical\n * @param {String} descriptor - to speed up search and improve understanding\n * @param {Mixed} [data] - additional data\n */\n critical(...args) {\n this._record('critical', ...args);\n }\n\n /**\n * initialize protocol\n * @method init\n * @static\n * @param {String} database - database name to use\n */\n static init(database) {\n return true;\n }\n\n /**\n * transform human readable time string, such as '3d', '.3' and '1.2' into Unix timestamp\n * the default relative time is Date.now(), if no second parameter is provided\n * @method transTimeFormat\n * @static\n * @param {String} time - time string to transform\n * @param {Number} [relative] - relative time to compare, default Date.now()\n * @return {Number|NaN} timestamp transformed\n */\n static transTimeFormat(time, relative) {\n // if falsy value or timestamp already, pass it through directly,\n if (!time || /^\\d{13}$/.test(time)) {\n return +time;\n }\n // incase relative time isn't unix timestamp format,\n // neither a falsy value which will turned out to be Date.now()\n if (relative && !/^\\d{13}$/.test(relative)) {\n throw new TypeError('relative time should be standard unix timestamp');\n }\n\n return (relative || Date.now()) - time.replace(/d$/, '') * 24 * 3600 * 1000;\n }\n\n /**\n * get logs in range\n * if from and end is not defined, will fetch full log\n * @method get\n * @static\n * @param {String} from - time from, unix timestamp\n * @param {String} to - time end, unix timestamp\n * @param {Function} readyFn - function to call back with logs as parameter\n */\n static get(from, to, readyFn) {\n util.throwError('method get is not implemented.');\n }\n\n /**\n * clean logs = keep limited logs\n * @method keep\n * @static\n * @param {Number} daysToMaintain - keep logs within days\n */\n static keep(daysToMaintain) {\n util.throwError('method keep is not implemented.');\n }\n\n /**\n * delete log database\n * @method clean\n * @static\n */\n static clean() {\n util.throwError('method clean is not implemented.');\n }\n\n /**\n * protocol status map\n * @prop {Object} STATUS\n */\n static get STATUS() {\n return {\n INITING: 1,\n INITED: 2,\n FAILED: 4\n };\n }\n}\n","/**\n * Pool, for storage of async calling\n * @class Pool\n */\nexport default class Pool {\n /**\n * Pool constructor\n * @constructor\n */\n constructor() {\n this._pool = [];\n }\n\n /**\n * add an procedure\n * @method push\n * @param {Function} handler - procedure handler\n * @param {Object} context - procedure context\n */\n push(handler, context) {\n handler.context = context;\n this._pool.push(handler);\n }\n\n /**\n * consume pool\n * @method consume\n */\n consume() {\n var handler;\n while ((handler = this._pool.shift())) {\n handler.call(handler.context);\n }\n }\n}\n","import LoggerInterface from './interface';\nimport Pool from '../lib/pool';\nimport * as util from '../lib/util';\n\n/**\n * IndexedDB protocol\n * @class IndexedDBLogger\n */\nexport default class IndexedDBLogger extends LoggerInterface {\n /**\n * IndexedDB protocol constructor\n * @constructor\n * @param {String} namespace - namespace to use\n */\n constructor(...args) {\n super(...args);\n }\n\n /**\n * add a log record\n * @method _reocrd\n * @private\n * @parma {String} level - log level\n * @param {String} descriptor - to speed up search and improve understanding\n * @param {Mixed} [data] - additional data\n */\n _record(level, descriptor, data) {\n if (IndexedDBLogger.status !== LoggerInterface.STATUS.INITED) {\n IndexedDBLogger._pool.push(() => this._record(level, descriptor, data));\n if (IndexedDBLogger.status !== LoggerInterface.STATUS.INITING) {\n IndexedDBLogger.init();\n }\n return;\n }\n\n let transaction = IndexedDBLogger.db.transaction(['logs'], IDBTransaction.READ_WRITE || 'readwrite');\n transaction.onerror = event => util.throwError(event.target.error);\n\n let store = transaction.objectStore('logs');\n let request = store.add({\n time: Date.now(),\n namespace: this._namesapce,\n descriptor: descriptor,\n data: data\n });\n\n request.onerror = event => {\n IndexedDBLogger.status = LoggerInterface.STATUS.FAILED;\n util.throwError(event.target.error);\n };\n }\n\n /**\n * initialize protocol\n * @method init\n * @static\n * @param {String} database - database name to use\n */\n static init(database) {\n if (!IndexedDBLogger.support) {\n util.throwError('your platform does not support indexeddb protocol.');\n }\n\n if (IndexedDBLogger.status) {\n return false;\n }\n\n IndexedDBLogger._pool = IndexedDBLogger._pool || new Pool();\n IndexedDBLogger._database = database || 'logline';\n IndexedDBLogger.status = super.STATUS.INITING;\n\n IndexedDBLogger.request = window.indexedDB.open(IndexedDBLogger._database);\n IndexedDBLogger.request.onerror = event => util.throwError('protocol indexeddb is prevented.');\n IndexedDBLogger.request.onsuccess = event => {\n IndexedDBLogger.db = event.target.result;\n IndexedDBLogger.status = super.STATUS.INITED;\n IndexedDBLogger._pool.consume();\n // globally handle db request errors\n IndexedDBLogger.db.onerror = event => util.throwError(event.target.error);\n };\n IndexedDBLogger.request.onupgradeneeded = event => {\n // init dabasebase\n let db = event.target.result, store = db.createObjectStore('logs', { autoIncrement: true });\n store.createIndex('namespace', 'namespace', { unique: false });\n store.createIndex('level', 'level', { unique: false });\n store.createIndex('descriptor', 'descriptor', { unique: false });\n store.createIndex('data', 'data', { unique: false });\n };\n }\n\n /**\n * get logs in range\n * if from and end is not defined, will fetch full log\n * @method get\n * @static\n * @param {String} from - time from, unix time stamp or falsy\n * @param {String} to - time end, unix time stamp or falsy\n * @param {Function} readyFn - function to call back with logs as parameter\n */\n static get(from, to, readyFn) {\n if (IndexedDBLogger.status !== super.STATUS.INITED) {\n return IndexedDBLogger._pool.push(() => IndexedDBLogger.get(from, to, readyFn));\n }\n\n from = LoggerInterface.transTimeFormat(from);\n to = LoggerInterface.transTimeFormat(to);\n\n let store = IndexedDBLogger._getTransactionStore(IDBTransaction.READ_ONLY || 'readonly'),\n request = store.openCursor(),\n logs = [];\n\n request.onsuccess = event => {\n var cursor = event.target.result;\n if (cursor) {\n if ((from && cursor.value.time < from) || (to && cursor.value.time > to)) {\n cursor.continue();\n }\n\n logs.push({\n time: cursor.value.time,\n namespace: cursor.value.namespace,\n descriptor: cursor.value.descriptor,\n data: cursor.value.data\n });\n cursor.continue();\n }\n else {\n readyFn(logs);\n }\n };\n\n request.onerror = event => util.throwError('failed to literat on logs from database.');\n }\n\n /**\n * clean logs = keep limited logs\n * @method keep\n * @static\n * @param {Number} daysToMaintain - keep logs within days\n */\n static keep(daysToMaintain) {\n if (IndexedDBLogger.status !== super.STATUS.INITED) {\n return IndexedDBLogger._pool.push(() => IndexedDBLogger.keep(daysToMaintain));\n }\n\n let store = IndexedDBLogger._getTransactionStore(IDBTransaction.READ_WRITE);\n if (!daysToMaintain) {\n let request = store.clear().onerror = event => util.throwError(event.target.error);\n }\n else {\n let range = (Date.now() - (daysToMaintain || 2) * 24 * 3600 * 1000);\n let request = store.openCursor();\n request.onsuccess = event => {\n let cursor = event.target.result;\n if (cursor && cursor.value.time < range) {\n store.delete(cursor.primaryKey);\n cursor.continue();\n }\n };\n request.onerror = event => util.throwError('unable to locate logs earlier than ' + daysToMaintain + 'd.');\n }\n }\n\n /**\n * delete log database\n * @method clean\n * @static\n */\n static clean() {\n if (IndexedDBLogger.status !== super.STATUS.INITED) {\n return IndexedDBLogger._pool.push(() => IndexedDBLogger.clean());\n }\n\n // database can be removed only after all connections are closed\n IndexedDBLogger.db.close();\n let request = window.indexedDB.deleteDatabase(IndexedDBLogger._database);\n request.onerror = event => util.throwError(event.target.error);\n /* eslint no-unused-vars: \"off\" */\n request.onsuccess = event => {\n delete IndexedDBLogger.status;\n delete IndexedDBLogger.db;\n };\n }\n\n /**\n * get internal transaction store\n * @method _getTransactionStore\n * @private\n * @static\n * @param {String} mode - transaction mode\n * @return {Object} - internal object store\n */\n static _getTransactionStore(mode) {\n if (IndexedDBLogger.db) {\n let transaction = IndexedDBLogger.db.transaction(['logs'], mode || IDBTransaction.READ_WRITE || 'readwrite');\n transaction.onerror = event => util.throwError(event.target.error);\n return transaction.objectStore('logs');\n }\n else {\n util.throwError('log database is not created or connections are closed, considering init it.');\n }\n }\n\n /**\n * detect support situation\n * @prop {Boolean} support\n */\n static get support() {\n return !!(window.indexedDB && window.IDBTransaction && window.IDBKeyRange);\n }\n}\n","import LoggerInterface from './interface';\nimport * as util from '../lib/util';\n\n/**\n * Localstorage protocol\n * @class LocalStorageLogger\n */\nexport default class LocalStorageLogger extends LoggerInterface {\n /**\n * Localstorage protocol constructor\n * @constructor\n * @param {String} namespace - namespace to use\n */\n constructor(...args) {\n super(...args);\n }\n\n /**\n * add a log record\n * @method _reocrd\n * @private\n * @parma {String} level - log level\n * @param {String} descriptor - to speed up search and improve understanding\n * @param {Mixed} [data] - additional data\n */\n _record(level, descriptor, data) {\n var logs = window.localStorage.getItem(LocalStorageLogger._database) ? JSON.parse(window.localStorage.getItem(LocalStorageLogger._database)) : [];\n logs.push([\n Date.now(),\n this._namesapce,\n level,\n descriptor,\n data\n ]);\n try {\n window.localStorage.setItem(LocalStorageLogger._database, JSON.stringify(logs));\n } catch (e) { util.throwError('error inserting record'); }\n }\n\n /**\n * initialize protocol\n * @method init\n * @static\n * @param {String} database - database name to use\n */\n static init(database) {\n if (!LocalStorageLogger.support) {\n util.throwError('your platform does not support localstorage protocol.');\n }\n LocalStorageLogger._database = database || 'logline';\n if (!window.localStorage.getItem(LocalStorageLogger._database)) {\n window.localStorage.setItem(LocalStorageLogger._database, JSON.stringify([]));\n }\n LocalStorageLogger.status = super.STATUS.INITED;\n }\n\n /**\n * get logs in range\n * if from and end is not defined, will fetch full log\n * @method get\n * @static\n * @param {String} from - time from, unix time stamp or falsy\n * @param {String} to - time end, unix time stamp or falsy\n * @param {Function} readyFn - function to call back with logs as parameter\n */\n static get(from, to, readyFn) {\n var logs = JSON.parse(window.localStorage.getItem(LocalStorageLogger._database)), i;\n\n from = LoggerInterface.transTimeFormat(from);\n to = LoggerInterface.transTimeFormat(to);\n\n for (i = 0; i < logs.length; i++) {\n if ((from && logs[i][0] < from) || (to && logs[i][0] > to)) {\n continue;\n }\n\n logs[i] = {\n time: logs[i][0],\n namespace: logs[i][1],\n level: logs[i][2],\n descriptor: logs[i][3],\n data: logs[i][4]\n };\n }\n readyFn(logs);\n }\n\n /**\n * clean logs = keep limited logs\n * @method keep\n * @static\n * @param {Number} daysToMaintain - keep logs within days\n */\n static keep(daysToMaintain) {\n var logs = !daysToMaintain ? [] : (window.localStorage.getItem(LocalStorageLogger._database) ? JSON.parse(window.localStorage.getItem(LocalStorageLogger._database)) : []).filter(log => {\n return log.time >= (Date.now() - (daysToMaintain || 2) * 24 * 3600 * 1000);\n });\n window.localStorage.setItem(LocalStorageLogger._database, JSON.stringify(logs));\n }\n\n /**\n * delete log database\n * @method clean\n * @static\n */\n static clean() {\n delete LocalStorageLogger.status;\n window.localStorage.removeItem(LocalStorageLogger._database);\n }\n\n /**\n * detect support situation\n * @prop {Boolean} support\n */\n static get support() {\n return 'localStorage' in window;\n }\n}\n","import LoggerInterface from './interface';\nimport Pool from '../lib/pool';\nimport * as util from '../lib/util';\n\n/**\n * Websql protocol\n * @class WebsqlLogger\n */\nexport default class WebsqlLogger extends LoggerInterface {\n /**\n * Websql logline constructor\n * @constructor\n * @param {String} namespace - namespace to use\n */\n constructor(...args) {\n super(...args);\n }\n\n /**\n * add a log record\n * @method _reocrd\n * @private\n * @parma {String} level - log level\n * @param {String} descriptor - to speed up search and improve understanding\n * @param {Mixed} [data] - additional data\n */\n _record(level, descriptor, data) {\n if (WebsqlLogger.status !== LoggerInterface.STATUS.INITED) {\n WebsqlLogger._pool.push(() => this._record(level, descriptor, data));\n if (WebsqlLogger.status !== LoggerInterface.STATUS.INITING) {\n WebsqlLogger.init();\n }\n return;\n }\n\n try {\n WebsqlLogger._db.transaction(tx => {\n tx.executeSql(\n 'INSERT INTO logs (time, namespace, level, descriptor, data) VALUES(?, ?, ?, ? ,?)',\n [Date.now(), this._namesapce, level, descriptor, (data === undefined || data === '') ? '' : (JSON.stringify(data) || '')],\n () => {/* empty func */},\n (tx, e) => { throw e.message; }\n );\n });\n } catch (e) { util.throwError('error inserting record'); }\n }\n\n /**\n * initialize protocol\n * @method init\n * @static\n * @param {String} database - database name to use\n */\n static init(database) {\n if (!WebsqlLogger.support) {\n util.throwError(new Error('your platform does not support websql protocol.'));\n }\n\n if (WebsqlLogger.status) {\n return false;\n }\n\n WebsqlLogger._pool = WebsqlLogger._pool || new Pool();\n WebsqlLogger._database = database || 'logline';\n WebsqlLogger.status = super.STATUS.INITING;\n\n try {\n WebsqlLogger._db = window.openDatabase(WebsqlLogger._database, '1.0', 'cats loves logs', 4.85 * 1024 * 1024);\n WebsqlLogger._db.transaction(tx => {\n tx.executeSql(\n 'CREATE TABLE IF NOT EXISTS logs (time, namespace, level, descriptor, data)', [],\n () => {\n WebsqlLogger.status = super.STATUS.INITED;\n WebsqlLogger._pool.consume();\n },\n () => {\n WebsqlLogger.status = super.STATUS.FAILED;\n }\n );\n });\n } catch (e) { util.throwError('unable to init log database.'); }\n }\n\n /**\n * get logs in range\n * if from and end is not defined, will fetch full log\n * @method get\n * @static\n * @param {String} from - time from, unix time stamp or falsy\n * @param {String} to - time end, unix time stamp or falsy\n * @param {Function} readyFn - function to call back with logs as parameter\n */\n static get(from, to, readyFn) {\n if (WebsqlLogger.status !== super.STATUS.INITED) {\n return WebsqlLogger._pool.push(() => WebsqlLogger.get(from, to, readyFn));\n }\n\n from = LoggerInterface.transTimeFormat(from);\n to = LoggerInterface.transTimeFormat(to);\n\n try {\n WebsqlLogger._db.transaction(function(tx) {\n tx.executeSql(\n 'SELECT * FROM logs ORDER BY time DESC', [],\n (tx, res) => {\n var logs = [], line, index = res.rows.length, item;\n while (--index >= 0) {\n item = res.rows.item(index);\n if ((from && item.time < from) || (to && item.time > to)) {\n continue;\n }\n\n // in some devices, properties are configureable: false, writable: false\n // we need deep copy\n line = JSON.parse(JSON.stringify(item));\n // incase data is an object, not a string\n try { line.data = JSON.parse(line.data); }\n catch (e) {/* leave line.data as it be */}\n logs.push(line);\n }\n readyFn(logs);\n },\n (tx, e) => { throw e.message; }\n );\n });\n } catch (e) { util.throwError('unable to collect logs from database.'); }\n }\n\n /**\n * clean logs = keep limited logs\n * @method keep\n * @static\n * @param {Number} daysToMaintain - keep logs within days\n */\n static keep(daysToMaintain) {\n if (WebsqlLogger.status !== super.STATUS.INITED) {\n return WebsqlLogger._pool.push(() => WebsqlLogger.keep(daysToMaintain));\n }\n\n try {\n WebsqlLogger._db.transaction(function(tx) {\n if (daysToMaintain) {\n tx.executeSql(\n 'DELETE FROM logs WHERE time < ?',\n [Date.now() - (daysToMaintain || 2) * 24 * 3600 * 1000],\n function() {/* empty func */},\n function(tx, e) {throw e.message;}\n );\n }\n else {\n tx.executeSql(\n 'DELETE FROM logs', [],\n () => {/* empty func */},\n (tx, e) => { throw e.message; }\n );\n }\n });\n } catch (e) { util.throwError('unable to clean logs from database.'); }\n }\n\n /**\n * delete log database\n * @method clean\n * @static\n */\n static clean() {\n if (WebsqlLogger.status !== super.STATUS.INITED) {\n WebsqlLogger._pool.push(() => WebsqlLogger.clean());\n return;\n }\n\n try {\n WebsqlLogger._db.transaction(tx => {\n tx.executeSql(\n 'DROP TABLE logs', [],\n () => {\n delete WebsqlLogger.status;\n },\n (tx, e) => { throw e.message; }\n );\n });\n } catch (e) { util.throwError('unable to clean log database.'); }\n }\n\n /**\n * detect support situation\n * @prop {Boolean} support\n */\n static get support() {\n return 'openDatabase' in window;\n }\n}\n","import Interface from './protocols/interface';\nimport IndexeddbLogger from './protocols/indexeddb';\nimport LocalstorageLogger from './protocols/localstorage';\nimport WebsqlLogger from './protocols/websql';\nimport * as util from './lib/util';\n\n\nclass Logline {\n /**\n * Logline constructor\n * @constructor\n * @param {String} namespace - namespace to use\n * @return {Object Protocol Instance}\n */\n constructor(namespace) {\n Logline._checkProtocol();\n return new Logline._protocol(namespace);\n }\n\n /**\n * choose a protocol to initialize\n * @method _initProtocol\n * @private\n * @static\n * @param {Object Protocol Class} protocol - protocol to use, must under Logline.PROTOCOL\n * @return {Object} Logline\n */\n static _initProtocol(protocol) {\n Logline._protocol = protocol;\n Logline._protocol.init(Logline._database || 'logline');\n }\n\n /**\n * check protocol\n * if no protocol is chosen, will try to choose an available one automatically\n * if none of the protocols is available, an error will be thrown\n * @method _checkProtocol\n * @private\n * @static\n */\n static _checkProtocol() {\n if (!Logline._protocol) {\n let protocols = Object.keys(Logline.PROTOCOL), protocol;\n while ((protocol = Logline.PROTOCOL[protocols.shift()])) {\n if (protocol.support) {\n Logline._initProtocol(protocol);\n return;\n }\n }\n\n throw new Error(protocols.join(', ').toLowerCase() + ' protocols are not supported on this platform');\n }\n }\n\n /**\n * get logs in range\n * if from and end is not defined, will fetch full log\n * @method get\n * @static\n * @param {String} [from] - time from\n * @param {String} [to] - time end\n * @param {Function} readyFn - function to call back with logs as parameter\n */\n static get(from, to, readyFn) {\n var now = Date.now();\n Logline._checkProtocol();\n\n switch (arguments.length) {\n case 1:\n readyFn = from;\n from = undefined;\n break;\n case 2:\n readyFn = to;\n to = undefined;\n break;\n case 3:\n default:\n break;\n }\n\n Logline._protocol.get(from, to, readyFn);\n }\n\n /**\n * read all logs\n * @method all\n * @static\n * @param {Function} readyFn - function to call back with logs as parameter\n */\n static all(readyFn) {\n Logline.get(readyFn);\n }\n\n /**\n * clean up logs = keep limited logs\n * @method keep\n * @static\n * @param {String} daysToMaintain - specialfy days to keep, support human readable format such as '3d', '.3'\n * @return {Object} Logline\n */\n static keep(daysToMaintain) {\n Logline._checkProtocol();\n Logline._protocol.keep(daysToMaintain);\n return this;\n }\n\n /**\n * delete log database\n * @method clean\n * @static\n * @return {Object} Logline\n */\n static clean() {\n Logline._checkProtocol();\n Logline._protocol.clean();\n return this;\n }\n\n /**\n * choose a protocol\n * @method using\n * @static\n * @param {Object Protocol Class} protocol - wanted protocol, should be on of Logline.PROTOCOL\n * @param {String} [database] - custome database name\n * @return {Object} Logline\n */\n static using(protocol, database) {\n // protocol unavailable is not allowed\n if (-1 === [IndexeddbLogger, LocalstorageLogger, WebsqlLogger].indexOf(protocol)) {\n util.throwError('specialfied protocol ' + (protocol ? (protocol + ' ') : '') + 'is not available');\n }\n\n // once protocol is selected, it shall not be changed during runtime\n if (Logline._protocol) {\n return this;\n }\n\n Logline.database(database || Logline._database);\n Logline._initProtocol(protocol);\n return this;\n }\n\n /**\n * specialfy a custome database name, in case of any conflicts\n * @methd database\n * @static\n * @param {String} name - target database name\n */\n static database(name) {\n Logline._database = name;\n }\n}\n\n// export protocols for modification and mounting\nLogline.PROTOCOL = {\n INDEXEDDB: IndexeddbLogger,\n LOCALSTORAGE: LocalstorageLogger,\n WEBSQL: WebsqlLogger\n};\n\n// export protocol interface for user custom implements\nLogline.INTERFACE = Object.freeze(Interface);\n\nexport default Logline;\n"],"names":["throwError","errMessage","Error","Interface","namespace","_namesapce","level","descriptor","data","args","_record","database","time","relative","test","TypeError","Date","now","replace","from","to","readyFn","daysToMaintain","Pool","_pool","handler","context","push","this","shift","call","IndexedDBLogger","status","LoggerInterface","STATUS","INITED","_this2","INITING","init","transaction","db","IDBTransaction","READ_WRITE","onerror","util","event","target","error","store","objectStore","request","add","FAILED","support","_database","babelHelpers.get","window","indexedDB","open","onsuccess","result","consume","onupgradeneeded","createObjectStore","autoIncrement","createIndex","unique","get","transTimeFormat","_getTransactionStore","READ_ONLY","openCursor","logs","cursor","value","continue","keep","range","delete","primaryKey","clear","clean","close","deleteDatabase","mode","IDBKeyRange","LocalStorageLogger","localStorage","getItem","JSON","parse","setItem","stringify","e","i","length","filter","log","removeItem","WebsqlLogger","_db","executeSql","undefined","tx","message","openDatabase","res","line","item","index","rows","Logline","_checkProtocol","_protocol","protocol","protocols","Object","keys","PROTOCOL","_initProtocol","join","toLowerCase","arguments","IndexeddbLogger","LocalstorageLogger","indexOf","name","INTERFACE","freeze"],"mappings":"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"} \ No newline at end of file diff --git a/src/logline.js b/src/logline.js index f9e64ef..55666f6 100644 --- a/src/logline.js +++ b/src/logline.js @@ -62,20 +62,21 @@ class Logline { * @param {Function} readyFn - function to call back with logs as parameter */ static get(from, to, readyFn) { + var now = Date.now(); Logline._checkProtocol(); switch (arguments.length) { - case 1: - readyFn = from; - from = undefined; - break; - case 2: - readyFn = to; - to = undefined; - break; - case 3: - default: - break; + case 1: + readyFn = from; + from = undefined; + break; + case 2: + readyFn = to; + to = undefined; + break; + case 3: + default: + break; } Logline._protocol.get(from, to, readyFn); From d3b53987e74834a12ecdbbd84311116cbbbc2017 Mon Sep 17 00:00:00 2001 From: kevinnwang Date: Wed, 1 Mar 2017 13:10:52 +0800 Subject: [PATCH 3/6] output recording logs in developer tool's console --- CHANGELOG | 4 ++++ TODO | 10 +++++----- src/lib/util.js | 22 ++++++++++++++++++++++ src/protocols/indexeddb.js | 3 ++- src/protocols/interface.js | 2 +- src/protocols/localstorage.js | 3 ++- src/protocols/websql.js | 3 ++- 7 files changed, 38 insertions(+), 9 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index a015504..87cb2f8 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,7 @@ +v1.0.5 +A output logs in developer tool's console +F IndexedDB: unable to remove special targeted logs + v1.0.4 U use rollup.js bundler to reduce dist package size(33% off) A add makefile, use make for automatic procedures diff --git a/TODO b/TODO index 40e5b25..89563c1 100644 --- a/TODO +++ b/TODO @@ -1,8 +1,8 @@ WIP -none +[ ] IndexedDB: cursor.continue() meet `throw InvalidStateError when the cursor is being iterated` CONSIDERING -[ ] fullfill error handling LOW -[ ] 修复phantomjs无法正确测试indexeddb的问题,phantomjs在关闭数据后才能读取到新存储的内容 LOW -[ ] add a tag, to indicate pending operations LOW -[ ] ability to get desired NICE TO HAVE +[ ] fullfill error handling +[ ] 修复phantomjs无法正确测试indexeddb的问题,phantomjs在关闭数据后才能读取到新存储的内容 +[ ] add a tag, to indicate pending operations +[ ] selecte random background color per namespace for the outpus on developer tool's console panel diff --git a/src/lib/util.js b/src/lib/util.js index 528606f..06a03dd 100644 --- a/src/lib/util.js +++ b/src/lib/util.js @@ -1,4 +1,26 @@ +const HAS_CONSOLE = window.console; +const LEVEL_CONSOLE_MAP = { + INFO: 'log', + WARN: 'warn', + ERROR: 'error', + CRITICAL: 'error' +}; +const LEVEL_STYLE_MAP = { + INFO: 'color:#FFF;background:gray', + WARN: 'color:#FFF;background:orange', + ERROR: 'color:#FFF;background:red', + CRITICAL: 'color:#FFF;background:black' +}; + // throw out Errors, with global prefix 'Logline: ' ahead of err.message export function throwError(errMessage) { throw new Error('Logline: ' + errMessage); } + +// print debug info in develper's console +// if WechatFE/vConsole is detected, will not use %c feature, as it is not well supported +export function debug(namespace, level, descriptor, data) { + if (HAS_CONSOLE) { + window.console[LEVEL_CONSOLE_MAP[level.toUpperCase()] || LEVEL_CONSOLE_MAP.INFO]('%c %s %s %c %s ' + (typeof data === 'object' ? '%O' : '%s'), LEVEL_STYLE_MAP[level.toUpperCase()] || LEVEL_STYLE_MAP.INFO, level, namespace, 'color:initial', descriptor, data || ''); + } +} diff --git a/src/protocols/indexeddb.js b/src/protocols/indexeddb.js index 3c6a241..a0b5099 100644 --- a/src/protocols/indexeddb.js +++ b/src/protocols/indexeddb.js @@ -33,13 +33,14 @@ export default class IndexedDBLogger extends LoggerInterface { return; } + util.debug(this._namespace, level, descriptor, data); let transaction = IndexedDBLogger.db.transaction(['logs'], IDBTransaction.READ_WRITE || 'readwrite'); transaction.onerror = event => util.throwError(event.target.error); let store = transaction.objectStore('logs'); let request = store.add({ time: Date.now(), - namespace: this._namesapce, + namespace: this._namespace, descriptor: descriptor, data: data }); diff --git a/src/protocols/interface.js b/src/protocols/interface.js index b03bfb8..9ac5ea2 100644 --- a/src/protocols/interface.js +++ b/src/protocols/interface.js @@ -11,7 +11,7 @@ export default class Interface { * @param {String} namespace - namespace to use */ constructor(namespace) { - this._namesapce = namespace; + this._namespace = namespace; } /** diff --git a/src/protocols/localstorage.js b/src/protocols/localstorage.js index 7b71990..aea0efb 100644 --- a/src/protocols/localstorage.js +++ b/src/protocols/localstorage.js @@ -27,12 +27,13 @@ export default class LocalStorageLogger extends LoggerInterface { var logs = window.localStorage.getItem(LocalStorageLogger._database) ? JSON.parse(window.localStorage.getItem(LocalStorageLogger._database)) : []; logs.push([ Date.now(), - this._namesapce, + this._namespace, level, descriptor, data ]); try { + util.debug(this._namespace, level, descriptor, data); window.localStorage.setItem(LocalStorageLogger._database, JSON.stringify(logs)); } catch (e) { util.throwError('error inserting record'); } } diff --git a/src/protocols/websql.js b/src/protocols/websql.js index 04ebedb..07de2c2 100644 --- a/src/protocols/websql.js +++ b/src/protocols/websql.js @@ -34,10 +34,11 @@ export default class WebsqlLogger extends LoggerInterface { } try { + util.debug(this._namespace, level, descriptor, data); WebsqlLogger._db.transaction(tx => { tx.executeSql( 'INSERT INTO logs (time, namespace, level, descriptor, data) VALUES(?, ?, ?, ? ,?)', - [Date.now(), this._namesapce, level, descriptor, (data === undefined || data === '') ? '' : (JSON.stringify(data) || '')], + [Date.now(), this._namespace, level, descriptor, (data === undefined || data === '') ? '' : (JSON.stringify(data) || '')], () => {/* empty func */}, (tx, e) => { throw e.message; } ); From 241926a43f6a2b77095444e942389cc12929be65 Mon Sep 17 00:00:00 2001 From: kevinnwang Date: Wed, 1 Mar 2017 15:51:50 +0800 Subject: [PATCH 4/6] IndexedDB: fix errors adding record with an object which contains functions --- src/lib/util.js | 18 ++++++++++++++++++ src/protocols/indexeddb.js | 4 +++- 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/src/lib/util.js b/src/lib/util.js index 06a03dd..9ec6a7a 100644 --- a/src/lib/util.js +++ b/src/lib/util.js @@ -24,3 +24,21 @@ export function debug(namespace, level, descriptor, data) { window.console[LEVEL_CONSOLE_MAP[level.toUpperCase()] || LEVEL_CONSOLE_MAP.INFO]('%c %s %s %c %s ' + (typeof data === 'object' ? '%O' : '%s'), LEVEL_STYLE_MAP[level.toUpperCase()] || LEVEL_STYLE_MAP.INFO, level, namespace, 'color:initial', descriptor, data || ''); } } + +// filter any function in a object +export function filterFunction(obj) { + var newObj = {}, i; + + if (typeof obj !== 'object') { + return obj; + } + + for (i in obj) { + if (obj.hasOwnProperty(i)) { + if (typeof obj[i] !== 'function') { + newObj[i] = filterFunction(obj[i]); + } + } + } + return newObj; +} diff --git a/src/protocols/indexeddb.js b/src/protocols/indexeddb.js index a0b5099..985a7ae 100644 --- a/src/protocols/indexeddb.js +++ b/src/protocols/indexeddb.js @@ -38,11 +38,13 @@ export default class IndexedDBLogger extends LoggerInterface { transaction.onerror = event => util.throwError(event.target.error); let store = transaction.objectStore('logs'); + // should not contains any function in data + // otherwise 'DOMException: Failed to execute 'add' on 'IDBObjectStore': An object could not be cloned.' will be thrown let request = store.add({ time: Date.now(), namespace: this._namespace, descriptor: descriptor, - data: data + data: util.filterFunction(data) }); request.onerror = event => { From 647ffd5d4e998e3e8612c8af47e07e3039785bd0 Mon Sep 17 00:00:00 2001 From: kevinnwang Date: Thu, 2 Mar 2017 09:28:30 +0800 Subject: [PATCH 5/6] adjust debug infomations --- README.md | 9 ++++----- README.zh_CN.md | 12 +++++------- src/lib/util.js | 2 +- 3 files changed, 10 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index e270996..801e037 100644 --- a/README.md +++ b/README.md @@ -41,11 +41,10 @@ Features ------- + No extra dependencies -+ Record logs -+ Client-side -+ websql, localstorage and indexeddb protocol -+ namespace -+ degree ++ client-side(reach when acctually needed, save bandwith and traffic) ++ multiple filter dimension(namespace, degree and keyword) ++ multiple persistence storage solution(IndexDB, Websql, localStorage) ++ cleanable(in case take too much user space) Quick to get started ------------------- diff --git a/README.zh_CN.md b/README.zh_CN.md index 62dff16..10050c6 100644 --- a/README.zh_CN.md +++ b/README.zh_CN.md @@ -32,13 +32,11 @@ logline是一个轻量,实用和客户端级的前端日志记录工具。 特性 --- -+ 无外部依赖 -+ 日志记录 -+ 客户端级 -+ websql/localstorage/indexeddb三种日志协议 -+ 命名空间 -+ 日志等级 -+ 日志清理(防止日志过多,占用上传带宽和占满用户允许的内存) ++ 零外部依赖 ++ 客户端存放(需要时再获取,节省移动带宽、流量和连接数) ++ 多维度过滤(命名空间、日志等级和关键词) ++ 多个存储方案(Websql、localStorage和IndexedDB) ++ 可清理(防止日志过多,占用上传带宽和占满用户允许的内存) 快速上手 ------ diff --git a/src/lib/util.js b/src/lib/util.js index 9ec6a7a..8d43f1f 100644 --- a/src/lib/util.js +++ b/src/lib/util.js @@ -21,7 +21,7 @@ export function throwError(errMessage) { // if WechatFE/vConsole is detected, will not use %c feature, as it is not well supported export function debug(namespace, level, descriptor, data) { if (HAS_CONSOLE) { - window.console[LEVEL_CONSOLE_MAP[level.toUpperCase()] || LEVEL_CONSOLE_MAP.INFO]('%c %s %s %c %s ' + (typeof data === 'object' ? '%O' : '%s'), LEVEL_STYLE_MAP[level.toUpperCase()] || LEVEL_STYLE_MAP.INFO, level, namespace, 'color:initial', descriptor, data || ''); + window.console[LEVEL_CONSOLE_MAP[level.toUpperCase()] || LEVEL_CONSOLE_MAP.INFO]('%c %s %s %c %s. ' + (typeof data === 'object' ? '%O' : '%s'), LEVEL_STYLE_MAP[level.toUpperCase()] || LEVEL_STYLE_MAP.INFO, level, namespace, 'color:initial', descriptor, data || ''); } } From f925b69b66a79f2b1dbe1b9a1382ed8765f87514 Mon Sep 17 00:00:00 2001 From: kevinnwang Date: Thu, 2 Mar 2017 18:19:46 +0800 Subject: [PATCH 6/6] build for release v1.0.5 --- dist/logline.js | 82 ++++++++++++++++++++++++++++++++++++----- dist/logline.min.js | 4 +- dist/logline.min.js.map | 2 +- package.json | 2 +- 4 files changed, 76 insertions(+), 14 deletions(-) diff --git a/dist/logline.js b/dist/logline.js index 1ca3225..52b0fef 100644 --- a/dist/logline.js +++ b/dist/logline.js @@ -1,5 +1,5 @@ /** - * logline v1.0.4 (https://github.com/latel/logline#readme) + * logline v1.0.5 (https://github.com/latel/logline#readme) * Copyright 2017, latel * MIT license */ @@ -10,10 +10,21 @@ (global.Logline = factory()); }(this, (function () { 'use strict'; -// throw out Errors, with global prefix 'Logline: ' ahead of err.message -function throwError(errMessage) { - throw new Error('Logline: ' + errMessage); -} +var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { + return typeof obj; +} : function (obj) { + return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; +}; + + + + + + + + + + var classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { @@ -104,6 +115,52 @@ var possibleConstructorReturn = function (self, call) { return call && (typeof call === "object" || typeof call === "function") ? call : self; }; +var HAS_CONSOLE = window.console; +var LEVEL_CONSOLE_MAP = { + INFO: 'log', + WARN: 'warn', + ERROR: 'error', + CRITICAL: 'error' +}; +var LEVEL_STYLE_MAP = { + INFO: 'color:#FFF;background:gray', + WARN: 'color:#FFF;background:orange', + ERROR: 'color:#FFF;background:red', + CRITICAL: 'color:#FFF;background:black' +}; + +// throw out Errors, with global prefix 'Logline: ' ahead of err.message +function throwError(errMessage) { + throw new Error('Logline: ' + errMessage); +} + +// print debug info in develper's console +// if WechatFE/vConsole is detected, will not use %c feature, as it is not well supported +function debug(namespace, level, descriptor, data) { + if (HAS_CONSOLE) { + window.console[LEVEL_CONSOLE_MAP[level.toUpperCase()] || LEVEL_CONSOLE_MAP.INFO]('%c %s %s %c %s. ' + ((typeof data === 'undefined' ? 'undefined' : _typeof(data)) === 'object' ? '%O' : '%s'), LEVEL_STYLE_MAP[level.toUpperCase()] || LEVEL_STYLE_MAP.INFO, level, namespace, 'color:initial', descriptor, data || ''); + } +} + +// filter any function in a object +function filterFunction(obj) { + var newObj = {}, + i; + + if ((typeof obj === 'undefined' ? 'undefined' : _typeof(obj)) !== 'object') { + return obj; + } + + for (i in obj) { + if (obj.hasOwnProperty(i)) { + if (typeof obj[i] !== 'function') { + newObj[i] = filterFunction(obj[i]); + } + } + } + return newObj; +} + /** * Logline Interface * @class Interface @@ -118,7 +175,7 @@ var Interface = function () { function Interface(namespace) { classCallCheck(this, Interface); - this._namesapce = namespace; + this._namespace = namespace; } /** @@ -400,17 +457,20 @@ var IndexedDBLogger = function (_LoggerInterface) { return; } + debug(this._namespace, level, descriptor, data); var transaction = IndexedDBLogger.db.transaction(['logs'], IDBTransaction.READ_WRITE || 'readwrite'); transaction.onerror = function (event) { return throwError(event.target.error); }; var store = transaction.objectStore('logs'); + // should not contains any function in data + // otherwise 'DOMException: Failed to execute 'add' on 'IDBObjectStore': An object could not be cloned.' will be thrown var request = store.add({ time: Date.now(), - namespace: this._namesapce, + namespace: this._namespace, descriptor: descriptor, - data: data + data: filterFunction(data) }); request.onerror = function (event) { @@ -660,8 +720,9 @@ var LocalStorageLogger = function (_LoggerInterface) { key: '_record', value: function _record(level, descriptor, data) { var logs = window.localStorage.getItem(LocalStorageLogger._database) ? JSON.parse(window.localStorage.getItem(LocalStorageLogger._database)) : []; - logs.push([Date.now(), this._namesapce, level, descriptor, data]); + logs.push([Date.now(), this._namespace, level, descriptor, data]); try { + debug(this._namespace, level, descriptor, data); window.localStorage.setItem(LocalStorageLogger._database, JSON.stringify(logs)); } catch (e) { throwError('error inserting record'); @@ -817,8 +878,9 @@ var WebsqlLogger = function (_LoggerInterface) { } try { + debug(this._namespace, level, descriptor, data); WebsqlLogger._db.transaction(function (tx) { - tx.executeSql('INSERT INTO logs (time, namespace, level, descriptor, data) VALUES(?, ?, ?, ? ,?)', [Date.now(), _this2._namesapce, level, descriptor, data === undefined || data === '' ? '' : JSON.stringify(data) || ''], function () {/* empty func */}, function (tx, e) { + tx.executeSql('INSERT INTO logs (time, namespace, level, descriptor, data) VALUES(?, ?, ?, ? ,?)', [Date.now(), _this2._namespace, level, descriptor, data === undefined || data === '' ? '' : JSON.stringify(data) || ''], function () {/* empty func */}, function (tx, e) { throw e.message; }); }); diff --git a/dist/logline.min.js b/dist/logline.min.js index 2041704..9a30132 100644 --- a/dist/logline.min.js +++ b/dist/logline.min.js @@ -1,8 +1,8 @@ /** - * logline v1.0.4 (https://github.com/latel/logline#readme) + * logline v1.0.5 (https://github.com/latel/logline#readme) * Copyright 2017, latel * MIT license */ -!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):t.Logline=e()}(this,function(){"use strict";function t(t){throw new Error("Logline: "+t)}var e=function(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")},o=function(){function t(t,e){for(var o=0;oo)&&r.continue(),u.push({time:r.value.time,namespace:r.value.namespace,descriptor:r.value.descriptor,data:r.value.data}),r.continue()):n(u)},c.onerror=function(e){return t("failed to literat on logs from database.")}}},{key:"keep",value:function(e){if(s.status!==r(s.__proto__||Object.getPrototypeOf(s),"STATUS",this).INITED)return s._pool.push(function(){return s.keep(e)});var o=s._getTransactionStore(IDBTransaction.READ_WRITE);if(e)!function(){var r=Date.now()-24*(e||2)*3600*1e3,n=o.openCursor();n.onsuccess=function(t){var e=t.target.result;e&&e.value.timee||(n[r]={time:n[r][0],namespace:n[r][1],level:n[r][2],descriptor:n[r][3],data:n[r][4]});o(n)}},{key:"keep",value:function(t){var e=t?(window.localStorage.getItem(u._database)?JSON.parse(window.localStorage.getItem(u._database)):[]).filter(function(e){return e.time>=Date.now()-24*(t||2)*3600*1e3}):[];window.localStorage.setItem(u._database,JSON.stringify(e))}},{key:"clean",value:function(){delete u.status,window.localStorage.removeItem(u._database)}},{key:"support",get:function(){return"localStorage"in window}}]),u}(i),l=function(u){function s(){var t;e(this,s);for(var o=arguments.length,r=Array(o),n=0;n=0;)if(i=r.rows.item(u),!(e&&i.timeo)){a=JSON.parse(JSON.stringify(i));try{a.data=JSON.parse(a.data)}catch(t){}c.push(a)}n(c)},function(t,e){throw e.message})})}catch(e){t("unable to collect logs from database.")}}},{key:"keep",value:function(e){if(s.status!==r(s.__proto__||Object.getPrototypeOf(s),"STATUS",this).INITED)return s._pool.push(function(){return s.keep(e)});try{s._db.transaction(function(t){e?t.executeSql("DELETE FROM logs WHERE time < ?",[Date.now()-24*(e||2)*3600*1e3],function(){},function(t,e){throw e.message}):t.executeSql("DELETE FROM logs",[],function(){},function(t,e){throw e.message})})}catch(e){t("unable to clean logs from database.")}}},{key:"clean",value:function(){if(s.status!==r(s.__proto__||Object.getPrototypeOf(s),"STATUS",this).INITED)return void s._pool.push(function(){return s.clean()});try{s._db.transaction(function(t){t.executeSql("DROP TABLE logs",[],function(){delete s.status},function(t,e){throw e.message})})}catch(e){t("unable to clean log database.")}}},{key:"support",get:function(){return"openDatabase"in window}}]),s}(i),f=function(){function r(t){return e(this,r),r._checkProtocol(),new r._protocol(t)}return o(r,null,[{key:"_initProtocol",value:function(t){r._protocol=t,r._protocol.init(r._database||"logline")}},{key:"_checkProtocol",value:function(){if(!r._protocol){for(var t=Object.keys(r.PROTOCOL),e=void 0;e=r.PROTOCOL[t.shift()];)if(e.support)return void r._initProtocol(e);throw new Error(t.join(", ").toLowerCase()+" protocols are not supported on this platform")}}},{key:"get",value:function(t,e,o){Date.now();switch(r._checkProtocol(),arguments.length){case 1:o=t,t=void 0;break;case 2:o=e,e=void 0;break;case 3:}r._protocol.get(t,e,o)}},{key:"all",value:function(t){r.get(t)}},{key:"keep",value:function(t){return r._checkProtocol(),r._protocol.keep(t),this}},{key:"clean",value:function(){return r._checkProtocol(),r._protocol.clean(),this}},{key:"using",value:function(e,o){return-1===[u,s,l].indexOf(e)&&t("specialfied protocol "+(e?e+" ":"")+"is not available"),r._protocol?this:(r.database(o||r._database),r._initProtocol(e),this)}},{key:"database",value:function(t){r._database=t}}]),r}();return f.PROTOCOL={INDEXEDDB:u,LOCALSTORAGE:s,WEBSQL:l},f.INTERFACE=Object.freeze(i),f}); +!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):t.Logline=e()}(this,function(){"use strict";function t(t){throw new Error("Logline: "+t)}function e(t,e,o,r){s&&window.console[l[e.toUpperCase()]||l.INFO]("%c %s %s %c %s. "+("object"===("undefined"==typeof r?"undefined":n(r))?"%O":"%s"),f[e.toUpperCase()]||f.INFO,e,t,"color:initial",o,r||"")}function o(t){var e,r={};if("object"!==("undefined"==typeof t?"undefined":n(t)))return t;for(e in t)t.hasOwnProperty(e)&&"function"!=typeof t[e]&&(r[e]=o(t[e]));return r}var n="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},r=function(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")},a=function(){function t(t,e){for(var o=0;oo)&&r.continue(),c.push({time:r.value.time,namespace:r.value.namespace,descriptor:r.value.descriptor,data:r.value.data}),r.continue()):n(c)},a.onerror=function(e){return t("failed to literat on logs from database.")}}},{key:"keep",value:function(e){if(s.status!==i(s.__proto__||Object.getPrototypeOf(s),"STATUS",this).INITED)return s._pool.push(function(){return s.keep(e)});var o=s._getTransactionStore(IDBTransaction.READ_WRITE);if(e)!function(){var n=Date.now()-24*(e||2)*3600*1e3,r=o.openCursor();r.onsuccess=function(t){var e=t.target.result;e&&e.value.timee||(a[r]={time:a[r][0],namespace:a[r][1],level:a[r][2],descriptor:a[r][3],data:a[r][4]});o(a)}},{key:"keep",value:function(t){var e=t?(window.localStorage.getItem(n._database)?JSON.parse(window.localStorage.getItem(n._database)):[]).filter(function(e){return e.time>=Date.now()-24*(t||2)*3600*1e3}):[];window.localStorage.setItem(n._database,JSON.stringify(e))}},{key:"clean",value:function(){delete n.status,window.localStorage.removeItem(n._database)}},{key:"support",get:function(){return"localStorage"in window}}]),n}(p),g=function(o){function n(){var t;r(this,n);for(var e=arguments.length,o=Array(e),a=0;a=0;)if(i=n.rows.item(u),!(e&&i.timeo)){a=JSON.parse(JSON.stringify(i));try{a.data=JSON.parse(a.data)}catch(t){}c.push(a)}r(c)},function(t,e){throw e.message})})}catch(e){t("unable to collect logs from database.")}}},{key:"keep",value:function(e){if(n.status!==i(n.__proto__||Object.getPrototypeOf(n),"STATUS",this).INITED)return n._pool.push(function(){return n.keep(e)});try{n._db.transaction(function(t){e?t.executeSql("DELETE FROM logs WHERE time < ?",[Date.now()-24*(e||2)*3600*1e3],function(){},function(t,e){throw e.message}):t.executeSql("DELETE FROM logs",[],function(){},function(t,e){throw e.message})})}catch(e){t("unable to clean logs from database.")}}},{key:"clean",value:function(){if(n.status!==i(n.__proto__||Object.getPrototypeOf(n),"STATUS",this).INITED)return void n._pool.push(function(){return n.clean()});try{n._db.transaction(function(t){t.executeSql("DROP TABLE logs",[],function(){delete n.status},function(t,e){throw e.message})})}catch(e){t("unable to clean log database.")}}},{key:"support",get:function(){return"openDatabase"in window}}]),n}(p),h=function(){function e(t){return r(this,e),e._checkProtocol(),new e._protocol(t)}return a(e,null,[{key:"_initProtocol",value:function(t){e._protocol=t,e._protocol.init(e._database||"logline")}},{key:"_checkProtocol",value:function(){if(!e._protocol){for(var t=Object.keys(e.PROTOCOL),o=void 0;o=e.PROTOCOL[t.shift()];)if(o.support)return void e._initProtocol(o);throw new Error(t.join(", ").toLowerCase()+" protocols are not supported on this platform")}}},{key:"get",value:function(t,o,n){Date.now();switch(e._checkProtocol(),arguments.length){case 1:n=t,t=void 0;break;case 2:n=o,o=void 0;break;case 3:}e._protocol.get(t,o,n)}},{key:"all",value:function(t){e.get(t)}},{key:"keep",value:function(t){return e._checkProtocol(),e._protocol.keep(t),this}},{key:"clean",value:function(){return e._checkProtocol(),e._protocol.clean(),this}},{key:"using",value:function(o,n){return-1===[_,y,g].indexOf(o)&&t("specialfied protocol "+(o?o+" ":"")+"is not available"),e._protocol?this:(e.database(n||e._database),e._initProtocol(o),this)}},{key:"database",value:function(t){e._database=t}}]),e}();return h.PROTOCOL={INDEXEDDB:_,LOCALSTORAGE:y,WEBSQL:g},h.INTERFACE=Object.freeze(p),h}); //# sourceMappingURL=logline.min.js.map diff --git a/dist/logline.min.js.map b/dist/logline.min.js.map index 0add508..059e882 100644 --- a/dist/logline.min.js.map +++ b/dist/logline.min.js.map @@ -1 +1 @@ -{"version":3,"file":"logline.min.js","sources":["../src/lib/util.js","../src/protocols/interface.js","../src/lib/pool.js","../src/protocols/indexeddb.js","../src/protocols/localstorage.js","../src/protocols/websql.js","../src/logline.js"],"sourcesContent":["// throw out Errors, with global prefix 'Logline: ' ahead of err.message\nexport function throwError(errMessage) {\n throw new Error('Logline: ' + errMessage);\n}\n","import * as util from '../lib/util';\n\n/**\n * Logline Interface\n * @class Interface\n */\nexport default class Interface {\n /**\n * Logline constructor\n * @constructor\n * @param {String} namespace - namespace to use\n */\n constructor(namespace) {\n this._namesapce = namespace;\n }\n\n /**\n * add a log record\n * @method _reocrd\n * @private\n * @parma {String} level - log level\n * @param {String} descriptor - to speed up search and improve understanding\n * @param {Mixed} [data] - additional data\n */\n _record(level, descriptor, data) {\n util.throwError('method _record is not implemented.');\n }\n\n /**\n * add a level-info record\n * @method info\n * @param {String} descriptor - to speed up search and improve understanding\n * @param {Mixed} [data] - additional data\n */\n info(...args) {\n this._record('info', ...args);\n }\n\n /**\n * add a level-warn record\n * @method warn\n * @param {String} descriptor - to speed up search and improve understanding\n * @param {Mixed} [data] - additional data\n */\n warn(...args) {\n this._record('warn', ...args);\n }\n\n /**\n * add a level-error record\n * @method error\n * @param {String} descriptor - to speed up search and improve understanding\n * @param {Mixed} [data] - additional data\n */\n error(...args) {\n this._record('error', ...args);\n }\n\n /**\n * add a level-critical record\n * @method critical\n * @param {String} descriptor - to speed up search and improve understanding\n * @param {Mixed} [data] - additional data\n */\n critical(...args) {\n this._record('critical', ...args);\n }\n\n /**\n * initialize protocol\n * @method init\n * @static\n * @param {String} database - database name to use\n */\n static init(database) {\n return true;\n }\n\n /**\n * transform human readable time string, such as '3d', '.3' and '1.2' into Unix timestamp\n * the default relative time is Date.now(), if no second parameter is provided\n * @method transTimeFormat\n * @static\n * @param {String} time - time string to transform\n * @param {Number} [relative] - relative time to compare, default Date.now()\n * @return {Number|NaN} timestamp transformed\n */\n static transTimeFormat(time, relative) {\n // if falsy value or timestamp already, pass it through directly,\n if (!time || /^\\d{13}$/.test(time)) {\n return +time;\n }\n // incase relative time isn't unix timestamp format,\n // neither a falsy value which will turned out to be Date.now()\n if (relative && !/^\\d{13}$/.test(relative)) {\n throw new TypeError('relative time should be standard unix timestamp');\n }\n\n return (relative || Date.now()) - time.replace(/d$/, '') * 24 * 3600 * 1000;\n }\n\n /**\n * get logs in range\n * if from and end is not defined, will fetch full log\n * @method get\n * @static\n * @param {String} from - time from, unix timestamp\n * @param {String} to - time end, unix timestamp\n * @param {Function} readyFn - function to call back with logs as parameter\n */\n static get(from, to, readyFn) {\n util.throwError('method get is not implemented.');\n }\n\n /**\n * clean logs = keep limited logs\n * @method keep\n * @static\n * @param {Number} daysToMaintain - keep logs within days\n */\n static keep(daysToMaintain) {\n util.throwError('method keep is not implemented.');\n }\n\n /**\n * delete log database\n * @method clean\n * @static\n */\n static clean() {\n util.throwError('method clean is not implemented.');\n }\n\n /**\n * protocol status map\n * @prop {Object} STATUS\n */\n static get STATUS() {\n return {\n INITING: 1,\n INITED: 2,\n FAILED: 4\n };\n }\n}\n","/**\n * Pool, for storage of async calling\n * @class Pool\n */\nexport default class Pool {\n /**\n * Pool constructor\n * @constructor\n */\n constructor() {\n this._pool = [];\n }\n\n /**\n * add an procedure\n * @method push\n * @param {Function} handler - procedure handler\n * @param {Object} context - procedure context\n */\n push(handler, context) {\n handler.context = context;\n this._pool.push(handler);\n }\n\n /**\n * consume pool\n * @method consume\n */\n consume() {\n var handler;\n while ((handler = this._pool.shift())) {\n handler.call(handler.context);\n }\n }\n}\n","import LoggerInterface from './interface';\nimport Pool from '../lib/pool';\nimport * as util from '../lib/util';\n\n/**\n * IndexedDB protocol\n * @class IndexedDBLogger\n */\nexport default class IndexedDBLogger extends LoggerInterface {\n /**\n * IndexedDB protocol constructor\n * @constructor\n * @param {String} namespace - namespace to use\n */\n constructor(...args) {\n super(...args);\n }\n\n /**\n * add a log record\n * @method _reocrd\n * @private\n * @parma {String} level - log level\n * @param {String} descriptor - to speed up search and improve understanding\n * @param {Mixed} [data] - additional data\n */\n _record(level, descriptor, data) {\n if (IndexedDBLogger.status !== LoggerInterface.STATUS.INITED) {\n IndexedDBLogger._pool.push(() => this._record(level, descriptor, data));\n if (IndexedDBLogger.status !== LoggerInterface.STATUS.INITING) {\n IndexedDBLogger.init();\n }\n return;\n }\n\n let transaction = IndexedDBLogger.db.transaction(['logs'], IDBTransaction.READ_WRITE || 'readwrite');\n transaction.onerror = event => util.throwError(event.target.error);\n\n let store = transaction.objectStore('logs');\n let request = store.add({\n time: Date.now(),\n namespace: this._namesapce,\n descriptor: descriptor,\n data: data\n });\n\n request.onerror = event => {\n IndexedDBLogger.status = LoggerInterface.STATUS.FAILED;\n util.throwError(event.target.error);\n };\n }\n\n /**\n * initialize protocol\n * @method init\n * @static\n * @param {String} database - database name to use\n */\n static init(database) {\n if (!IndexedDBLogger.support) {\n util.throwError('your platform does not support indexeddb protocol.');\n }\n\n if (IndexedDBLogger.status) {\n return false;\n }\n\n IndexedDBLogger._pool = IndexedDBLogger._pool || new Pool();\n IndexedDBLogger._database = database || 'logline';\n IndexedDBLogger.status = super.STATUS.INITING;\n\n IndexedDBLogger.request = window.indexedDB.open(IndexedDBLogger._database);\n IndexedDBLogger.request.onerror = event => util.throwError('protocol indexeddb is prevented.');\n IndexedDBLogger.request.onsuccess = event => {\n IndexedDBLogger.db = event.target.result;\n IndexedDBLogger.status = super.STATUS.INITED;\n IndexedDBLogger._pool.consume();\n // globally handle db request errors\n IndexedDBLogger.db.onerror = event => util.throwError(event.target.error);\n };\n IndexedDBLogger.request.onupgradeneeded = event => {\n // init dabasebase\n let db = event.target.result, store = db.createObjectStore('logs', { autoIncrement: true });\n store.createIndex('namespace', 'namespace', { unique: false });\n store.createIndex('level', 'level', { unique: false });\n store.createIndex('descriptor', 'descriptor', { unique: false });\n store.createIndex('data', 'data', { unique: false });\n };\n }\n\n /**\n * get logs in range\n * if from and end is not defined, will fetch full log\n * @method get\n * @static\n * @param {String} from - time from, unix time stamp or falsy\n * @param {String} to - time end, unix time stamp or falsy\n * @param {Function} readyFn - function to call back with logs as parameter\n */\n static get(from, to, readyFn) {\n if (IndexedDBLogger.status !== super.STATUS.INITED) {\n return IndexedDBLogger._pool.push(() => IndexedDBLogger.get(from, to, readyFn));\n }\n\n from = LoggerInterface.transTimeFormat(from);\n to = LoggerInterface.transTimeFormat(to);\n\n let store = IndexedDBLogger._getTransactionStore(IDBTransaction.READ_ONLY || 'readonly'),\n request = store.openCursor(),\n logs = [];\n\n request.onsuccess = event => {\n var cursor = event.target.result;\n if (cursor) {\n if ((from && cursor.value.time < from) || (to && cursor.value.time > to)) {\n cursor.continue();\n }\n\n logs.push({\n time: cursor.value.time,\n namespace: cursor.value.namespace,\n descriptor: cursor.value.descriptor,\n data: cursor.value.data\n });\n cursor.continue();\n }\n else {\n readyFn(logs);\n }\n };\n\n request.onerror = event => util.throwError('failed to literat on logs from database.');\n }\n\n /**\n * clean logs = keep limited logs\n * @method keep\n * @static\n * @param {Number} daysToMaintain - keep logs within days\n */\n static keep(daysToMaintain) {\n if (IndexedDBLogger.status !== super.STATUS.INITED) {\n return IndexedDBLogger._pool.push(() => IndexedDBLogger.keep(daysToMaintain));\n }\n\n let store = IndexedDBLogger._getTransactionStore(IDBTransaction.READ_WRITE);\n if (!daysToMaintain) {\n let request = store.clear().onerror = event => util.throwError(event.target.error);\n }\n else {\n let range = (Date.now() - (daysToMaintain || 2) * 24 * 3600 * 1000);\n let request = store.openCursor();\n request.onsuccess = event => {\n let cursor = event.target.result;\n if (cursor && cursor.value.time < range) {\n store.delete(cursor.primaryKey);\n cursor.continue();\n }\n };\n request.onerror = event => util.throwError('unable to locate logs earlier than ' + daysToMaintain + 'd.');\n }\n }\n\n /**\n * delete log database\n * @method clean\n * @static\n */\n static clean() {\n if (IndexedDBLogger.status !== super.STATUS.INITED) {\n return IndexedDBLogger._pool.push(() => IndexedDBLogger.clean());\n }\n\n // database can be removed only after all connections are closed\n IndexedDBLogger.db.close();\n let request = window.indexedDB.deleteDatabase(IndexedDBLogger._database);\n request.onerror = event => util.throwError(event.target.error);\n /* eslint no-unused-vars: \"off\" */\n request.onsuccess = event => {\n delete IndexedDBLogger.status;\n delete IndexedDBLogger.db;\n };\n }\n\n /**\n * get internal transaction store\n * @method _getTransactionStore\n * @private\n * @static\n * @param {String} mode - transaction mode\n * @return {Object} - internal object store\n */\n static _getTransactionStore(mode) {\n if (IndexedDBLogger.db) {\n let transaction = IndexedDBLogger.db.transaction(['logs'], mode || IDBTransaction.READ_WRITE || 'readwrite');\n transaction.onerror = event => util.throwError(event.target.error);\n return transaction.objectStore('logs');\n }\n else {\n util.throwError('log database is not created or connections are closed, considering init it.');\n }\n }\n\n /**\n * detect support situation\n * @prop {Boolean} support\n */\n static get support() {\n return !!(window.indexedDB && window.IDBTransaction && window.IDBKeyRange);\n }\n}\n","import LoggerInterface from './interface';\nimport * as util from '../lib/util';\n\n/**\n * Localstorage protocol\n * @class LocalStorageLogger\n */\nexport default class LocalStorageLogger extends LoggerInterface {\n /**\n * Localstorage protocol constructor\n * @constructor\n * @param {String} namespace - namespace to use\n */\n constructor(...args) {\n super(...args);\n }\n\n /**\n * add a log record\n * @method _reocrd\n * @private\n * @parma {String} level - log level\n * @param {String} descriptor - to speed up search and improve understanding\n * @param {Mixed} [data] - additional data\n */\n _record(level, descriptor, data) {\n var logs = window.localStorage.getItem(LocalStorageLogger._database) ? JSON.parse(window.localStorage.getItem(LocalStorageLogger._database)) : [];\n logs.push([\n Date.now(),\n this._namesapce,\n level,\n descriptor,\n data\n ]);\n try {\n window.localStorage.setItem(LocalStorageLogger._database, JSON.stringify(logs));\n } catch (e) { util.throwError('error inserting record'); }\n }\n\n /**\n * initialize protocol\n * @method init\n * @static\n * @param {String} database - database name to use\n */\n static init(database) {\n if (!LocalStorageLogger.support) {\n util.throwError('your platform does not support localstorage protocol.');\n }\n LocalStorageLogger._database = database || 'logline';\n if (!window.localStorage.getItem(LocalStorageLogger._database)) {\n window.localStorage.setItem(LocalStorageLogger._database, JSON.stringify([]));\n }\n LocalStorageLogger.status = super.STATUS.INITED;\n }\n\n /**\n * get logs in range\n * if from and end is not defined, will fetch full log\n * @method get\n * @static\n * @param {String} from - time from, unix time stamp or falsy\n * @param {String} to - time end, unix time stamp or falsy\n * @param {Function} readyFn - function to call back with logs as parameter\n */\n static get(from, to, readyFn) {\n var logs = JSON.parse(window.localStorage.getItem(LocalStorageLogger._database)), i;\n\n from = LoggerInterface.transTimeFormat(from);\n to = LoggerInterface.transTimeFormat(to);\n\n for (i = 0; i < logs.length; i++) {\n if ((from && logs[i][0] < from) || (to && logs[i][0] > to)) {\n continue;\n }\n\n logs[i] = {\n time: logs[i][0],\n namespace: logs[i][1],\n level: logs[i][2],\n descriptor: logs[i][3],\n data: logs[i][4]\n };\n }\n readyFn(logs);\n }\n\n /**\n * clean logs = keep limited logs\n * @method keep\n * @static\n * @param {Number} daysToMaintain - keep logs within days\n */\n static keep(daysToMaintain) {\n var logs = !daysToMaintain ? [] : (window.localStorage.getItem(LocalStorageLogger._database) ? JSON.parse(window.localStorage.getItem(LocalStorageLogger._database)) : []).filter(log => {\n return log.time >= (Date.now() - (daysToMaintain || 2) * 24 * 3600 * 1000);\n });\n window.localStorage.setItem(LocalStorageLogger._database, JSON.stringify(logs));\n }\n\n /**\n * delete log database\n * @method clean\n * @static\n */\n static clean() {\n delete LocalStorageLogger.status;\n window.localStorage.removeItem(LocalStorageLogger._database);\n }\n\n /**\n * detect support situation\n * @prop {Boolean} support\n */\n static get support() {\n return 'localStorage' in window;\n }\n}\n","import LoggerInterface from './interface';\nimport Pool from '../lib/pool';\nimport * as util from '../lib/util';\n\n/**\n * Websql protocol\n * @class WebsqlLogger\n */\nexport default class WebsqlLogger extends LoggerInterface {\n /**\n * Websql logline constructor\n * @constructor\n * @param {String} namespace - namespace to use\n */\n constructor(...args) {\n super(...args);\n }\n\n /**\n * add a log record\n * @method _reocrd\n * @private\n * @parma {String} level - log level\n * @param {String} descriptor - to speed up search and improve understanding\n * @param {Mixed} [data] - additional data\n */\n _record(level, descriptor, data) {\n if (WebsqlLogger.status !== LoggerInterface.STATUS.INITED) {\n WebsqlLogger._pool.push(() => this._record(level, descriptor, data));\n if (WebsqlLogger.status !== LoggerInterface.STATUS.INITING) {\n WebsqlLogger.init();\n }\n return;\n }\n\n try {\n WebsqlLogger._db.transaction(tx => {\n tx.executeSql(\n 'INSERT INTO logs (time, namespace, level, descriptor, data) VALUES(?, ?, ?, ? ,?)',\n [Date.now(), this._namesapce, level, descriptor, (data === undefined || data === '') ? '' : (JSON.stringify(data) || '')],\n () => {/* empty func */},\n (tx, e) => { throw e.message; }\n );\n });\n } catch (e) { util.throwError('error inserting record'); }\n }\n\n /**\n * initialize protocol\n * @method init\n * @static\n * @param {String} database - database name to use\n */\n static init(database) {\n if (!WebsqlLogger.support) {\n util.throwError(new Error('your platform does not support websql protocol.'));\n }\n\n if (WebsqlLogger.status) {\n return false;\n }\n\n WebsqlLogger._pool = WebsqlLogger._pool || new Pool();\n WebsqlLogger._database = database || 'logline';\n WebsqlLogger.status = super.STATUS.INITING;\n\n try {\n WebsqlLogger._db = window.openDatabase(WebsqlLogger._database, '1.0', 'cats loves logs', 4.85 * 1024 * 1024);\n WebsqlLogger._db.transaction(tx => {\n tx.executeSql(\n 'CREATE TABLE IF NOT EXISTS logs (time, namespace, level, descriptor, data)', [],\n () => {\n WebsqlLogger.status = super.STATUS.INITED;\n WebsqlLogger._pool.consume();\n },\n () => {\n WebsqlLogger.status = super.STATUS.FAILED;\n }\n );\n });\n } catch (e) { util.throwError('unable to init log database.'); }\n }\n\n /**\n * get logs in range\n * if from and end is not defined, will fetch full log\n * @method get\n * @static\n * @param {String} from - time from, unix time stamp or falsy\n * @param {String} to - time end, unix time stamp or falsy\n * @param {Function} readyFn - function to call back with logs as parameter\n */\n static get(from, to, readyFn) {\n if (WebsqlLogger.status !== super.STATUS.INITED) {\n return WebsqlLogger._pool.push(() => WebsqlLogger.get(from, to, readyFn));\n }\n\n from = LoggerInterface.transTimeFormat(from);\n to = LoggerInterface.transTimeFormat(to);\n\n try {\n WebsqlLogger._db.transaction(function(tx) {\n tx.executeSql(\n 'SELECT * FROM logs ORDER BY time DESC', [],\n (tx, res) => {\n var logs = [], line, index = res.rows.length, item;\n while (--index >= 0) {\n item = res.rows.item(index);\n if ((from && item.time < from) || (to && item.time > to)) {\n continue;\n }\n\n // in some devices, properties are configureable: false, writable: false\n // we need deep copy\n line = JSON.parse(JSON.stringify(item));\n // incase data is an object, not a string\n try { line.data = JSON.parse(line.data); }\n catch (e) {/* leave line.data as it be */}\n logs.push(line);\n }\n readyFn(logs);\n },\n (tx, e) => { throw e.message; }\n );\n });\n } catch (e) { util.throwError('unable to collect logs from database.'); }\n }\n\n /**\n * clean logs = keep limited logs\n * @method keep\n * @static\n * @param {Number} daysToMaintain - keep logs within days\n */\n static keep(daysToMaintain) {\n if (WebsqlLogger.status !== super.STATUS.INITED) {\n return WebsqlLogger._pool.push(() => WebsqlLogger.keep(daysToMaintain));\n }\n\n try {\n WebsqlLogger._db.transaction(function(tx) {\n if (daysToMaintain) {\n tx.executeSql(\n 'DELETE FROM logs WHERE time < ?',\n [Date.now() - (daysToMaintain || 2) * 24 * 3600 * 1000],\n function() {/* empty func */},\n function(tx, e) {throw e.message;}\n );\n }\n else {\n tx.executeSql(\n 'DELETE FROM logs', [],\n () => {/* empty func */},\n (tx, e) => { throw e.message; }\n );\n }\n });\n } catch (e) { util.throwError('unable to clean logs from database.'); }\n }\n\n /**\n * delete log database\n * @method clean\n * @static\n */\n static clean() {\n if (WebsqlLogger.status !== super.STATUS.INITED) {\n WebsqlLogger._pool.push(() => WebsqlLogger.clean());\n return;\n }\n\n try {\n WebsqlLogger._db.transaction(tx => {\n tx.executeSql(\n 'DROP TABLE logs', [],\n () => {\n delete WebsqlLogger.status;\n },\n (tx, e) => { throw e.message; }\n );\n });\n } catch (e) { util.throwError('unable to clean log database.'); }\n }\n\n /**\n * detect support situation\n * @prop {Boolean} support\n */\n static get support() {\n return 'openDatabase' in window;\n }\n}\n","import Interface from './protocols/interface';\nimport IndexeddbLogger from './protocols/indexeddb';\nimport LocalstorageLogger from './protocols/localstorage';\nimport WebsqlLogger from './protocols/websql';\nimport * as util from './lib/util';\n\n\nclass Logline {\n /**\n * Logline constructor\n * @constructor\n * @param {String} namespace - namespace to use\n * @return {Object Protocol Instance}\n */\n constructor(namespace) {\n Logline._checkProtocol();\n return new Logline._protocol(namespace);\n }\n\n /**\n * choose a protocol to initialize\n * @method _initProtocol\n * @private\n * @static\n * @param {Object Protocol Class} protocol - protocol to use, must under Logline.PROTOCOL\n * @return {Object} Logline\n */\n static _initProtocol(protocol) {\n Logline._protocol = protocol;\n Logline._protocol.init(Logline._database || 'logline');\n }\n\n /**\n * check protocol\n * if no protocol is chosen, will try to choose an available one automatically\n * if none of the protocols is available, an error will be thrown\n * @method _checkProtocol\n * @private\n * @static\n */\n static _checkProtocol() {\n if (!Logline._protocol) {\n let protocols = Object.keys(Logline.PROTOCOL), protocol;\n while ((protocol = Logline.PROTOCOL[protocols.shift()])) {\n if (protocol.support) {\n Logline._initProtocol(protocol);\n return;\n }\n }\n\n throw new Error(protocols.join(', ').toLowerCase() + ' protocols are not supported on this platform');\n }\n }\n\n /**\n * get logs in range\n * if from and end is not defined, will fetch full log\n * @method get\n * @static\n * @param {String} [from] - time from\n * @param {String} [to] - time end\n * @param {Function} readyFn - function to call back with logs as parameter\n */\n static get(from, to, readyFn) {\n var now = Date.now();\n Logline._checkProtocol();\n\n switch (arguments.length) {\n case 1:\n readyFn = from;\n from = undefined;\n break;\n case 2:\n readyFn = to;\n to = undefined;\n break;\n case 3:\n default:\n break;\n }\n\n Logline._protocol.get(from, to, readyFn);\n }\n\n /**\n * read all logs\n * @method all\n * @static\n * @param {Function} readyFn - function to call back with logs as parameter\n */\n static all(readyFn) {\n Logline.get(readyFn);\n }\n\n /**\n * clean up logs = keep limited logs\n * @method keep\n * @static\n * @param {String} daysToMaintain - specialfy days to keep, support human readable format such as '3d', '.3'\n * @return {Object} Logline\n */\n static keep(daysToMaintain) {\n Logline._checkProtocol();\n Logline._protocol.keep(daysToMaintain);\n return this;\n }\n\n /**\n * delete log database\n * @method clean\n * @static\n * @return {Object} Logline\n */\n static clean() {\n Logline._checkProtocol();\n Logline._protocol.clean();\n return this;\n }\n\n /**\n * choose a protocol\n * @method using\n * @static\n * @param {Object Protocol Class} protocol - wanted protocol, should be on of Logline.PROTOCOL\n * @param {String} [database] - custome database name\n * @return {Object} Logline\n */\n static using(protocol, database) {\n // protocol unavailable is not allowed\n if (-1 === [IndexeddbLogger, LocalstorageLogger, WebsqlLogger].indexOf(protocol)) {\n util.throwError('specialfied protocol ' + (protocol ? (protocol + ' ') : '') + 'is not available');\n }\n\n // once protocol is selected, it shall not be changed during runtime\n if (Logline._protocol) {\n return this;\n }\n\n Logline.database(database || Logline._database);\n Logline._initProtocol(protocol);\n return this;\n }\n\n /**\n * specialfy a custome database name, in case of any conflicts\n * @methd database\n * @static\n * @param {String} name - target database name\n */\n static database(name) {\n Logline._database = name;\n }\n}\n\n// export protocols for modification and mounting\nLogline.PROTOCOL = {\n INDEXEDDB: IndexeddbLogger,\n LOCALSTORAGE: LocalstorageLogger,\n WEBSQL: WebsqlLogger\n};\n\n// export protocol interface for user custom implements\nLogline.INTERFACE = Object.freeze(Interface);\n\nexport default Logline;\n"],"names":["throwError","errMessage","Error","Interface","namespace","_namesapce","level","descriptor","data","args","_record","database","time","relative","test","TypeError","Date","now","replace","from","to","readyFn","daysToMaintain","Pool","_pool","handler","context","push","this","shift","call","IndexedDBLogger","status","LoggerInterface","STATUS","INITED","_this2","INITING","init","transaction","db","IDBTransaction","READ_WRITE","onerror","util","event","target","error","store","objectStore","request","add","FAILED","support","_database","babelHelpers.get","window","indexedDB","open","onsuccess","result","consume","onupgradeneeded","createObjectStore","autoIncrement","createIndex","unique","get","transTimeFormat","_getTransactionStore","READ_ONLY","openCursor","logs","cursor","value","continue","keep","range","delete","primaryKey","clear","clean","close","deleteDatabase","mode","IDBKeyRange","LocalStorageLogger","localStorage","getItem","JSON","parse","setItem","stringify","e","i","length","filter","log","removeItem","WebsqlLogger","_db","executeSql","undefined","tx","message","openDatabase","res","line","item","index","rows","Logline","_checkProtocol","_protocol","protocol","protocols","Object","keys","PROTOCOL","_initProtocol","join","toLowerCase","arguments","IndexeddbLogger","LocalstorageLogger","indexOf","name","INTERFACE","freeze"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"logline.min.js","sources":["../src/lib/util.js","../src/protocols/interface.js","../src/lib/pool.js","../src/protocols/indexeddb.js","../src/protocols/localstorage.js","../src/protocols/websql.js","../src/logline.js"],"sourcesContent":["const HAS_CONSOLE = window.console;\nconst LEVEL_CONSOLE_MAP = {\n INFO: 'log',\n WARN: 'warn',\n ERROR: 'error',\n CRITICAL: 'error'\n};\nconst LEVEL_STYLE_MAP = {\n INFO: 'color:#FFF;background:gray',\n WARN: 'color:#FFF;background:orange',\n ERROR: 'color:#FFF;background:red',\n CRITICAL: 'color:#FFF;background:black'\n};\n\n// throw out Errors, with global prefix 'Logline: ' ahead of err.message\nexport function throwError(errMessage) {\n throw new Error('Logline: ' + errMessage);\n}\n\n// print debug info in develper's console\n// if WechatFE/vConsole is detected, will not use %c feature, as it is not well supported\nexport function debug(namespace, level, descriptor, data) {\n if (HAS_CONSOLE) {\n window.console[LEVEL_CONSOLE_MAP[level.toUpperCase()] || LEVEL_CONSOLE_MAP.INFO]('%c %s %s %c %s. ' + (typeof data === 'object' ? '%O' : '%s'), LEVEL_STYLE_MAP[level.toUpperCase()] || LEVEL_STYLE_MAP.INFO, level, namespace, 'color:initial', descriptor, data || '');\n }\n}\n\n// filter any function in a object\nexport function filterFunction(obj) {\n var newObj = {}, i;\n\n if (typeof obj !== 'object') {\n return obj;\n }\n\n for (i in obj) {\n if (obj.hasOwnProperty(i)) {\n if (typeof obj[i] !== 'function') {\n newObj[i] = filterFunction(obj[i]);\n }\n }\n }\n return newObj;\n}\n","import * as util from '../lib/util';\n\n/**\n * Logline Interface\n * @class Interface\n */\nexport default class Interface {\n /**\n * Logline constructor\n * @constructor\n * @param {String} namespace - namespace to use\n */\n constructor(namespace) {\n this._namespace = namespace;\n }\n\n /**\n * add a log record\n * @method _reocrd\n * @private\n * @parma {String} level - log level\n * @param {String} descriptor - to speed up search and improve understanding\n * @param {Mixed} [data] - additional data\n */\n _record(level, descriptor, data) {\n util.throwError('method _record is not implemented.');\n }\n\n /**\n * add a level-info record\n * @method info\n * @param {String} descriptor - to speed up search and improve understanding\n * @param {Mixed} [data] - additional data\n */\n info(...args) {\n this._record('info', ...args);\n }\n\n /**\n * add a level-warn record\n * @method warn\n * @param {String} descriptor - to speed up search and improve understanding\n * @param {Mixed} [data] - additional data\n */\n warn(...args) {\n this._record('warn', ...args);\n }\n\n /**\n * add a level-error record\n * @method error\n * @param {String} descriptor - to speed up search and improve understanding\n * @param {Mixed} [data] - additional data\n */\n error(...args) {\n this._record('error', ...args);\n }\n\n /**\n * add a level-critical record\n * @method critical\n * @param {String} descriptor - to speed up search and improve understanding\n * @param {Mixed} [data] - additional data\n */\n critical(...args) {\n this._record('critical', ...args);\n }\n\n /**\n * initialize protocol\n * @method init\n * @static\n * @param {String} database - database name to use\n */\n static init(database) {\n return true;\n }\n\n /**\n * transform human readable time string, such as '3d', '.3' and '1.2' into Unix timestamp\n * the default relative time is Date.now(), if no second parameter is provided\n * @method transTimeFormat\n * @static\n * @param {String} time - time string to transform\n * @param {Number} [relative] - relative time to compare, default Date.now()\n * @return {Number|NaN} timestamp transformed\n */\n static transTimeFormat(time, relative) {\n // if falsy value or timestamp already, pass it through directly,\n if (!time || /^\\d{13}$/.test(time)) {\n return +time;\n }\n // incase relative time isn't unix timestamp format,\n // neither a falsy value which will turned out to be Date.now()\n if (relative && !/^\\d{13}$/.test(relative)) {\n throw new TypeError('relative time should be standard unix timestamp');\n }\n\n return (relative || Date.now()) - time.replace(/d$/, '') * 24 * 3600 * 1000;\n }\n\n /**\n * get logs in range\n * if from and end is not defined, will fetch full log\n * @method get\n * @static\n * @param {String} from - time from, unix timestamp\n * @param {String} to - time end, unix timestamp\n * @param {Function} readyFn - function to call back with logs as parameter\n */\n static get(from, to, readyFn) {\n util.throwError('method get is not implemented.');\n }\n\n /**\n * clean logs = keep limited logs\n * @method keep\n * @static\n * @param {Number} daysToMaintain - keep logs within days\n */\n static keep(daysToMaintain) {\n util.throwError('method keep is not implemented.');\n }\n\n /**\n * delete log database\n * @method clean\n * @static\n */\n static clean() {\n util.throwError('method clean is not implemented.');\n }\n\n /**\n * protocol status map\n * @prop {Object} STATUS\n */\n static get STATUS() {\n return {\n INITING: 1,\n INITED: 2,\n FAILED: 4\n };\n }\n}\n","/**\n * Pool, for storage of async calling\n * @class Pool\n */\nexport default class Pool {\n /**\n * Pool constructor\n * @constructor\n */\n constructor() {\n this._pool = [];\n }\n\n /**\n * add an procedure\n * @method push\n * @param {Function} handler - procedure handler\n * @param {Object} context - procedure context\n */\n push(handler, context) {\n handler.context = context;\n this._pool.push(handler);\n }\n\n /**\n * consume pool\n * @method consume\n */\n consume() {\n var handler;\n while ((handler = this._pool.shift())) {\n handler.call(handler.context);\n }\n }\n}\n","import LoggerInterface from './interface';\nimport Pool from '../lib/pool';\nimport * as util from '../lib/util';\n\n/**\n * IndexedDB protocol\n * @class IndexedDBLogger\n */\nexport default class IndexedDBLogger extends LoggerInterface {\n /**\n * IndexedDB protocol constructor\n * @constructor\n * @param {String} namespace - namespace to use\n */\n constructor(...args) {\n super(...args);\n }\n\n /**\n * add a log record\n * @method _reocrd\n * @private\n * @parma {String} level - log level\n * @param {String} descriptor - to speed up search and improve understanding\n * @param {Mixed} [data] - additional data\n */\n _record(level, descriptor, data) {\n if (IndexedDBLogger.status !== LoggerInterface.STATUS.INITED) {\n IndexedDBLogger._pool.push(() => this._record(level, descriptor, data));\n if (IndexedDBLogger.status !== LoggerInterface.STATUS.INITING) {\n IndexedDBLogger.init();\n }\n return;\n }\n\n util.debug(this._namespace, level, descriptor, data);\n let transaction = IndexedDBLogger.db.transaction(['logs'], IDBTransaction.READ_WRITE || 'readwrite');\n transaction.onerror = event => util.throwError(event.target.error);\n\n let store = transaction.objectStore('logs');\n // should not contains any function in data\n // otherwise 'DOMException: Failed to execute 'add' on 'IDBObjectStore': An object could not be cloned.' will be thrown\n let request = store.add({\n time: Date.now(),\n namespace: this._namespace,\n descriptor: descriptor,\n data: util.filterFunction(data)\n });\n\n request.onerror = event => {\n IndexedDBLogger.status = LoggerInterface.STATUS.FAILED;\n util.throwError(event.target.error);\n };\n }\n\n /**\n * initialize protocol\n * @method init\n * @static\n * @param {String} database - database name to use\n */\n static init(database) {\n if (!IndexedDBLogger.support) {\n util.throwError('your platform does not support indexeddb protocol.');\n }\n\n if (IndexedDBLogger.status) {\n return false;\n }\n\n IndexedDBLogger._pool = IndexedDBLogger._pool || new Pool();\n IndexedDBLogger._database = database || 'logline';\n IndexedDBLogger.status = super.STATUS.INITING;\n\n IndexedDBLogger.request = window.indexedDB.open(IndexedDBLogger._database);\n IndexedDBLogger.request.onerror = event => util.throwError('protocol indexeddb is prevented.');\n IndexedDBLogger.request.onsuccess = event => {\n IndexedDBLogger.db = event.target.result;\n IndexedDBLogger.status = super.STATUS.INITED;\n IndexedDBLogger._pool.consume();\n // globally handle db request errors\n IndexedDBLogger.db.onerror = event => util.throwError(event.target.error);\n };\n IndexedDBLogger.request.onupgradeneeded = event => {\n // init dabasebase\n let db = event.target.result, store = db.createObjectStore('logs', { autoIncrement: true });\n store.createIndex('namespace', 'namespace', { unique: false });\n store.createIndex('level', 'level', { unique: false });\n store.createIndex('descriptor', 'descriptor', { unique: false });\n store.createIndex('data', 'data', { unique: false });\n };\n }\n\n /**\n * get logs in range\n * if from and end is not defined, will fetch full log\n * @method get\n * @static\n * @param {String} from - time from, unix time stamp or falsy\n * @param {String} to - time end, unix time stamp or falsy\n * @param {Function} readyFn - function to call back with logs as parameter\n */\n static get(from, to, readyFn) {\n if (IndexedDBLogger.status !== super.STATUS.INITED) {\n return IndexedDBLogger._pool.push(() => IndexedDBLogger.get(from, to, readyFn));\n }\n\n from = LoggerInterface.transTimeFormat(from);\n to = LoggerInterface.transTimeFormat(to);\n\n let store = IndexedDBLogger._getTransactionStore(IDBTransaction.READ_ONLY || 'readonly'),\n request = store.openCursor(),\n logs = [];\n\n request.onsuccess = event => {\n var cursor = event.target.result;\n if (cursor) {\n if ((from && cursor.value.time < from) || (to && cursor.value.time > to)) {\n cursor.continue();\n }\n\n logs.push({\n time: cursor.value.time,\n namespace: cursor.value.namespace,\n descriptor: cursor.value.descriptor,\n data: cursor.value.data\n });\n cursor.continue();\n }\n else {\n readyFn(logs);\n }\n };\n\n request.onerror = event => util.throwError('failed to literat on logs from database.');\n }\n\n /**\n * clean logs = keep limited logs\n * @method keep\n * @static\n * @param {Number} daysToMaintain - keep logs within days\n */\n static keep(daysToMaintain) {\n if (IndexedDBLogger.status !== super.STATUS.INITED) {\n return IndexedDBLogger._pool.push(() => IndexedDBLogger.keep(daysToMaintain));\n }\n\n let store = IndexedDBLogger._getTransactionStore(IDBTransaction.READ_WRITE);\n if (!daysToMaintain) {\n let request = store.clear().onerror = event => util.throwError(event.target.error);\n }\n else {\n let range = (Date.now() - (daysToMaintain || 2) * 24 * 3600 * 1000);\n let request = store.openCursor();\n request.onsuccess = event => {\n let cursor = event.target.result;\n if (cursor && cursor.value.time < range) {\n store.delete(cursor.primaryKey);\n cursor.continue();\n }\n };\n request.onerror = event => util.throwError('unable to locate logs earlier than ' + daysToMaintain + 'd.');\n }\n }\n\n /**\n * delete log database\n * @method clean\n * @static\n */\n static clean() {\n if (IndexedDBLogger.status !== super.STATUS.INITED) {\n return IndexedDBLogger._pool.push(() => IndexedDBLogger.clean());\n }\n\n // database can be removed only after all connections are closed\n IndexedDBLogger.db.close();\n let request = window.indexedDB.deleteDatabase(IndexedDBLogger._database);\n request.onerror = event => util.throwError(event.target.error);\n /* eslint no-unused-vars: \"off\" */\n request.onsuccess = event => {\n delete IndexedDBLogger.status;\n delete IndexedDBLogger.db;\n };\n }\n\n /**\n * get internal transaction store\n * @method _getTransactionStore\n * @private\n * @static\n * @param {String} mode - transaction mode\n * @return {Object} - internal object store\n */\n static _getTransactionStore(mode) {\n if (IndexedDBLogger.db) {\n let transaction = IndexedDBLogger.db.transaction(['logs'], mode || IDBTransaction.READ_WRITE || 'readwrite');\n transaction.onerror = event => util.throwError(event.target.error);\n return transaction.objectStore('logs');\n }\n else {\n util.throwError('log database is not created or connections are closed, considering init it.');\n }\n }\n\n /**\n * detect support situation\n * @prop {Boolean} support\n */\n static get support() {\n return !!(window.indexedDB && window.IDBTransaction && window.IDBKeyRange);\n }\n}\n","import LoggerInterface from './interface';\nimport * as util from '../lib/util';\n\n/**\n * Localstorage protocol\n * @class LocalStorageLogger\n */\nexport default class LocalStorageLogger extends LoggerInterface {\n /**\n * Localstorage protocol constructor\n * @constructor\n * @param {String} namespace - namespace to use\n */\n constructor(...args) {\n super(...args);\n }\n\n /**\n * add a log record\n * @method _reocrd\n * @private\n * @parma {String} level - log level\n * @param {String} descriptor - to speed up search and improve understanding\n * @param {Mixed} [data] - additional data\n */\n _record(level, descriptor, data) {\n var logs = window.localStorage.getItem(LocalStorageLogger._database) ? JSON.parse(window.localStorage.getItem(LocalStorageLogger._database)) : [];\n logs.push([\n Date.now(),\n this._namespace,\n level,\n descriptor,\n data\n ]);\n try {\n util.debug(this._namespace, level, descriptor, data);\n window.localStorage.setItem(LocalStorageLogger._database, JSON.stringify(logs));\n } catch (e) { util.throwError('error inserting record'); }\n }\n\n /**\n * initialize protocol\n * @method init\n * @static\n * @param {String} database - database name to use\n */\n static init(database) {\n if (!LocalStorageLogger.support) {\n util.throwError('your platform does not support localstorage protocol.');\n }\n LocalStorageLogger._database = database || 'logline';\n if (!window.localStorage.getItem(LocalStorageLogger._database)) {\n window.localStorage.setItem(LocalStorageLogger._database, JSON.stringify([]));\n }\n LocalStorageLogger.status = super.STATUS.INITED;\n }\n\n /**\n * get logs in range\n * if from and end is not defined, will fetch full log\n * @method get\n * @static\n * @param {String} from - time from, unix time stamp or falsy\n * @param {String} to - time end, unix time stamp or falsy\n * @param {Function} readyFn - function to call back with logs as parameter\n */\n static get(from, to, readyFn) {\n var logs = JSON.parse(window.localStorage.getItem(LocalStorageLogger._database)), i;\n\n from = LoggerInterface.transTimeFormat(from);\n to = LoggerInterface.transTimeFormat(to);\n\n for (i = 0; i < logs.length; i++) {\n if ((from && logs[i][0] < from) || (to && logs[i][0] > to)) {\n continue;\n }\n\n logs[i] = {\n time: logs[i][0],\n namespace: logs[i][1],\n level: logs[i][2],\n descriptor: logs[i][3],\n data: logs[i][4]\n };\n }\n readyFn(logs);\n }\n\n /**\n * clean logs = keep limited logs\n * @method keep\n * @static\n * @param {Number} daysToMaintain - keep logs within days\n */\n static keep(daysToMaintain) {\n var logs = !daysToMaintain ? [] : (window.localStorage.getItem(LocalStorageLogger._database) ? JSON.parse(window.localStorage.getItem(LocalStorageLogger._database)) : []).filter(log => {\n return log.time >= (Date.now() - (daysToMaintain || 2) * 24 * 3600 * 1000);\n });\n window.localStorage.setItem(LocalStorageLogger._database, JSON.stringify(logs));\n }\n\n /**\n * delete log database\n * @method clean\n * @static\n */\n static clean() {\n delete LocalStorageLogger.status;\n window.localStorage.removeItem(LocalStorageLogger._database);\n }\n\n /**\n * detect support situation\n * @prop {Boolean} support\n */\n static get support() {\n return 'localStorage' in window;\n }\n}\n","import LoggerInterface from './interface';\nimport Pool from '../lib/pool';\nimport * as util from '../lib/util';\n\n/**\n * Websql protocol\n * @class WebsqlLogger\n */\nexport default class WebsqlLogger extends LoggerInterface {\n /**\n * Websql logline constructor\n * @constructor\n * @param {String} namespace - namespace to use\n */\n constructor(...args) {\n super(...args);\n }\n\n /**\n * add a log record\n * @method _reocrd\n * @private\n * @parma {String} level - log level\n * @param {String} descriptor - to speed up search and improve understanding\n * @param {Mixed} [data] - additional data\n */\n _record(level, descriptor, data) {\n if (WebsqlLogger.status !== LoggerInterface.STATUS.INITED) {\n WebsqlLogger._pool.push(() => this._record(level, descriptor, data));\n if (WebsqlLogger.status !== LoggerInterface.STATUS.INITING) {\n WebsqlLogger.init();\n }\n return;\n }\n\n try {\n util.debug(this._namespace, level, descriptor, data);\n WebsqlLogger._db.transaction(tx => {\n tx.executeSql(\n 'INSERT INTO logs (time, namespace, level, descriptor, data) VALUES(?, ?, ?, ? ,?)',\n [Date.now(), this._namespace, level, descriptor, (data === undefined || data === '') ? '' : (JSON.stringify(data) || '')],\n () => {/* empty func */},\n (tx, e) => { throw e.message; }\n );\n });\n } catch (e) { util.throwError('error inserting record'); }\n }\n\n /**\n * initialize protocol\n * @method init\n * @static\n * @param {String} database - database name to use\n */\n static init(database) {\n if (!WebsqlLogger.support) {\n util.throwError(new Error('your platform does not support websql protocol.'));\n }\n\n if (WebsqlLogger.status) {\n return false;\n }\n\n WebsqlLogger._pool = WebsqlLogger._pool || new Pool();\n WebsqlLogger._database = database || 'logline';\n WebsqlLogger.status = super.STATUS.INITING;\n\n try {\n WebsqlLogger._db = window.openDatabase(WebsqlLogger._database, '1.0', 'cats loves logs', 4.85 * 1024 * 1024);\n WebsqlLogger._db.transaction(tx => {\n tx.executeSql(\n 'CREATE TABLE IF NOT EXISTS logs (time, namespace, level, descriptor, data)', [],\n () => {\n WebsqlLogger.status = super.STATUS.INITED;\n WebsqlLogger._pool.consume();\n },\n () => {\n WebsqlLogger.status = super.STATUS.FAILED;\n }\n );\n });\n } catch (e) { util.throwError('unable to init log database.'); }\n }\n\n /**\n * get logs in range\n * if from and end is not defined, will fetch full log\n * @method get\n * @static\n * @param {String} from - time from, unix time stamp or falsy\n * @param {String} to - time end, unix time stamp or falsy\n * @param {Function} readyFn - function to call back with logs as parameter\n */\n static get(from, to, readyFn) {\n if (WebsqlLogger.status !== super.STATUS.INITED) {\n return WebsqlLogger._pool.push(() => WebsqlLogger.get(from, to, readyFn));\n }\n\n from = LoggerInterface.transTimeFormat(from);\n to = LoggerInterface.transTimeFormat(to);\n\n try {\n WebsqlLogger._db.transaction(function(tx) {\n tx.executeSql(\n 'SELECT * FROM logs ORDER BY time DESC', [],\n (tx, res) => {\n var logs = [], line, index = res.rows.length, item;\n while (--index >= 0) {\n item = res.rows.item(index);\n if ((from && item.time < from) || (to && item.time > to)) {\n continue;\n }\n\n // in some devices, properties are configureable: false, writable: false\n // we need deep copy\n line = JSON.parse(JSON.stringify(item));\n // incase data is an object, not a string\n try { line.data = JSON.parse(line.data); }\n catch (e) {/* leave line.data as it be */}\n logs.push(line);\n }\n readyFn(logs);\n },\n (tx, e) => { throw e.message; }\n );\n });\n } catch (e) { util.throwError('unable to collect logs from database.'); }\n }\n\n /**\n * clean logs = keep limited logs\n * @method keep\n * @static\n * @param {Number} daysToMaintain - keep logs within days\n */\n static keep(daysToMaintain) {\n if (WebsqlLogger.status !== super.STATUS.INITED) {\n return WebsqlLogger._pool.push(() => WebsqlLogger.keep(daysToMaintain));\n }\n\n try {\n WebsqlLogger._db.transaction(function(tx) {\n if (daysToMaintain) {\n tx.executeSql(\n 'DELETE FROM logs WHERE time < ?',\n [Date.now() - (daysToMaintain || 2) * 24 * 3600 * 1000],\n function() {/* empty func */},\n function(tx, e) {throw e.message;}\n );\n }\n else {\n tx.executeSql(\n 'DELETE FROM logs', [],\n () => {/* empty func */},\n (tx, e) => { throw e.message; }\n );\n }\n });\n } catch (e) { util.throwError('unable to clean logs from database.'); }\n }\n\n /**\n * delete log database\n * @method clean\n * @static\n */\n static clean() {\n if (WebsqlLogger.status !== super.STATUS.INITED) {\n WebsqlLogger._pool.push(() => WebsqlLogger.clean());\n return;\n }\n\n try {\n WebsqlLogger._db.transaction(tx => {\n tx.executeSql(\n 'DROP TABLE logs', [],\n () => {\n delete WebsqlLogger.status;\n },\n (tx, e) => { throw e.message; }\n );\n });\n } catch (e) { util.throwError('unable to clean log database.'); }\n }\n\n /**\n * detect support situation\n * @prop {Boolean} support\n */\n static get support() {\n return 'openDatabase' in window;\n }\n}\n","import Interface from './protocols/interface';\nimport IndexeddbLogger from './protocols/indexeddb';\nimport LocalstorageLogger from './protocols/localstorage';\nimport WebsqlLogger from './protocols/websql';\nimport * as util from './lib/util';\n\n\nclass Logline {\n /**\n * Logline constructor\n * @constructor\n * @param {String} namespace - namespace to use\n * @return {Object Protocol Instance}\n */\n constructor(namespace) {\n Logline._checkProtocol();\n return new Logline._protocol(namespace);\n }\n\n /**\n * choose a protocol to initialize\n * @method _initProtocol\n * @private\n * @static\n * @param {Object Protocol Class} protocol - protocol to use, must under Logline.PROTOCOL\n * @return {Object} Logline\n */\n static _initProtocol(protocol) {\n Logline._protocol = protocol;\n Logline._protocol.init(Logline._database || 'logline');\n }\n\n /**\n * check protocol\n * if no protocol is chosen, will try to choose an available one automatically\n * if none of the protocols is available, an error will be thrown\n * @method _checkProtocol\n * @private\n * @static\n */\n static _checkProtocol() {\n if (!Logline._protocol) {\n let protocols = Object.keys(Logline.PROTOCOL), protocol;\n while ((protocol = Logline.PROTOCOL[protocols.shift()])) {\n if (protocol.support) {\n Logline._initProtocol(protocol);\n return;\n }\n }\n\n throw new Error(protocols.join(', ').toLowerCase() + ' protocols are not supported on this platform');\n }\n }\n\n /**\n * get logs in range\n * if from and end is not defined, will fetch full log\n * @method get\n * @static\n * @param {String} [from] - time from\n * @param {String} [to] - time end\n * @param {Function} readyFn - function to call back with logs as parameter\n */\n static get(from, to, readyFn) {\n var now = Date.now();\n Logline._checkProtocol();\n\n switch (arguments.length) {\n case 1:\n readyFn = from;\n from = undefined;\n break;\n case 2:\n readyFn = to;\n to = undefined;\n break;\n case 3:\n default:\n break;\n }\n\n Logline._protocol.get(from, to, readyFn);\n }\n\n /**\n * read all logs\n * @method all\n * @static\n * @param {Function} readyFn - function to call back with logs as parameter\n */\n static all(readyFn) {\n Logline.get(readyFn);\n }\n\n /**\n * clean up logs = keep limited logs\n * @method keep\n * @static\n * @param {String} daysToMaintain - specialfy days to keep, support human readable format such as '3d', '.3'\n * @return {Object} Logline\n */\n static keep(daysToMaintain) {\n Logline._checkProtocol();\n Logline._protocol.keep(daysToMaintain);\n return this;\n }\n\n /**\n * delete log database\n * @method clean\n * @static\n * @return {Object} Logline\n */\n static clean() {\n Logline._checkProtocol();\n Logline._protocol.clean();\n return this;\n }\n\n /**\n * choose a protocol\n * @method using\n * @static\n * @param {Object Protocol Class} protocol - wanted protocol, should be on of Logline.PROTOCOL\n * @param {String} [database] - custome database name\n * @return {Object} Logline\n */\n static using(protocol, database) {\n // protocol unavailable is not allowed\n if (-1 === [IndexeddbLogger, LocalstorageLogger, WebsqlLogger].indexOf(protocol)) {\n util.throwError('specialfied protocol ' + (protocol ? (protocol + ' ') : '') + 'is not available');\n }\n\n // once protocol is selected, it shall not be changed during runtime\n if (Logline._protocol) {\n return this;\n }\n\n Logline.database(database || Logline._database);\n Logline._initProtocol(protocol);\n return this;\n }\n\n /**\n * specialfy a custome database name, in case of any conflicts\n * @methd database\n * @static\n * @param {String} name - target database name\n */\n static database(name) {\n Logline._database = name;\n }\n}\n\n// export protocols for modification and mounting\nLogline.PROTOCOL = {\n INDEXEDDB: IndexeddbLogger,\n LOCALSTORAGE: LocalstorageLogger,\n WEBSQL: WebsqlLogger\n};\n\n// export protocol interface for user custom implements\nLogline.INTERFACE = Object.freeze(Interface);\n\nexport default Logline;\n"],"names":["throwError","errMessage","Error","debug","namespace","level","descriptor","data","HAS_CONSOLE","console","LEVEL_CONSOLE_MAP","toUpperCase","INFO","LEVEL_STYLE_MAP","filterFunction","obj","i","newObj","hasOwnProperty","window","Interface","_namespace","args","_record","database","time","relative","test","TypeError","Date","now","replace","from","to","readyFn","daysToMaintain","Pool","_pool","handler","context","push","this","shift","call","IndexedDBLogger","status","LoggerInterface","STATUS","INITED","_this2","INITING","init","transaction","db","IDBTransaction","READ_WRITE","onerror","util","event","target","error","store","objectStore","request","add","FAILED","support","_database","babelHelpers.get","indexedDB","open","onsuccess","result","consume","onupgradeneeded","createObjectStore","autoIncrement","createIndex","unique","get","transTimeFormat","_getTransactionStore","READ_ONLY","openCursor","logs","cursor","value","continue","keep","range","delete","primaryKey","clear","clean","close","deleteDatabase","mode","IDBKeyRange","LocalStorageLogger","localStorage","getItem","JSON","parse","setItem","stringify","e","length","filter","log","removeItem","WebsqlLogger","_db","executeSql","undefined","tx","message","openDatabase","res","line","item","index","rows","Logline","_checkProtocol","_protocol","protocol","protocols","Object","keys","PROTOCOL","_initProtocol","join","toLowerCase","arguments","IndexeddbLogger","LocalstorageLogger","indexOf","name","INTERFACE","freeze"],"mappings":"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"} \ No newline at end of file diff --git a/package.json b/package.json index 02abf22..604be3e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "logline", - "version": "1.0.4", + "version": "1.0.5", "description": "logs for the frontend", "main": "dist/logline.min.js", "scripts": {