diff --git a/.babelrc b/.babelrc new file mode 100644 index 0000000..653b5be --- /dev/null +++ b/.babelrc @@ -0,0 +1,3 @@ +{ + "presets": [ "es2015-rollup" ] +} \ No newline at end of file diff --git a/.eslintrc b/.eslintrc new file mode 100644 index 0000000..9e56abf --- /dev/null +++ b/.eslintrc @@ -0,0 +1,25 @@ +{ + "parser": "babel-eslint", + "parserOptions": { + "ecmaVersion": 6, + "sourceType": "module", + "ecmaFeatures": { + "modules": true + } + }, + "extends": "eslint:recommended", + "env": { + "node": true, + "mocha": true + }, + "rules":{ + "no-console": 0 + }, + "globals": { + "localforage": true, + "Promise": true, + "console": true, + "self": true, + "System": true + } +} \ No newline at end of file diff --git a/.gitignore b/.gitignore index 8a306b4..37342cc 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,7 @@ .DS_Store .swp +dist +build bower_components node_modules components diff --git a/.jscsrc b/.jscsrc new file mode 100644 index 0000000..3415b8d --- /dev/null +++ b/.jscsrc @@ -0,0 +1,31 @@ +{ + "esnext": true, + "disallowSpacesInAnonymousFunctionExpression": { + "beforeOpeningRoundBrace": true + }, + "disallowTrailingComma": true, + "requireBlocksOnNewline": true, + "requireLineFeedAtFileEnd": true, + "requireSpaceAfterKeywords": [ + "if", + "else", + "for", + "while", + "do", + "switch", + "return", + "try", + "catch" + ], + "requireSpaceBeforeBlockStatements": true, + "requireSpacesInConditionalExpression": true, + "requireSpacesInFunctionExpression": { + "beforeOpeningCurlyBrace": true + }, + "safeContextKeyword": ["globalObject", "self"], + "validateQuoteMarks": { + "escape": true, + "mark": "'" + }, + "validateIndentation": 4 +} diff --git a/.jshintrc b/.jshintrc new file mode 100644 index 0000000..f29a720 --- /dev/null +++ b/.jshintrc @@ -0,0 +1,32 @@ +{ + "asi": false, + "bitwise": true, + "browser": true, + "curly": true, + "eqeqeq": true, + "eqnull": true, + "esnext": true, + "immed": true, + "latedef": true, + "newcap": true, + "noarg": true, + "nonew": true, + "quotmark": false, + "strict": false, + "trailing": false, + "undef": true, + "unused": true, + + "validthis": true, + + "globals": { + "console": true, + "define": true, + "localforage": true, + "module": true, + "Promise": true, + "require": true, + "self": true, + "System": true + } +} diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..d96bef9 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,4 @@ +language: node_js +node_js: + - "4.0" + - "5.0" diff --git a/bower.json b/bower.json index f090417..bdf95a2 100644 --- a/bower.json +++ b/bower.json @@ -1,6 +1,6 @@ { "name": "localforage-cordovasqlitedriver", - "version": "1.3.0", + "version": "1.4.0", "main": [ "src/localforage-cordovasqlitedriver.js" ], @@ -19,13 +19,5 @@ ], "dependencies": { "localforage": "^1.4.0" - }, - "devDependencies": { - "es6-promise": "~1.0.0", - "requirejs": "~2.1.10", - "mocha": "~1.18.2", - "expect": "~0.3.1", - "assert": "~0.1.0", - "modernizr": "~2.8.1" } } diff --git a/component.json b/component.json deleted file mode 100644 index abddaf4..0000000 --- a/component.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "name": "localForage-cordovaSQLiteDriver", - "version": "1.3.0", - "dependencies": { - "then/promise": "5.0.0" - }, - "scripts": [ - "src/localforage-cordovasqlitedriver.js" - ], - "main": "src/localforage-cordovasqlitedriver.js" -} diff --git a/lib/cordova-sqlite.js b/lib/cordova-sqlite.js new file mode 100644 index 0000000..9a75534 --- /dev/null +++ b/lib/cordova-sqlite.js @@ -0,0 +1,25 @@ +/* global document, sqlitePlugin */ +// we can't import this, since it gets defined later +// import sqlitePlugin from 'sqlitePlugin'; + +var deviceReady = new Promise(function(resolve, reject) { + if (typeof sqlitePlugin !== 'undefined') { + resolve(); + } else if (typeof cordova === 'undefined') { + reject(); + } else { + // Wait for Cordova to load + document.addEventListener("deviceready", resolve, false); + } +}); + +export var openDatabasePromise = deviceReady.catch(Promise.resolve).then(function() { + return new Promise(function(resolve, reject) { + if (typeof sqlitePlugin !== 'undefined' && + typeof sqlitePlugin.openDatabase === 'function') { + resolve(sqlitePlugin.openDatabase); + } else { + reject('SQLite plugin is not present.'); + } + }); +}); diff --git a/lib/localforage-cordovasqlitedriver.js b/lib/localforage-cordovasqlitedriver.js new file mode 100644 index 0000000..ffbf7a7 --- /dev/null +++ b/lib/localforage-cordovasqlitedriver.js @@ -0,0 +1,120 @@ +/* + * Includes code from: + * + * localForage - websql driver + * https://github.com/mozilla/localforage + * + * Copyright (c) 2015 Mozilla + * Licensed under Apache 2.0 license. + * + */ +// import localforage from 'localforage'; +import { getSerializerPromise, getWebSqlDriverPromise } from './utils'; +import { openDatabasePromise } from './cordova-sqlite'; + +// // If cordova is not present, we can stop now. +// if (!globalObject.cordova) { +// return; +// } + +// Open the cordova sqlite plugin database (automatically creates one if one didn't +// previously exist), using any options set in the config. +function _initStorage(options) { + var self = this; + var dbInfo = { + db: null + }; + + if (options) { + for (var i in options) { + dbInfo[i] = typeof(options[i]) !== 'string' ? + options[i].toString() : options[i]; + } + } + + var dbInfoPromise = openDatabasePromise.then(function(openDatabase){ + return new Promise(function(resolve, reject) { + // Open the database; the openDatabase API will automatically + // create it for us if it doesn't exist. + try { + dbInfo.location = dbInfo.location || 'default'; + dbInfo.db = openDatabase({ + name: dbInfo.name, + version: String(dbInfo.version), + description: dbInfo.description, + size: dbInfo.size, + location: dbInfo.location + }); + } catch (e) { + reject(e); + } + + // Create our key/value table if it doesn't exist. + dbInfo.db.transaction(function(t) { + t.executeSql('CREATE TABLE IF NOT EXISTS ' + dbInfo.storeName + + ' (id INTEGER PRIMARY KEY, key unique, value)', [], + function() { + self._dbInfo = dbInfo; + resolve(); + }, function(t, error) { + reject(error); + }); + }); + }); + }); + + var serializerPromise = getSerializerPromise(self); + var webSqlDriverPromise = getWebSqlDriverPromise(self); + + return Promise.all([ + serializerPromise, + webSqlDriverPromise, + dbInfoPromise + ]).then(function(results) { + dbInfo.serializer = results[0]; + return dbInfoPromise; + }); +} + +var cordovaSQLiteDriver = { + _driver: 'cordovaSQLiteDriver', + _initStorage: _initStorage, + _support: function() { + return openDatabasePromise.then(function(openDatabase) { + return !!openDatabase; + }).catch(function(){ + return false; + }); + } +}; + +function wireUpDriverMethods(driver) { + var LibraryMethods = [ + 'clear', + 'getItem', + 'iterate', + 'key', + 'keys', + 'length', + 'removeItem', + 'setItem' + ]; + + function wireUpDriverMethod(driver, methodName) { + driver[methodName] = function () { + var localForageInstance = this; + var args = arguments; + return getWebSqlDriverPromise(localForageInstance).then(function (webSqlDriver) { + return webSqlDriver[methodName].apply(localForageInstance, args); + }); + }; + } + + for (var i = 0, len = LibraryMethods.length; i < len; i++) { + wireUpDriverMethod(driver, LibraryMethods[i]); + } +} + +wireUpDriverMethods(cordovaSQLiteDriver); + +export default cordovaSQLiteDriver; diff --git a/lib/utils.js b/lib/utils.js new file mode 100644 index 0000000..e83b61d --- /dev/null +++ b/lib/utils.js @@ -0,0 +1,40 @@ +export function getSerializerPromise(localForageInstance) { + if (getSerializerPromise.result) { + return getSerializerPromise.result; + } + if (!localForageInstance || typeof localForageInstance.getSerializer !== 'function') { + Promise.reject(new Error( + 'localforage.getSerializer() was not available! ' + + 'localforage v1.4+ is required!')); + } + getSerializerPromise.result = localForageInstance.getSerializer(); + return getSerializerPromise.result; +} + +export function getDriverPromise(localForageInstance, driverName) { + getDriverPromise.result = getDriverPromise.result || {}; + if (getDriverPromise.result[driverName]) { + return getDriverPromise.result[driverName]; + } + if (!localForageInstance || typeof localForageInstance.getDriver !== 'function') { + Promise.reject(new Error( + 'localforage.getDriver() was not available! ' + + 'localforage v1.4+ is required!')); + } + getDriverPromise.result[driverName] = localForageInstance.getDriver(driverName); + return getDriverPromise.result[driverName]; +} + +export function getWebSqlDriverPromise(localForageInstance) { + return getDriverPromise(localForageInstance, localForageInstance.WEBSQL); +} + +export function executeCallback(promise, callback) { + if (callback) { + promise.then(function(result) { + callback(null, result); + }, function(error) { + callback(error); + }); + } +} diff --git a/package.json b/package.json index 236c49a..109770a 100644 --- a/package.json +++ b/package.json @@ -1,45 +1,44 @@ { "name": "localforage-cordovasqlitedriver", - "author": "Thodoris Greasidis", + "version": "1.4.0", "description": "SQLite driver for Cordova apps using localForage.", + "homepage": "https://github.com/thgreasi/localForage-cordovaSQLiteDriver", + "main": "dist/localforage-cordovasqlitedriver.js", + "jsnext:main": "dist/localforage-cordovasqlitedriver.es6.js", + "scripts": { + "prebuild": "eslint lib test", + "build": "rollup -c rollup.config.umd.js && rollup -c rollup.config.es6.js", + "pretest": "rollup -c rollup.config.test.js", + "test": "mocha build/test-bundle.js", + "prepublish": "npm run build && npm test" + }, + "repository": { + "type": "git", + "url": "git://github.com/thgreasi/localForage-cordovaSQLiteDriver.git" + }, "keywords": [ "localforage", "SQLite", "driver", "cordova" ], - "version": "1.3.0", - "homepage": "https://github.com/thgreasi/localForage-cordovaSQLiteDriver", - "repository": { - "type": "git", - "url": "git://github.com/thgreasi/localForage-cordovaSQLiteDriver.git" - }, - "devDependencies": { - "component": "^1.0.0-rc7", - "cors": "^2.3.1", - "grunt": "^0.4.2", - "grunt-contrib-concat": "^0.3.0", - "grunt-contrib-connect": "^0.8.0", - "grunt-contrib-jshint": "^0.9.2", - "grunt-contrib-uglify": "^0.4.0", - "grunt-contrib-watch": "^0.5.0", - "grunt-es3-safe-recast": "^0.1.0", - "grunt-jscs": "^0.8.0", - "grunt-mocha": "^0.4.10", - "grunt-saucelabs": "^5.1.2", - "grunt-shell": "^0.6.4", - "load-grunt-tasks": "^0.4.0", - "mocha": "^1.18.2", - "phantomjs": "^1.9.7-12", - "uglify-js": "^2.3.x" - }, - "browser": "src/localforage-cordovasqlitedriver.js", - "main": "src/localforage-cordovasqlitedriver.js", + "author": "Thodoris Greasidis", "licence": "Apache-2.0", "bugs": { "url": "http://github.com/thgreasi/localForage-cordovaSQLiteDriver/issues" }, + "devDependencies": { + "babel-eslint": "^6.0.4", + "babel-preset-es2015-rollup": "^1.1.1", + "eslint": "^2.8.0", + "mocha": "^2.4.5", + "requirejs": "^2.2.0", + "rollup": "^0.26.1", + "rollup-plugin-babel": "^2.4.0", + "rollup-plugin-multi-entry": "^1.2.0", + "source-map-support": "^0.4.0" + }, "dependencies": { - "promise": "^5.0.0" + "localforage": ">=1.4.0" } } diff --git a/rollup.config.es6.js b/rollup.config.es6.js new file mode 100644 index 0000000..ef894ed --- /dev/null +++ b/rollup.config.es6.js @@ -0,0 +1,6 @@ +import config from './rollup.config'; + +config.format = 'es6'; +config.dest = 'dist/localforage-cordovasqlitedriver.es6.js'; + +export default config; diff --git a/rollup.config.js b/rollup.config.js new file mode 100644 index 0000000..b189698 --- /dev/null +++ b/rollup.config.js @@ -0,0 +1,7 @@ +import babel from 'rollup-plugin-babel'; + +export default { + entry: 'lib/localforage-cordovasqlitedriver.js', + // sourceMap: true, + plugins: [babel()] +}; diff --git a/rollup.config.test.js b/rollup.config.test.js new file mode 100644 index 0000000..ec95bc6 --- /dev/null +++ b/rollup.config.test.js @@ -0,0 +1,11 @@ +import babel from 'rollup-plugin-babel'; +import multiEntry from 'rollup-plugin-multi-entry'; + +export default { + entry: 'test/**/*_test.js', + plugins: [babel(), multiEntry()], + format: 'cjs', + intro: 'require("source-map-support").install();', + dest: 'build/test-bundle.js', + sourceMap: true +}; diff --git a/rollup.config.umd.js b/rollup.config.umd.js new file mode 100644 index 0000000..75f776a --- /dev/null +++ b/rollup.config.umd.js @@ -0,0 +1,7 @@ +import config from './rollup.config'; + +config.format = 'umd'; +config.dest = 'dist/localforage-cordovasqlitedriver.js'; +config.moduleName = 'cordovaSQLiteDriver'; + +export default config; diff --git a/src/localforage-cordovasqlitedriver.js b/src/localforage-cordovasqlitedriver.js deleted file mode 100644 index 96f1b91..0000000 --- a/src/localforage-cordovasqlitedriver.js +++ /dev/null @@ -1,201 +0,0 @@ -/* - * Includes code from: - * - * localForage - websql driver - * https://github.com/mozilla/localforage - * - * Copyright (c) 2015 Mozilla - * Licensed under Apache 2.0 license. - * - */ -(function() { - 'use strict'; - - var globalObject = this; - - // // If cordova is not present, we can stop now. - // if (!globalObject.cordova) { - // return; - // } - - var ModuleType = { - DEFINE: 1, - EXPORT: 2, - WINDOW: 3 - }; - - // Attaching to window (i.e. no module loader) is the assumed, - // simple default. - var moduleType = ModuleType.WINDOW; - - // Find out what kind of module setup we have; if none, we'll just attach - // localForage to the main window. - if (typeof module !== 'undefined' && module.exports && typeof require !== 'undefined') { - moduleType = ModuleType.EXPORT; - } else if (typeof define === 'function' && define.amd) { - moduleType = ModuleType.DEFINE; - } - - // Promises! - var Promise = (moduleType === ModuleType.EXPORT) ? - require('promise') : this.Promise; - - var deviceReady = new Promise(function(resolve, reject) { - if (globalObject.sqlitePlugin) { - resolve(); - } else if (!globalObject.cordova) { - reject(); - } else { - // Wait for Cordova to load - document.addEventListener("deviceready", resolve, false); - } - }); - - var openDatabasePromise = deviceReady.catch(Promise.resolve).then(function() { - return new Promise(function(resolve, reject) { - var sqlitePlugin = sqlitePlugin || globalObject.sqlitePlugin; - var openDatabase = sqlitePlugin && sqlitePlugin.openDatabase; - - if (typeof openDatabase === 'function') { - resolve(openDatabase); - } else { - reject('SQLite plugin is not present.'); - } - }); - }); - - function getSerializerPromise(localForageInstance) { - if (getSerializerPromise.result) { - return getSerializerPromise.result; - } - if (!localForageInstance || typeof localForageInstance.getSerializer !== 'function') { - Promise.reject(new Error( - 'localforage.getSerializer() was not available! ' + - 'localforage-cordovasqlitedriver required localforage v1.4+')); - } - getSerializerPromise.result = localForageInstance.getSerializer(); - return getSerializerPromise.result; - } - - function getWebSqlDriverPromise(localForageInstance) { - if (getWebSqlDriverPromise.result) { - return getWebSqlDriverPromise.result; - } - if (!localForageInstance || typeof localForageInstance.getDriver !== 'function') { - Promise.reject(new Error( - 'localforage.getDriver() was not available! ' + - 'localforage-cordovasqlitedriver requires localforage v1.4+')); - } - getWebSqlDriverPromise.result = localForageInstance.getDriver(localForageInstance.WEBSQL); - return getWebSqlDriverPromise.result; - } - - // Open the cordova sqlite plugin database (automatically creates one if one didn't - // previously exist), using any options set in the config. - function _initStorage(options) { - var self = this; - var dbInfo = { - db: null - }; - - if (options) { - for (var i in options) { - dbInfo[i] = typeof(options[i]) !== 'string' ? - options[i].toString() : options[i]; - } - } - - var dbInfoPromise = openDatabasePromise.then(function(openDatabase){ - return new Promise(function(resolve, reject) { - // Open the database; the openDatabase API will automatically - // create it for us if it doesn't exist. - try { - dbInfo.location = dbInfo.location || 'default'; - dbInfo.db = openDatabase({ - name: dbInfo.name, - version: String(dbInfo.version), - description: dbInfo.description, - size: dbInfo.size, - location: dbInfo.location - }); - } catch (e) { - reject(e); - } - - // Create our key/value table if it doesn't exist. - dbInfo.db.transaction(function(t) { - t.executeSql('CREATE TABLE IF NOT EXISTS ' + dbInfo.storeName + - ' (id INTEGER PRIMARY KEY, key unique, value)', [], - function() { - self._dbInfo = dbInfo; - resolve(); - }, function(t, error) { - reject(error); - }); - }); - }); - }); - - var serializerPromise = getSerializerPromise(self); - var webSqlDriverPromise = getWebSqlDriverPromise(self); - - return Promise.all([ - serializerPromise, - webSqlDriverPromise, - dbInfoPromise - ]).then(function(results) { - dbInfo.serializer = results[0]; - return dbInfoPromise; - }); - } - - var cordovaSQLiteDriver = { - _driver: 'cordovaSQLiteDriver', - _initStorage: _initStorage, - _support: function() { - return openDatabasePromise.then(function(openDatabase) { - return !!openDatabase; - }).catch(function(){ return false; }); - } - }; - - function wireUpDriverMethods(driver) { - var LibraryMethods = [ - 'clear', - 'getItem', - 'iterate', - 'key', - 'keys', - 'length', - 'removeItem', - 'setItem' - ]; - - function wireUpDriverMethod(driver, methodName) { - driver[methodName] = function () { - var localForageInstance = this; - var args = arguments; - return getWebSqlDriverPromise(localForageInstance).then(function (webSqlDriver) { - return webSqlDriver[methodName].apply(localForageInstance, args); - }); - }; - } - - for (var i = 0, len = LibraryMethods.length; i < len; i++) { - var methodName = LibraryMethods[i]; - wireUpDriverMethod(driver, LibraryMethods[i]); - } - } - - wireUpDriverMethods(cordovaSQLiteDriver); - - if (moduleType === ModuleType.DEFINE) { - define('cordovaSQLiteDriver', function() { - return cordovaSQLiteDriver; - }); - } else if (moduleType === ModuleType.EXPORT) { - module.exports = cordovaSQLiteDriver; - } else { - this.cordovaSQLiteDriver = cordovaSQLiteDriver; - } -}).call(window);