localforage
Advanced tools
Comparing version 0.1.1 to 0.2.0
{ | ||
"name": "localforage", | ||
"version": "0.1.1", | ||
"version": "0.2.0", | ||
"main": [ | ||
"dist/localforage.min.js", | ||
"dist/backbone.localforage.min.js" | ||
"dist/localforage.min.js" | ||
], | ||
@@ -15,4 +14,8 @@ "ignore": [ | ||
], | ||
"dependencies": {}, | ||
"devDependencies": {} | ||
"dependencies": { | ||
"es6-promise": "~0.1.1" | ||
}, | ||
"devDependencies": { | ||
"requirejs": "~2.1.10" | ||
} | ||
} |
@@ -6,18 +6,22 @@ # About this CHANGELOG | ||
## [Version 0.1.1](https://github.com/mozilla/localForage/releases/tag/0.1.1) | ||
### [Version 0.2.0](https://github.com/mozilla/localForage/releases/tag/0.2.0) | ||
* Added config options to allow users to set their own database names, etc. #100 | ||
* Add support for ArrayBuffer, Blob, and TypedArrays ([#54](https://github.com/mozilla/localForage/pull/54), [#73](https://github.com/mozilla/localForage/pull/73)) | ||
### [Version 0.1.1](https://github.com/mozilla/localForage/releases/tag/0.1.1) | ||
* Added config options to allow users to set their own database names, etc. ([#100](https://github.com/mozilla/localForage/pull/100)) | ||
--- | ||
## March 16th, 2014 | ||
### March 16th, 2014 | ||
* [Moved Backbone adapter to its own repository](https://github.com/mozilla/localForage/commit/b7987b3091855379d4908376b668b4b51a6fedfe) | ||
* Moved Backbone adapter to its own repository ([b7987b3091855379d4908376b668b4b51a6fedfe](https://github.com/mozilla/localForage/commit/b7987b3091855379d4908376b668b4b51a6fedfe)) | ||
## March 13th, 2014 | ||
### March 13th, 2014 | ||
* [Changed `localforage.driver` to a function instead of the string directly](https://github.com/mozilla/localForage/commit/49415145021b0029d2521182de6e338e048fe5b1) | ||
* Changed `localforage.driver` to a function instead of the string directly ([49415145021b0029d2521182de6e338e048fe5b1](https://github.com/mozilla/localForage/commit/49415145021b0029d2521182de6e338e048fe5b1)) | ||
## March 4th, 2014 | ||
### March 4th, 2014 | ||
* [Changed the IndexedDB database name from `asyncStorage` to `localforage`](https://github.com/mozilla/localForage/commit/f4e0156a29969a79005ac27b303d7e321a720fc6) | ||
* Changed the IndexedDB database name from `asyncStorage` to `localforage` ([f4e0156a29969a79005ac27b303d7e321a720fc6](https://github.com/mozilla/localForage/commit/f4e0156a29969a79005ac27b303d7e321a720fc6)) |
@@ -1,1 +0,1 @@ | ||
!function(){var a,b,c,d;!function(){var e={},f={};a=function(a,b,c){e[a]={deps:b,callback:c}},d=c=b=function(a){function c(b){if("."!==b.charAt(0))return b;for(var c=b.split("/"),d=a.split("/").slice(0,-1),e=0,f=c.length;f>e;e++){var g=c[e];if(".."===g)d.pop();else{if("."===g)continue;d.push(g)}}return d.join("/")}if(d._eak_seen=e,f[a])return f[a];if(f[a]={},!e[a])throw new Error("Could not find module "+a);for(var g,h=e[a],i=h.deps,j=h.callback,k=[],l=0,m=i.length;m>l;l++)k.push("exports"===i[l]?g={}:b(c(i[l])));var n=j.apply(this,k);return f[a]=g||n}}(),a("promise/all",["./utils","exports"],function(a,b){"use strict";function c(a){var b=this;if(!d(a))throw new TypeError("You must pass an array to all.");return new b(function(b,c){function d(a){return function(b){f(a,b)}}function f(a,c){h[a]=c,0===--i&&b(h)}var g,h=[],i=a.length;0===i&&b([]);for(var j=0;j<a.length;j++)g=a[j],g&&e(g.then)?g.then(d(j),c):f(j,g)})}var d=a.isArray,e=a.isFunction;b.all=c}),a("promise/asap",["exports"],function(a){"use strict";function b(){return function(){process.nextTick(e)}}function c(){var a=0,b=new i(e),c=document.createTextNode("");return b.observe(c,{characterData:!0}),function(){c.data=a=++a%2}}function d(){return function(){j.setTimeout(e,1)}}function e(){for(var a=0;a<k.length;a++){var b=k[a],c=b[0],d=b[1];c(d)}k=[]}function f(a,b){var c=k.push([a,b]);1===c&&g()}var g,h="undefined"!=typeof window?window:{},i=h.MutationObserver||h.WebKitMutationObserver,j="undefined"!=typeof global?global:this,k=[];g="undefined"!=typeof process&&"[object process]"==={}.toString.call(process)?b():i?c():d(),a.asap=f}),a("promise/cast",["exports"],function(a){"use strict";function b(a){if(a&&"object"==typeof a&&a.constructor===this)return a;var b=this;return new b(function(b){b(a)})}a.cast=b}),a("promise/config",["exports"],function(a){"use strict";function b(a,b){return 2!==arguments.length?c[a]:void(c[a]=b)}var c={instrument:!1};a.config=c,a.configure=b}),a("promise/polyfill",["./promise","./utils","exports"],function(a,b,c){"use strict";function d(){var a="Promise"in window&&"cast"in window.Promise&&"resolve"in window.Promise&&"reject"in window.Promise&&"all"in window.Promise&&"race"in window.Promise&&function(){var a;return new window.Promise(function(b){a=b}),f(a)}();a||(window.Promise=e)}var e=a.Promise,f=b.isFunction;c.polyfill=d}),a("promise/promise",["./config","./utils","./cast","./all","./race","./resolve","./reject","./asap","exports"],function(a,b,c,d,e,f,g,h,i){"use strict";function j(a){if(!w(a))throw new TypeError("You must pass a resolver function as the first argument to the promise constructor");if(!(this instanceof j))throw new TypeError("Failed to construct 'Promise': Please use the 'new' operator, this object constructor cannot be called as a function.");this._subscribers=[],k(a,this)}function k(a,b){function c(a){p(b,a)}function d(a){r(b,a)}try{a(c,d)}catch(e){d(e)}}function l(a,b,c,d){var e,f,g,h,i=w(c);if(i)try{e=c(d),g=!0}catch(j){h=!0,f=j}else e=d,g=!0;o(b,e)||(i&&g?p(b,e):h?r(b,f):a===F?p(b,e):a===G&&r(b,e))}function m(a,b,c,d){var e=a._subscribers,f=e.length;e[f]=b,e[f+F]=c,e[f+G]=d}function n(a,b){for(var c,d,e=a._subscribers,f=a._detail,g=0;g<e.length;g+=3)c=e[g],d=e[g+b],l(b,c,d,f);a._subscribers=null}function o(a,b){var c,d=null;try{if(a===b)throw new TypeError("A promises callback cannot return that same promise.");if(v(b)&&(d=b.then,w(d)))return d.call(b,function(d){return c?!0:(c=!0,void(b!==d?p(a,d):q(a,d)))},function(b){return c?!0:(c=!0,void r(a,b))}),!0}catch(e){return c?!0:(r(a,e),!0)}return!1}function p(a,b){a===b?q(a,b):o(a,b)||q(a,b)}function q(a,b){a._state===D&&(a._state=E,a._detail=b,u.async(s,a))}function r(a,b){a._state===D&&(a._state=E,a._detail=b,u.async(t,a))}function s(a){n(a,a._state=F)}function t(a){n(a,a._state=G)}var u=a.config,v=(a.configure,b.objectOrFunction),w=b.isFunction,x=(b.now,c.cast),y=d.all,z=e.race,A=f.resolve,B=g.reject,C=h.asap;u.async=C;var D=void 0,E=0,F=1,G=2;j.prototype={constructor:j,_state:void 0,_detail:void 0,_subscribers:void 0,then:function(a,b){var c=this,d=new this.constructor(function(){});if(this._state){var e=arguments;u.async(function(){l(c._state,d,e[c._state-1],c._detail)})}else m(this,d,a,b);return d},"catch":function(a){return this.then(null,a)}},j.all=y,j.cast=x,j.race=z,j.resolve=A,j.reject=B,i.Promise=j}),a("promise/race",["./utils","exports"],function(a,b){"use strict";function c(a){var b=this;if(!d(a))throw new TypeError("You must pass an array to race.");return new b(function(b,c){for(var d,e=0;e<a.length;e++)d=a[e],d&&"function"==typeof d.then?d.then(b,c):b(d)})}var d=a.isArray;b.race=c}),a("promise/reject",["exports"],function(a){"use strict";function b(a){var b=this;return new b(function(b,c){c(a)})}a.reject=b}),a("promise/resolve",["exports"],function(a){"use strict";function b(a){var b=this;return new b(function(b){b(a)})}a.resolve=b}),a("promise/utils",["exports"],function(a){"use strict";function b(a){return c(a)||"object"==typeof a&&null!==a}function c(a){return"function"==typeof a}function d(a){return"[object Array]"===Object.prototype.toString.call(a)}var e=Date.now||function(){return(new Date).getTime()};a.objectOrFunction=b,a.isFunction=c,a.isArray=d,a.now=e}),b("promise/polyfill").polyfill()}(),function(){"use strict";function a(a){if(a)for(var b in j)void 0!==a[b]&&(j[b]=a[b]);return new h(function(a,b){var c=k.open(j.name,j.version);c.onerror=function(){b(c.error.name)},c.onupgradeneeded=function(){c.result.createObjectStore(j.storeName)},c.onsuccess=function(){i=c.result,a()}})}function b(a,b){return new h(function(c,d){localforage.ready().then(function(){var e=i.transaction(j.storeName,"readonly").objectStore(j.storeName),f=e.get(a);f.onsuccess=function(){var a=f.result;void 0===a&&(a=null),b&&b(a),c(a)},f.onerror=function(){d(f.error.name)}})})}function c(a,b,c){return new h(function(d,e){localforage.ready().then(function(){var f=i.transaction(j.storeName,"readwrite").objectStore(j.storeName);void 0===b&&(b=null);var g=f.put(b,a);g.onsuccess=function(){c&&c(b),d(b)},g.onerror=function(){e(g.error.name)}})})}function d(a,b){return new h(function(c,d){localforage.ready().then(function(){var e=i.transaction(j.storeName,"readwrite").objectStore(j.storeName),f=e["delete"](a);f.onsuccess=function(){b&&b(),c()},f.onerror=function(){d(f.error.name)}})})}function e(a){return new h(function(b,c){localforage.ready().then(function(){var d=i.transaction(j.storeName,"readwrite").objectStore(j.storeName),e=d.clear();e.onsuccess=function(){a&&a(),b()},e.onerror=function(){c(e.error.name)}})})}function f(a){return new h(function(b,c){localforage.ready().then(function(){var d=i.transaction(j.storeName,"readonly").objectStore(j.storeName),e=d.count();e.onsuccess=function(){a&&a(e.result),b(e.result)},e.onerror=function(){c(e.error.name)}})})}function g(a,b){return new h(function(c,d){return 0>a?(b&&b(null),void c(null)):void localforage.ready().then(function(){var e=i.transaction(j.storeName,"readonly").objectStore(j.storeName),f=!1,g=e.openCursor();g.onsuccess=function(){var d=g.result;return d?void(0===a?(b&&b(d.key),c(d.key)):f?(b&&b(d.key),c(d.key)):(f=!0,d.advance(a))):(b&&b(null),void c(null))},g.onerror=function(){d(g.error.name)}})})}var h=window.Promise,i=null,j={name:"localforage",storeName:"keyvaluepairs",version:1},k=k||window.indexedDB||window.webkitIndexedDB||window.mozIndexedDB||window.OIndexedDB||window.msIndexedDB;if(k){var l={_driver:"asyncStorage",_initStorage:a,getItem:b,setItem:c,removeItem:d,clear:e,length:f,key:g};"function"==typeof define&&define.amd?define("asyncStorage",function(){return l}):"undefined"!=typeof module&&module.exports?module.exports=l:this.asyncStorage=l}}.call(this),function(){"use strict";function a(a){if(a)for(var b in i)void 0!==a[b]&&(i[b]=a[b]);return h=i.name+"/",j.resolve()}function b(a){return new j(function(b){localforage.ready().then(function(){k.clear(),a&&a(),b()})})}function c(a,b){return new j(function(c,d){localforage.ready().then(function(){try{var e=k.getItem(h+a);e&&(e=JSON.parse(e)),b&&b(e),c(e)}catch(f){d(f)}})})}function d(a,b){return new j(function(c){localforage.ready().then(function(){var d=k.key(a);d&&(d=d.substring(h.length)),b&&b(d),c(d)})})}function e(a){return new j(function(b){localforage.ready().then(function(){var c=k.length;a&&a(c),b(c)})})}function f(a,b){return new j(function(c){localforage.ready().then(function(){k.removeItem(h+a),b&&b(),c()})})}function g(a,b,c){return new j(function(d,e){localforage.ready().then(function(){void 0===b&&(b=null);var f=b;try{b=JSON.stringify(b)}catch(g){e(g)}k.setItem(h+a,b),c&&c(f),d(f)})})}var h="",i={name:"localforage"},j=window.Promise,k=null;try{k=window.localStorage}catch(l){return}var m={_driver:"localStorageWrapper",_initStorage:a,getItem:c,setItem:g,removeItem:f,clear:b,length:e,key:d};"function"==typeof define&&define.amd?define("localStorageWrapper",function(){return m}):"undefined"!=typeof module&&module.exports?module.exports=m:this.localStorageWrapper=m}.call(this),function(){"use strict";function a(a){if(a)for(var b in m)void 0!==a[b]&&(m[b]="string"!=typeof a[b]?a[b].toString():a[b]);return new k(function(a){l=window.openDatabase(m.name,m.version,m.description,h),l.transaction(function(b){b.executeSql("CREATE TABLE IF NOT EXISTS "+m.storeName+" (id INTEGER PRIMARY KEY, key unique, value)",[],function(){a()},null)})})}function b(a,b){return new k(function(c,d){localforage.ready().then(function(){l.transaction(function(e){e.executeSql("SELECT * FROM "+m.storeName+" WHERE key = ? LIMIT 1",[a],function(a,e){var f=e.rows.length?e.rows.item(0).value:null;if(f&&f.substr(0,j)===i)try{f=JSON.parse(f.slice(j))}catch(g){d(g)}b&&b(f),c(f)},null)})})})}function c(a,b,c){return new k(function(d){localforage.ready().then(function(){void 0===b&&(b=null);var e;e="boolean"==typeof b||"number"==typeof b||"object"==typeof b?i+JSON.stringify(b):b,l.transaction(function(f){f.executeSql("INSERT OR REPLACE INTO "+m.storeName+" (key, value) VALUES (?, ?)",[a,e],function(){c&&c(b),d(b)},null)})})})}function d(a,b){return new k(function(c){localforage.ready().then(function(){l.transaction(function(d){d.executeSql("DELETE FROM "+m.storeName+" WHERE key = ?",[a],function(){b&&b(),c()},null)})})})}function e(a){return new k(function(b){localforage.ready().then(function(){l.transaction(function(c){c.executeSql("DELETE FROM "+m.storeName,[],function(){a&&a(),b()},null)})})})}function f(a){return new k(function(b){localforage.ready().then(function(){l.transaction(function(c){c.executeSql("SELECT COUNT(key) as c FROM "+m.storeName,[],function(c,d){var e=d.rows.item(0).c;a&&a(e),b(e)},null)})})})}function g(a,b){return new k(function(c){localforage.ready().then(function(){l.transaction(function(d){d.executeSql("SELECT key FROM "+m.storeName+" WHERE id = ? LIMIT 1",[a+1],function(a,d){var e=d.rows.length?d.rows.item(0).key:null;b&&b(e),c(e)},null)})})})}var h=4980736,i="__lfsc__:",j=i.length,k=window.Promise,l=null,m={description:"",name:"localforage",storeName:"keyvaluepairs",version:"1.0"};if(window.openDatabase){var n={_driver:"webSQLStorage",_initStorage:a,getItem:b,setItem:c,removeItem:d,clear:e,length:f,key:g};"function"==typeof define&&define.amd?define("webSQLStorage",function(){return n}):"undefined"!=typeof module&&module.exports?module.exports=n:this.webSQLStorage=n}}.call(this),function(){"use strict";var a=window.Promise,b=1,c=2,d=3,e=d;"function"==typeof define&&define.amd?e=b:"undefined"!=typeof module&&module.exports&&(e=c);var f,g=g||window.indexedDB||window.webkitIndexedDB||window.mozIndexedDB||window.OIndexedDB||window.msIndexedDB,h=this,i={INDEXEDDB:"asyncStorage",LOCALSTORAGE:"localStorageWrapper",WEBSQL:"webSQLStorage",driver:function(){return i._driver||null},_ready:a.reject(new Error("setDriver() wasn't called")),setDriver:function(d,f){return this._ready=new a(function(a,j){if(!g&&d===i.INDEXEDDB||!window.openDatabase&&d===i.WEBSQL)return f&&f(i),void j(i);if(e===b)require([d],function(b){i._extend(b),i._initStorage(window.localForageConfig).then(function(){f&&f(i),a(i)})});else if(e===c){var k;switch(d){case i.INDEXEDDB:k=require("localforage/src/drivers/indexeddb");break;case i.LOCALSTORAGE:k=require("localforage/src/drivers/localstorage");break;case i.WEBSQL:k=require("localforage/src/drivers/websql")}i._extend(k),i._initStorage(window.localForageConfig).then(function(){f&&f(i),a(i)})}else i._extend(h[d]),i._initStorage(window.localForageConfig).then(function(){f&&f(i),a(i)})}),i._ready},ready:function(){return this._ready},_extend:function(a){for(var b in a)a.hasOwnProperty(b)&&(this[b]=a[b])}};f=g?i.INDEXEDDB:window.openDatabase?i.WEBSQL:i.LOCALSTORAGE,i.setDriver(f),e===b?define(function(){return i}):e===c?module.exports=i:this.localforage=i}.call(this); | ||
!function(){var a,b,c,d;!function(){var e={},f={};a=function(a,b,c){e[a]={deps:b,callback:c}},d=c=b=function(a){function c(b){if("."!==b.charAt(0))return b;for(var c=b.split("/"),d=a.split("/").slice(0,-1),e=0,f=c.length;f>e;e++){var g=c[e];if(".."===g)d.pop();else{if("."===g)continue;d.push(g)}}return d.join("/")}if(d._eak_seen=e,f[a])return f[a];if(f[a]={},!e[a])throw new Error("Could not find module "+a);for(var g,h=e[a],i=h.deps,j=h.callback,k=[],l=0,m=i.length;m>l;l++)k.push("exports"===i[l]?g={}:b(c(i[l])));var n=j.apply(this,k);return f[a]=g||n}}(),a("promise/all",["./utils","exports"],function(a,b){"use strict";function c(a){var b=this;if(!d(a))throw new TypeError("You must pass an array to all.");return new b(function(b,c){function d(a){return function(b){f(a,b)}}function f(a,c){h[a]=c,0===--i&&b(h)}var g,h=[],i=a.length;0===i&&b([]);for(var j=0;j<a.length;j++)g=a[j],g&&e(g.then)?g.then(d(j),c):f(j,g)})}var d=a.isArray,e=a.isFunction;b.all=c}),a("promise/asap",["exports"],function(a){"use strict";function b(){return function(){process.nextTick(e)}}function c(){var a=0,b=new i(e),c=document.createTextNode("");return b.observe(c,{characterData:!0}),function(){c.data=a=++a%2}}function d(){return function(){j.setTimeout(e,1)}}function e(){for(var a=0;a<k.length;a++){var b=k[a],c=b[0],d=b[1];c(d)}k=[]}function f(a,b){var c=k.push([a,b]);1===c&&g()}var g,h="undefined"!=typeof window?window:{},i=h.MutationObserver||h.WebKitMutationObserver,j="undefined"!=typeof global?global:this,k=[];g="undefined"!=typeof process&&"[object process]"==={}.toString.call(process)?b():i?c():d(),a.asap=f}),a("promise/cast",["exports"],function(a){"use strict";function b(a){if(a&&"object"==typeof a&&a.constructor===this)return a;var b=this;return new b(function(b){b(a)})}a.cast=b}),a("promise/config",["exports"],function(a){"use strict";function b(a,b){return 2!==arguments.length?c[a]:void(c[a]=b)}var c={instrument:!1};a.config=c,a.configure=b}),a("promise/polyfill",["./promise","./utils","exports"],function(a,b,c){"use strict";function d(){var a="Promise"in window&&"cast"in window.Promise&&"resolve"in window.Promise&&"reject"in window.Promise&&"all"in window.Promise&&"race"in window.Promise&&function(){var a;return new window.Promise(function(b){a=b}),f(a)}();a||(window.Promise=e)}var e=a.Promise,f=b.isFunction;c.polyfill=d}),a("promise/promise",["./config","./utils","./cast","./all","./race","./resolve","./reject","./asap","exports"],function(a,b,c,d,e,f,g,h,i){"use strict";function j(a){if(!w(a))throw new TypeError("You must pass a resolver function as the first argument to the promise constructor");if(!(this instanceof j))throw new TypeError("Failed to construct 'Promise': Please use the 'new' operator, this object constructor cannot be called as a function.");this._subscribers=[],k(a,this)}function k(a,b){function c(a){p(b,a)}function d(a){r(b,a)}try{a(c,d)}catch(e){d(e)}}function l(a,b,c,d){var e,f,g,h,i=w(c);if(i)try{e=c(d),g=!0}catch(j){h=!0,f=j}else e=d,g=!0;o(b,e)||(i&&g?p(b,e):h?r(b,f):a===F?p(b,e):a===G&&r(b,e))}function m(a,b,c,d){var e=a._subscribers,f=e.length;e[f]=b,e[f+F]=c,e[f+G]=d}function n(a,b){for(var c,d,e=a._subscribers,f=a._detail,g=0;g<e.length;g+=3)c=e[g],d=e[g+b],l(b,c,d,f);a._subscribers=null}function o(a,b){var c,d=null;try{if(a===b)throw new TypeError("A promises callback cannot return that same promise.");if(v(b)&&(d=b.then,w(d)))return d.call(b,function(d){return c?!0:(c=!0,void(b!==d?p(a,d):q(a,d)))},function(b){return c?!0:(c=!0,void r(a,b))}),!0}catch(e){return c?!0:(r(a,e),!0)}return!1}function p(a,b){a===b?q(a,b):o(a,b)||q(a,b)}function q(a,b){a._state===D&&(a._state=E,a._detail=b,u.async(s,a))}function r(a,b){a._state===D&&(a._state=E,a._detail=b,u.async(t,a))}function s(a){n(a,a._state=F)}function t(a){n(a,a._state=G)}var u=a.config,v=(a.configure,b.objectOrFunction),w=b.isFunction,x=(b.now,c.cast),y=d.all,z=e.race,A=f.resolve,B=g.reject,C=h.asap;u.async=C;var D=void 0,E=0,F=1,G=2;j.prototype={constructor:j,_state:void 0,_detail:void 0,_subscribers:void 0,then:function(a,b){var c=this,d=new this.constructor(function(){});if(this._state){var e=arguments;u.async(function(){l(c._state,d,e[c._state-1],c._detail)})}else m(this,d,a,b);return d},"catch":function(a){return this.then(null,a)}},j.all=y,j.cast=x,j.race=z,j.resolve=A,j.reject=B,i.Promise=j}),a("promise/race",["./utils","exports"],function(a,b){"use strict";function c(a){var b=this;if(!d(a))throw new TypeError("You must pass an array to race.");return new b(function(b,c){for(var d,e=0;e<a.length;e++)d=a[e],d&&"function"==typeof d.then?d.then(b,c):b(d)})}var d=a.isArray;b.race=c}),a("promise/reject",["exports"],function(a){"use strict";function b(a){var b=this;return new b(function(b,c){c(a)})}a.reject=b}),a("promise/resolve",["exports"],function(a){"use strict";function b(a){var b=this;return new b(function(b){b(a)})}a.resolve=b}),a("promise/utils",["exports"],function(a){"use strict";function b(a){return c(a)||"object"==typeof a&&null!==a}function c(a){return"function"==typeof a}function d(a){return"[object Array]"===Object.prototype.toString.call(a)}var e=Date.now||function(){return(new Date).getTime()};a.objectOrFunction=b,a.isFunction=c,a.isArray=d,a.now=e}),b("promise/polyfill").polyfill()}(),function(){"use strict";function a(a){if(a)for(var b in j)void 0!==a[b]&&(j[b]=a[b]);return new h(function(a,b){var c=k.open(j.name,j.version);c.onerror=function(){b(c.error.name)},c.onupgradeneeded=function(){c.result.createObjectStore(j.storeName)},c.onsuccess=function(){i=c.result,a()}})}function b(a,b){var c=this;return new h(function(d,e){c.ready().then(function(){var c=i.transaction(j.storeName,"readonly").objectStore(j.storeName),f=c.get(a);f.onsuccess=function(){var a=f.result;void 0===a&&(a=null),b&&b(a),d(a)},f.onerror=function(){e(f.error.name)}})})}function c(a,b,c){var d=this;return new h(function(e,f){d.ready().then(function(){var d=i.transaction(j.storeName,"readwrite").objectStore(j.storeName);void 0===b&&(b=null);var g=d.put(b,a);g.onsuccess=function(){c&&c(b),e(b)},g.onerror=function(){f(g.error.name)}})})}function d(a,b){var c=this;return new h(function(d,e){c.ready().then(function(){var c=i.transaction(j.storeName,"readwrite").objectStore(j.storeName),f=c["delete"](a);f.onsuccess=function(){b&&b(),d()},f.onerror=function(){e(f.error.name)}})})}function e(a){var b=this;return new h(function(c,d){b.ready().then(function(){var b=i.transaction(j.storeName,"readwrite").objectStore(j.storeName),e=b.clear();e.onsuccess=function(){a&&a(),c()},e.onerror=function(){d(e.error.name)}})})}function f(a){var b=this;return new h(function(c,d){b.ready().then(function(){var b=i.transaction(j.storeName,"readonly").objectStore(j.storeName),e=b.count();e.onsuccess=function(){a&&a(e.result),c(e.result)},e.onerror=function(){d(e.error.name)}})})}function g(a,b){var c=this;return new h(function(d,e){return 0>a?(b&&b(null),void d(null)):void c.ready().then(function(){var c=i.transaction(j.storeName,"readonly").objectStore(j.storeName),f=!1,g=c.openCursor();g.onsuccess=function(){var c=g.result;return c?void(0===a?(b&&b(c.key),d(c.key)):f?(b&&b(c.key),d(c.key)):(f=!0,c.advance(a))):(b&&b(null),void d(null))},g.onerror=function(){e(g.error.name)}})})}var h=window.Promise,i=null,j={name:"localforage",storeName:"keyvaluepairs",version:1},k=k||window.indexedDB||window.webkitIndexedDB||window.mozIndexedDB||window.OIndexedDB||window.msIndexedDB;if(k){var l={_driver:"asyncStorage",_initStorage:a,getItem:b,setItem:c,removeItem:d,clear:e,length:f,key:g};"function"==typeof define&&define.amd?define("asyncStorage",function(){return l}):"undefined"!=typeof module&&module.exports?module.exports=l:this.asyncStorage=l}}.call(this),function(){"use strict";function a(a){if(a)for(var b in l)void 0!==a[b]&&(l[b]=a[b]);return k=l.name+"/",m.resolve()}function b(a){var b=this;return new m(function(c){b.ready().then(function(){n.clear(),a&&a(),c()})})}function c(a,b){var c=this;return new m(function(d,e){c.ready().then(function(){try{var c=n.getItem(k+a);c&&(c=g(c)),b&&b(c),d(c)}catch(f){e(f)}})})}function d(a,b){var c=this;return new m(function(d){c.ready().then(function(){var c=n.key(a);c&&(c=c.substring(k.length)),b&&b(c),d(c)})})}function e(a){var b=this;return new m(function(c){b.ready().then(function(){var b=n.length;a&&a(b),c(b)})})}function f(a,b){var c=this;return new m(function(d){c.ready().then(function(){n.removeItem(k+a),b&&b(),d()})})}function g(a){if(a.substring(0,q)!==p)return JSON.parse(a);for(var b=a.substring(C),c=a.substring(q,C),d=new ArrayBuffer(2*b.length),e=new Uint16Array(d),f=b.length-1;f>=0;f--)e[f]=b.charCodeAt(f);switch(c){case r:return d;case s:return new Blob([d]);case t:return new Int8Array(d);case u:return new Uint8Array(d);case v:return new Uint8ClampedArray(d);case w:return new Int16Array(d);case y:return new Uint16Array(d);case x:return new Int32Array(d);case z:return new Uint32Array(d);case A:return new Float32Array(d);case B:return new Float64Array(d);default:throw new Error("Unkown type: "+c)}}function h(a){var b="",c=new Uint16Array(a);try{b=String.fromCharCode.apply(null,c)}catch(d){for(var e=0;e<c.length;e++)b+=String.fromCharCode(c[e])}return b}function i(a,b){var c="";if(a&&(c=a.toString()),a&&("[object ArrayBuffer]"===a.toString()||a.buffer&&"[object ArrayBuffer]"===a.buffer.toString())){var d,e=p;a instanceof ArrayBuffer?(d=a,e+=r):(d=a.buffer,"[object Int8Array]"===c?e+=t:"[object Uint8Array]"===c?e+=u:"[object Uint8ClampedArray]"===c?e+=v:"[object Int16Array]"===c?e+=w:"[object Uint16Array]"===c?e+=y:"[object Int32Array]"===c?e+=x:"[object Uint32Array]"===c?e+=z:"[object Float32Array]"===c?e+=A:"[object Float64Array]"===c?e+=B:b(new Error("Failed to get type for BinaryArray")));var f=h(d);b(null,e+f)}else if("[object Blob]"===c){var g=new FileReader;g.onload=function(){var a=h(this.result);b(null,p+s+a)},g.readAsArrayBuffer(a)}else try{b(null,JSON.stringify(a))}catch(i){console.error("Couldn't convert value into a JSON string: ",a),b(i)}}function j(a,b,c){var d=this;return new m(function(e,f){d.ready().then(function(){void 0===b&&(b=null);var d=b;i(b,function(b,g){b?f(b):(n.setItem(k+a,g),c&&c(d),e(d))})})})}var k="",l={name:"localforage"},m=window.Promise,n=null;try{n=window.localStorage}catch(o){return}var p="__lfsc__:",q=p.length,r="arbf",s="blob",t="si08",u="ui08",v="uic8",w="si16",x="si32",y="ur16",z="ui32",A="fl32",B="fl64",C=q+r.length,D={_driver:"localStorageWrapper",_initStorage:a,getItem:c,setItem:j,removeItem:f,clear:b,length:e,key:d};"function"==typeof define&&define.amd?define("localStorageWrapper",function(){return D}):"undefined"!=typeof module&&module.exports?module.exports=D:this.localStorageWrapper=D}.call(this),function(){"use strict";function a(a){if(a)for(var b in o)void 0!==a[b]&&(o[b]="string"!=typeof a[b]?a[b].toString():a[b]);return new m(function(a){n=window.openDatabase(o.name,o.version,o.description,l),n.transaction(function(b){b.executeSql("CREATE TABLE IF NOT EXISTS "+o.storeName+" (id INTEGER PRIMARY KEY, key unique, value)",[],function(){a()},null)})})}function b(a,b){var c=this;return new m(function(d){c.ready().then(function(){n.transaction(function(c){c.executeSql("SELECT * FROM "+o.storeName+" WHERE key = ? LIMIT 1",[a],function(a,c){var e=c.rows.length?c.rows.item(0).value:null;e&&(e=i(e)),b&&b(e),d(e)},null)})})})}function c(a,b,c){var d=this;return new m(function(e,f){d.ready().then(function(){void 0===b&&(b=null);var d=b;j(b,function(b,g){b?f(b):n.transaction(function(b){b.executeSql("INSERT OR REPLACE INTO "+o.storeName+" (key, value) VALUES (?, ?)",[a,g],function(){c&&c(d),e(d)},null)})})})})}function d(a,b){var c=this;return new m(function(d){c.ready().then(function(){n.transaction(function(c){c.executeSql("DELETE FROM "+o.storeName+" WHERE key = ?",[a],function(){b&&b(),d()},null)})})})}function e(a){var b=this;return new m(function(c){b.ready().then(function(){n.transaction(function(b){b.executeSql("DELETE FROM "+o.storeName,[],function(){a&&a(),c()},null)})})})}function f(a){var b=this;return new m(function(c){b.ready().then(function(){n.transaction(function(b){b.executeSql("SELECT COUNT(key) as c FROM "+o.storeName,[],function(b,d){var e=d.rows.item(0).c;a&&a(e),c(e)},null)})})})}function g(a,b){var c=this;return new m(function(d){c.ready().then(function(){n.transaction(function(c){c.executeSql("SELECT key FROM "+o.storeName+" WHERE id = ? LIMIT 1",[a+1],function(a,c){var e=c.rows.length?c.rows.item(0).key:null;b&&b(e),d(e)},null)})})})}function h(a){var b,c=new Uint8Array(a),d="";for(b=0;b<c.length;b+=3)d+=k[c[b]>>2],d+=k[(3&c[b])<<4|c[b+1]>>4],d+=k[(15&c[b+1])<<2|c[b+2]>>6],d+=k[63&c[b+2]];return c.length%3===2?d=d.substring(0,d.length-1)+"=":c.length%3===1&&(d=d.substring(0,d.length-2)+"=="),d}function i(a){if(a.substring(0,q)!==p)return JSON.parse(a);var b,c,d,e,f,g=a.substring(C),h=a.substring(q,C),i=.75*g.length,j=g.length,l=0;"="===g[g.length-1]&&(i--,"="===g[g.length-2]&&i--);var m=new ArrayBuffer(i),n=new Uint8Array(m);for(b=0;j>b;b+=4)c=k.indexOf(g[b]),d=k.indexOf(g[b+1]),e=k.indexOf(g[b+2]),f=k.indexOf(g[b+3]),n[l++]=c<<2|d>>4,n[l++]=(15&d)<<4|e>>2,n[l++]=(3&e)<<6|63&f;switch(h){case r:return m;case s:return new Blob([m]);case t:return new Int8Array(m);case u:return new Uint8Array(m);case v:return new Uint8ClampedArray(m);case w:return new Int16Array(m);case y:return new Uint16Array(m);case x:return new Int32Array(m);case z:return new Uint32Array(m);case A:return new Float32Array(m);case B:return new Float64Array(m);default:throw new Error("Unkown type: "+h)}}function j(a,b){var c="";if(a&&(c=a.toString()),a&&("[object ArrayBuffer]"===a.toString()||a.buffer&&"[object ArrayBuffer]"===a.buffer.toString())){var d,e=p;a instanceof ArrayBuffer?(d=a,e+=r):(d=a.buffer,"[object Int8Array]"===c?e+=t:"[object Uint8Array]"===c?e+=u:"[object Uint8ClampedArray]"===c?e+=v:"[object Int16Array]"===c?e+=w:"[object Uint16Array]"===c?e+=y:"[object Int32Array]"===c?e+=x:"[object Uint32Array]"===c?e+=z:"[object Float32Array]"===c?e+=A:"[object Float64Array]"===c?e+=B:b(new Error("Failed to get type for BinaryArray")));var f=h(d);b(null,e+f)}else if("[object Blob]"===c){var g=new FileReader;g.onload=function(){var a=h(this.result);b(null,p+s+a)},g.readAsArrayBuffer(a)}else try{b(null,JSON.stringify(a))}catch(i){console.error("Couldn't convert value into a JSON string: ",a),b(i)}}var k="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",l=4980736,m=window.Promise,n=null,o={description:"",name:"localforage",storeName:"keyvaluepairs",version:"1.0"},p="__lfsc__:",q=p.length,r="arbf",s="blob",t="si08",u="ui08",v="uic8",w="si16",x="si32",y="ur16",z="ui32",A="fl32",B="fl64",C=q+r.length;if(window.openDatabase){var D={_driver:"webSQLStorage",_initStorage:a,getItem:b,setItem:c,removeItem:d,clear:e,length:f,key:g};"function"==typeof define&&define.amd?define("webSQLStorage",function(){return D}):"undefined"!=typeof module&&module.exports?module.exports=D:this.webSQLStorage=D}}.call(this),function(){"use strict";var a=window.Promise,b=1,c=2,d=3,e=d;"function"==typeof define&&define.amd?e=b:"undefined"!=typeof module&&module.exports&&(e=c);var f,g=g||window.indexedDB||window.webkitIndexedDB||window.mozIndexedDB||window.OIndexedDB||window.msIndexedDB,h=this,i={INDEXEDDB:"asyncStorage",LOCALSTORAGE:"localStorageWrapper",WEBSQL:"webSQLStorage",driver:function(){return this._driver||null},_ready:a.reject(new Error("setDriver() wasn't called")),setDriver:function(d,f){return this._ready=new a(function(a,j){if(!g&&d===i.INDEXEDDB||!window.openDatabase&&d===i.WEBSQL)return f&&f(i),void j(i);if(e===b)require([d],function(b){i._extend(b),i._initStorage(window.localForageConfig).then(function(){f&&f(i),a(i)})});else if(e===c){var k;switch(d){case i.INDEXEDDB:k=require("localforage/src/drivers/indexeddb");break;case i.LOCALSTORAGE:k=require("localforage/src/drivers/localstorage");break;case i.WEBSQL:k=require("localforage/src/drivers/websql")}i._extend(k),i._initStorage(window.localForageConfig).then(function(){f&&f(i),a(i)})}else i._extend(h[d]),i._initStorage(window.localForageConfig).then(function(){f&&f(i),a(i)})}),i._ready},ready:function(){return this._ready},_extend:function(a){for(var b in a)a.hasOwnProperty(b)&&(this[b]=a[b])}};f=g?i.INDEXEDDB:window.openDatabase?i.WEBSQL:i.LOCALSTORAGE,i.setDriver(f),e===b?define(function(){return i}):e===c?module.exports=i:this.localforage=i}.call(this); |
/*global exports:true, require:true */ | ||
module.exports = exports = function(grunt) { | ||
'use strict'; | ||
grunt.initConfig({ | ||
@@ -64,3 +65,4 @@ casper: { | ||
src: [ | ||
'vendor/promise.js', | ||
// https://github.com/jakearchibald/es6-promise | ||
'bower_components/es6-promise/promise.js', | ||
'src/drivers/**/*.js', | ||
@@ -89,5 +91,5 @@ 'src/localforage.js' | ||
watch: { | ||
concat: { | ||
build: { | ||
files: ['src/*.js', 'src/**/*.js'], | ||
tasks: ['concat'] | ||
tasks: ['build'] | ||
}, | ||
@@ -98,6 +100,2 @@ grunt: { | ||
] | ||
}, | ||
test: { | ||
files: ['src/*.js', 'src/**/*.js'], | ||
tasks: ['test'] | ||
} | ||
@@ -104,0 +102,0 @@ } |
@@ -11,3 +11,3 @@ { | ||
], | ||
"version": "0.1.1", | ||
"version": "0.2.0", | ||
"homepage": "https://github.com/mozilla/localForage", | ||
@@ -14,0 +14,0 @@ "repository": { |
@@ -52,4 +52,5 @@ (function() { | ||
function getItem(key, callback) { | ||
var _this = this; | ||
return new Promise(function(resolve, reject) { | ||
localforage.ready().then(function() { | ||
_this.ready().then(function() { | ||
var store = db.transaction(dbInfo.storeName, 'readonly').objectStore(dbInfo.storeName); | ||
@@ -76,4 +77,5 @@ var req = store.get(key); | ||
function setItem(key, value, callback) { | ||
var _this = this; | ||
return new Promise(function(resolve, reject) { | ||
localforage.ready().then(function() { | ||
_this.ready().then(function() { | ||
var store = db.transaction(dbInfo.storeName, 'readwrite').objectStore(dbInfo.storeName); | ||
@@ -106,4 +108,5 @@ | ||
function removeItem(key, callback) { | ||
var _this = this; | ||
return new Promise(function(resolve, reject) { | ||
localforage.ready().then(function() { | ||
_this.ready().then(function() { | ||
var store = db.transaction(dbInfo.storeName, 'readwrite').objectStore(dbInfo.storeName); | ||
@@ -135,4 +138,5 @@ | ||
function clear(callback) { | ||
var _this = this; | ||
return new Promise(function(resolve, reject) { | ||
localforage.ready().then(function() { | ||
_this.ready().then(function() { | ||
var store = db.transaction(dbInfo.storeName, 'readwrite').objectStore(dbInfo.storeName); | ||
@@ -155,4 +159,5 @@ var req = store.clear(); | ||
function length(callback) { | ||
var _this = this; | ||
return new Promise(function(resolve, reject) { | ||
localforage.ready().then(function() { | ||
_this.ready().then(function() { | ||
var store = db.transaction(dbInfo.storeName, 'readonly').objectStore(dbInfo.storeName); | ||
@@ -175,2 +180,3 @@ var req = store.count(); | ||
function key(n, callback) { | ||
var _this = this; | ||
return new Promise(function(resolve, reject) { | ||
@@ -187,3 +193,3 @@ if (n < 0) { | ||
localforage.ready().then(function() { | ||
_this.ready().then(function() { | ||
var store = db.transaction(dbInfo.storeName, 'readonly').objectStore(dbInfo.storeName); | ||
@@ -190,0 +196,0 @@ |
@@ -44,7 +44,25 @@ // If IndexedDB isn't available, we'll fall back to localStorage. | ||
var SERIALIZED_MARKER = '__lfsc__:'; | ||
var SERIALIZED_MARKER_LENGTH = SERIALIZED_MARKER.length; | ||
// OMG the serializations! | ||
var TYPE_ARRAYBUFFER = 'arbf'; | ||
var TYPE_BLOB = 'blob'; | ||
var TYPE_INT8ARRAY = 'si08'; | ||
var TYPE_UINT8ARRAY = 'ui08'; | ||
var TYPE_UINT8CLAMPEDARRAY = 'uic8'; | ||
var TYPE_INT16ARRAY = 'si16'; | ||
var TYPE_INT32ARRAY = 'si32'; | ||
var TYPE_UINT16ARRAY = 'ur16'; | ||
var TYPE_UINT32ARRAY = 'ui32'; | ||
var TYPE_FLOAT32ARRAY = 'fl32'; | ||
var TYPE_FLOAT64ARRAY = 'fl64'; | ||
var TYPE_SERIALIZED_MARKER_LENGTH = SERIALIZED_MARKER_LENGTH + TYPE_ARRAYBUFFER.length; | ||
// Remove all keys from the datastore, effectively destroying all data in | ||
// the app's key/value store! | ||
function clear(callback) { | ||
var _this = this; | ||
return new Promise(function(resolve, reject) { | ||
localforage.ready().then(function() { | ||
_this.ready().then(function() { | ||
localStorage.clear(); | ||
@@ -65,12 +83,14 @@ | ||
function getItem(key, callback) { | ||
var _this = this; | ||
return new Promise(function(resolve, reject) { | ||
localforage.ready().then(function() { | ||
_this.ready().then(function() { | ||
try { | ||
var result = localStorage.getItem(keyPrefix + key); | ||
// If a result was found, parse it from serialized JSON into a | ||
// JS object. If result isn't truthy, the key is likely | ||
// undefined and we'll pass it straight to the callback. | ||
// If a result was found, parse it from the serialized | ||
// string into a JS object. If result isn't truthy, the key | ||
// is likely undefined and we'll pass it straight to the | ||
// callback. | ||
if (result) { | ||
result = JSON.parse(result); | ||
result = _deserialize(result); | ||
} | ||
@@ -92,4 +112,5 @@ | ||
function key(n, callback) { | ||
var _this = this; | ||
return new Promise(function(resolve, reject) { | ||
localforage.ready().then(function() { | ||
_this.ready().then(function() { | ||
var result = localStorage.key(n); | ||
@@ -112,4 +133,5 @@ | ||
function length(callback) { | ||
var _this = this; | ||
return new Promise(function(resolve, reject) { | ||
localforage.ready().then(function() { | ||
_this.ready().then(function() { | ||
var result = localStorage.length; | ||
@@ -128,4 +150,5 @@ | ||
function removeItem(key, callback) { | ||
var _this = this; | ||
return new Promise(function(resolve, reject) { | ||
localforage.ready().then(function() { | ||
_this.ready().then(function() { | ||
localStorage.removeItem(keyPrefix + key); | ||
@@ -142,2 +165,154 @@ | ||
// Deserialize data we've inserted into a value column/field. We place | ||
// special markers into our strings to mark them as encoded; this isn't | ||
// as nice as a meta field, but it's the only sane thing we can do whilst | ||
// keeping localStorage support intact. | ||
// | ||
// Oftentimes this will just deserialize JSON content, but if we have a | ||
// special marker (SERIALIZED_MARKER, defined above), we will extract | ||
// some kind of arraybuffer/binary data/typed array out of the string. | ||
function _deserialize(value) { | ||
// If we haven't marked this string as being specially serialized (i.e. | ||
// something other than serialized JSON), we can just return it and be | ||
// done with it. | ||
if (value.substring(0, SERIALIZED_MARKER_LENGTH) !== SERIALIZED_MARKER) { | ||
return JSON.parse(value); | ||
} | ||
// The following code deals with deserializing some kind of Blob or | ||
// TypedArray. First we separate out the type of data we're dealing | ||
// with from the data itself. | ||
var serializedString = value.substring(TYPE_SERIALIZED_MARKER_LENGTH); | ||
var type = value.substring(SERIALIZED_MARKER_LENGTH, TYPE_SERIALIZED_MARKER_LENGTH); | ||
// Fill the string into a ArrayBuffer. | ||
var buffer = new ArrayBuffer(serializedString.length * 2); // 2 bytes for each char | ||
var bufferView = new Uint16Array(buffer); | ||
for (var i = serializedString.length - 1; i >= 0; i--) { | ||
bufferView[i] = serializedString.charCodeAt(i); | ||
} | ||
// Return the right type based on the code/type set during | ||
// serialization. | ||
switch (type) { | ||
case TYPE_ARRAYBUFFER: | ||
return buffer; | ||
case TYPE_BLOB: | ||
return new Blob([buffer]); | ||
case TYPE_INT8ARRAY: | ||
return new Int8Array(buffer); | ||
case TYPE_UINT8ARRAY: | ||
return new Uint8Array(buffer); | ||
case TYPE_UINT8CLAMPEDARRAY: | ||
return new Uint8ClampedArray(buffer); | ||
case TYPE_INT16ARRAY: | ||
return new Int16Array(buffer); | ||
case TYPE_UINT16ARRAY: | ||
return new Uint16Array(buffer); | ||
case TYPE_INT32ARRAY: | ||
return new Int32Array(buffer); | ||
case TYPE_UINT32ARRAY: | ||
return new Uint32Array(buffer); | ||
case TYPE_FLOAT32ARRAY: | ||
return new Float32Array(buffer); | ||
case TYPE_FLOAT64ARRAY: | ||
return new Float64Array(buffer); | ||
default: | ||
throw new Error('Unkown type: ' + type); | ||
} | ||
} | ||
// Converts a buffer to a string to store, serialized, in the backend | ||
// storage library. | ||
function _bufferToString(buffer) { | ||
var str = ''; | ||
var uint16Array = new Uint16Array(buffer); | ||
try { | ||
str = String.fromCharCode.apply(null, uint16Array); | ||
} catch (e) { | ||
// This is a fallback implementation in case the first one does | ||
// not work. This is required to get the phantomjs passing... | ||
for (var i = 0; i < uint16Array.length; i++) { | ||
str += String.fromCharCode(uint16Array[i]); | ||
} | ||
} | ||
return str; | ||
} | ||
// Serialize a value, afterwards executing a callback (which usually | ||
// instructs the `setItem()` callback/promise to be executed). This is how | ||
// we store binary data with localStorage. | ||
function _serialize(value, callback) { | ||
var valueString = ''; | ||
if (value) { | ||
valueString = value.toString(); | ||
} | ||
// Cannot use `value instanceof ArrayBuffer` or such here, as these | ||
// checks fail when running the tests using casper.js... | ||
// | ||
// TODO: See why those tests fail and use a better solution. | ||
if (value && (value.toString() === '[object ArrayBuffer]' || | ||
value.buffer && value.buffer.toString() === '[object ArrayBuffer]')) { | ||
// Convert binary arrays to a string and prefix the string with | ||
// a special marker. | ||
var buffer; | ||
var marker = SERIALIZED_MARKER; | ||
if (value instanceof ArrayBuffer) { | ||
buffer = value; | ||
marker += TYPE_ARRAYBUFFER; | ||
} else { | ||
buffer = value.buffer; | ||
if (valueString === '[object Int8Array]') { | ||
marker += TYPE_INT8ARRAY; | ||
} else if (valueString === '[object Uint8Array]') { | ||
marker += TYPE_UINT8ARRAY; | ||
} else if (valueString === '[object Uint8ClampedArray]') { | ||
marker += TYPE_UINT8CLAMPEDARRAY; | ||
} else if (valueString === '[object Int16Array]') { | ||
marker += TYPE_INT16ARRAY; | ||
} else if (valueString === '[object Uint16Array]') { | ||
marker += TYPE_UINT16ARRAY; | ||
} else if (valueString === '[object Int32Array]') { | ||
marker += TYPE_INT32ARRAY; | ||
} else if (valueString === '[object Uint32Array]') { | ||
marker += TYPE_UINT32ARRAY; | ||
} else if (valueString === '[object Float32Array]') { | ||
marker += TYPE_FLOAT32ARRAY; | ||
} else if (valueString === '[object Float64Array]') { | ||
marker += TYPE_FLOAT64ARRAY; | ||
} else { | ||
callback(new Error("Failed to get type for BinaryArray")); | ||
} | ||
} | ||
var str = _bufferToString(buffer); | ||
callback(null, marker + str); | ||
} else if (valueString === "[object Blob]") { | ||
// Conver the blob to a binaryArray and then to a string. | ||
var fileReader = new FileReader(); | ||
fileReader.onload = function() { | ||
var str = _bufferToString(this.result); | ||
callback(null, SERIALIZED_MARKER + TYPE_BLOB + str); | ||
}; | ||
fileReader.readAsArrayBuffer(value); | ||
} else { | ||
try { | ||
callback(null, JSON.stringify(value)); | ||
} catch (e) { | ||
console.error("Couldn't convert value into a JSON string: ", | ||
value); | ||
callback(e); | ||
} | ||
} | ||
} | ||
// Set a key's value and run an optional callback once the value is set. | ||
@@ -148,4 +323,5 @@ // Unlike Gaia's implementation, the callback function is passed the value, | ||
function setItem(key, value, callback) { | ||
var _this = this; | ||
return new Promise(function(resolve, reject) { | ||
localforage.ready().then(function() { | ||
_this.ready().then(function() { | ||
// Convert undefined values to null. | ||
@@ -160,15 +336,15 @@ // https://github.com/mozilla/localForage/pull/42 | ||
try { | ||
value = JSON.stringify(value); | ||
} catch (e) { | ||
reject(e); | ||
} | ||
_serialize(value, function setSerialized(error, value) { | ||
if (error) { | ||
reject(error); | ||
} else { | ||
localStorage.setItem(keyPrefix + key, value); | ||
localStorage.setItem(keyPrefix + key, value); | ||
if (callback) { | ||
callback(originalValue); | ||
} | ||
if (callback) { | ||
callback(originalValue); | ||
} | ||
resolve(originalValue); | ||
resolve(originalValue); | ||
} | ||
}); | ||
}); | ||
@@ -175,0 +351,0 @@ }); |
@@ -0,4 +1,18 @@ | ||
/* | ||
* Includes code from: | ||
* | ||
* base64-arraybuffer | ||
* https://github.com/niklasvh/base64-arraybuffer | ||
* | ||
* Copyright (c) 2012 Niklas von Hertzen | ||
* Licensed under the MIT license. | ||
*/ | ||
(function() { | ||
'use strict'; | ||
// Sadly, the best way to save binary data in WebSQL is Base64 serializing | ||
// it, so this is how we store it to prevent very strange errors with less | ||
// verbose ways of binary <-> string data storage. | ||
var BASE_CHARS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; | ||
// Default DB size is _JUST UNDER_ 5MB, as it's the highest size we can use | ||
@@ -9,4 +23,3 @@ // without a prompt. | ||
var DB_SIZE = 4980736; | ||
var SERIALIZED_MARKER = '__lfsc__:'; | ||
var SERIALIZED_MARKER_LENGTH = SERIALIZED_MARKER.length; | ||
var Promise = window.Promise; | ||
@@ -21,2 +34,19 @@ var db = null; | ||
var SERIALIZED_MARKER = '__lfsc__:'; | ||
var SERIALIZED_MARKER_LENGTH = SERIALIZED_MARKER.length; | ||
// OMG the serializations! | ||
var TYPE_ARRAYBUFFER = 'arbf'; | ||
var TYPE_BLOB = 'blob'; | ||
var TYPE_INT8ARRAY = 'si08'; | ||
var TYPE_UINT8ARRAY = 'ui08'; | ||
var TYPE_UINT8CLAMPEDARRAY = 'uic8'; | ||
var TYPE_INT16ARRAY = 'si16'; | ||
var TYPE_INT32ARRAY = 'si32'; | ||
var TYPE_UINT16ARRAY = 'ur16'; | ||
var TYPE_UINT32ARRAY = 'ui32'; | ||
var TYPE_FLOAT32ARRAY = 'fl32'; | ||
var TYPE_FLOAT64ARRAY = 'fl64'; | ||
var TYPE_SERIALIZED_MARKER_LENGTH = SERIALIZED_MARKER_LENGTH + TYPE_ARRAYBUFFER.length; | ||
// If WebSQL methods aren't available, we can stop now. | ||
@@ -54,4 +84,5 @@ if (!window.openDatabase) { | ||
function getItem(key, callback) { | ||
var _this = this; | ||
return new Promise(function(resolve, reject) { | ||
localforage.ready().then(function() { | ||
_this.ready().then(function() { | ||
db.transaction(function (t) { | ||
@@ -63,8 +94,4 @@ t.executeSql('SELECT * FROM ' + dbInfo.storeName + ' WHERE key = ? LIMIT 1', [key], function (t, results) { | ||
// unpack. | ||
if (result && result.substr(0, SERIALIZED_MARKER_LENGTH) === SERIALIZED_MARKER) { | ||
try { | ||
result = JSON.parse(result.slice(SERIALIZED_MARKER_LENGTH)); | ||
} catch (e) { | ||
reject(e); | ||
} | ||
if (result) { | ||
result = _deserialize(result); | ||
} | ||
@@ -84,4 +111,5 @@ | ||
function setItem(key, value, callback) { | ||
var _this = this; | ||
return new Promise(function(resolve, reject) { | ||
localforage.ready().then(function() { | ||
_this.ready().then(function() { | ||
// The localStorage API doesn't return undefined values in an | ||
@@ -94,23 +122,19 @@ // "expected" way, so undefined is always cast to null in all | ||
// We need to serialize certain types of objects using WebSQL; | ||
// otherwise they'll get stored as strings as be useless when we | ||
// use getItem() later. | ||
var valueToSave; | ||
if (typeof(value) === 'boolean' || typeof(value) === 'number' || typeof(value) === 'object') { | ||
// Mark the content as "localForage serialized content" so we | ||
// know to run JSON.parse() on it when we get it back out from | ||
// the database. | ||
valueToSave = SERIALIZED_MARKER + JSON.stringify(value); | ||
} else { | ||
valueToSave = value; | ||
} | ||
// Save the original value to pass to the callback. | ||
var originalValue = value; | ||
db.transaction(function (t) { | ||
t.executeSql('INSERT OR REPLACE INTO ' + dbInfo.storeName + ' (key, value) VALUES (?, ?)', [key, valueToSave], function() { | ||
if (callback) { | ||
callback(value); | ||
} | ||
_serialize(value, function setItemserializeValueCallback(error, value) { | ||
if (error) { | ||
reject(error); | ||
} else { | ||
db.transaction(function (t) { | ||
t.executeSql('INSERT OR REPLACE INTO ' + dbInfo.storeName + ' (key, value) VALUES (?, ?)', [key, value], function() { | ||
if (callback) { | ||
callback(originalValue); | ||
} | ||
resolve(value); | ||
}, null); | ||
resolve(originalValue); | ||
}, null); | ||
}); | ||
} | ||
}); | ||
@@ -122,4 +146,5 @@ }); | ||
function removeItem(key, callback) { | ||
var _this = this; | ||
return new Promise(function(resolve, reject) { | ||
localforage.ready().then(function() { | ||
_this.ready().then(function() { | ||
db.transaction(function (t) { | ||
@@ -141,4 +166,5 @@ t.executeSql('DELETE FROM ' + dbInfo.storeName + ' WHERE key = ?', [key], function() { | ||
function clear(callback) { | ||
var _this = this; | ||
return new Promise(function(resolve, reject) { | ||
localforage.ready().then(function() { | ||
_this.ready().then(function() { | ||
db.transaction(function (t) { | ||
@@ -160,4 +186,5 @@ t.executeSql('DELETE FROM ' + dbInfo.storeName, [], function(t, results) { | ||
function length(callback) { | ||
var _this = this; | ||
return new Promise(function(resolve, reject) { | ||
localforage.ready().then(function() { | ||
_this.ready().then(function() { | ||
db.transaction(function (t) { | ||
@@ -187,4 +214,5 @@ // Ahhh, SQL makes this one soooooo easy. | ||
function key(n, callback) { | ||
var _this = this; | ||
return new Promise(function(resolve, reject) { | ||
localforage.ready().then(function() { | ||
_this.ready().then(function() { | ||
db.transaction(function (t) { | ||
@@ -205,2 +233,180 @@ t.executeSql('SELECT key FROM ' + dbInfo.storeName + ' WHERE id = ? LIMIT 1', [n + 1], function (t, results) { | ||
// Converts a buffer to a string to store, serialized, in the backend | ||
// storage library. | ||
function _bufferToString(buffer) { | ||
// base64-arraybuffer | ||
var bytes = new Uint8Array(buffer); | ||
var i; | ||
var base64String = ''; | ||
for (i = 0; i < bytes.length; i += 3) { | ||
base64String += BASE_CHARS[bytes[i] >> 2]; | ||
base64String += BASE_CHARS[((bytes[i] & 3) << 4) | (bytes[i + 1] >> 4)]; | ||
base64String += BASE_CHARS[((bytes[i + 1] & 15) << 2) | (bytes[i + 2] >> 6)]; | ||
base64String += BASE_CHARS[bytes[i + 2] & 63]; | ||
} | ||
if ((bytes.length % 3) === 2) { | ||
base64String = base64String.substring(0, base64String.length - 1) + "="; | ||
} else if (bytes.length % 3 === 1) { | ||
base64String = base64String.substring(0, base64String.length - 2) + "=="; | ||
} | ||
return base64String; | ||
} | ||
// Deserialize data we've inserted into a value column/field. We place | ||
// special markers into our strings to mark them as encoded; this isn't | ||
// as nice as a meta field, but it's the only sane thing we can do whilst | ||
// keeping localStorage support intact. | ||
// | ||
// Oftentimes this will just deserialize JSON content, but if we have a | ||
// special marker (SERIALIZED_MARKER, defined above), we will extract | ||
// some kind of arraybuffer/binary data/typed array out of the string. | ||
function _deserialize(value) { | ||
// If we haven't marked this string as being specially serialized (i.e. | ||
// something other than serialized JSON), we can just return it and be | ||
// done with it. | ||
if (value.substring(0, SERIALIZED_MARKER_LENGTH) !== SERIALIZED_MARKER) { | ||
return JSON.parse(value); | ||
} | ||
// The following code deals with deserializing some kind of Blob or | ||
// TypedArray. First we separate out the type of data we're dealing | ||
// with from the data itself. | ||
var serializedString = value.substring(TYPE_SERIALIZED_MARKER_LENGTH); | ||
var type = value.substring(SERIALIZED_MARKER_LENGTH, TYPE_SERIALIZED_MARKER_LENGTH); | ||
// Fill the string into a ArrayBuffer. | ||
var bufferLength = serializedString.length * 0.75; | ||
var len = serializedString.length; | ||
var i; | ||
var p = 0; | ||
var encoded1, encoded2, encoded3, encoded4; | ||
if (serializedString[serializedString.length - 1] === "=") { | ||
bufferLength--; | ||
if (serializedString[serializedString.length - 2] === "=") { | ||
bufferLength--; | ||
} | ||
} | ||
var buffer = new ArrayBuffer(bufferLength); | ||
var bytes = new Uint8Array(buffer); | ||
for (i = 0; i < len; i+=4) { | ||
encoded1 = BASE_CHARS.indexOf(serializedString[i]); | ||
encoded2 = BASE_CHARS.indexOf(serializedString[i+1]); | ||
encoded3 = BASE_CHARS.indexOf(serializedString[i+2]); | ||
encoded4 = BASE_CHARS.indexOf(serializedString[i+3]); | ||
bytes[p++] = (encoded1 << 2) | (encoded2 >> 4); | ||
bytes[p++] = ((encoded2 & 15) << 4) | (encoded3 >> 2); | ||
bytes[p++] = ((encoded3 & 3) << 6) | (encoded4 & 63); | ||
} | ||
// Return the right type based on the code/type set during | ||
// serialization. | ||
switch (type) { | ||
case TYPE_ARRAYBUFFER: | ||
return buffer; | ||
case TYPE_BLOB: | ||
return new Blob([buffer]); | ||
case TYPE_INT8ARRAY: | ||
return new Int8Array(buffer); | ||
case TYPE_UINT8ARRAY: | ||
return new Uint8Array(buffer); | ||
case TYPE_UINT8CLAMPEDARRAY: | ||
return new Uint8ClampedArray(buffer); | ||
case TYPE_INT16ARRAY: | ||
return new Int16Array(buffer); | ||
case TYPE_UINT16ARRAY: | ||
return new Uint16Array(buffer); | ||
case TYPE_INT32ARRAY: | ||
return new Int32Array(buffer); | ||
case TYPE_UINT32ARRAY: | ||
return new Uint32Array(buffer); | ||
case TYPE_FLOAT32ARRAY: | ||
return new Float32Array(buffer); | ||
case TYPE_FLOAT64ARRAY: | ||
return new Float64Array(buffer); | ||
default: | ||
throw new Error('Unkown type: ' + type); | ||
} | ||
} | ||
// Serialize a value, afterwards executing a callback (which usually | ||
// instructs the `setItem()` callback/promise to be executed). This is how | ||
// we store binary data with localStorage. | ||
function _serialize(value, callback) { | ||
var valueString = ''; | ||
if (value) { | ||
valueString = value.toString(); | ||
} | ||
// Cannot use `value instanceof ArrayBuffer` or such here, as these | ||
// checks fail when running the tests using casper.js... | ||
// | ||
// TODO: See why those tests fail and use a better solution. | ||
if (value && (value.toString() === '[object ArrayBuffer]' || | ||
value.buffer && value.buffer.toString() === '[object ArrayBuffer]')) { | ||
// Convert binary arrays to a string and prefix the string with | ||
// a special marker. | ||
var buffer; | ||
var marker = SERIALIZED_MARKER; | ||
if (value instanceof ArrayBuffer) { | ||
buffer = value; | ||
marker += TYPE_ARRAYBUFFER; | ||
} else { | ||
buffer = value.buffer; | ||
if (valueString === '[object Int8Array]') { | ||
marker += TYPE_INT8ARRAY; | ||
} else if (valueString === '[object Uint8Array]') { | ||
marker += TYPE_UINT8ARRAY; | ||
} else if (valueString === '[object Uint8ClampedArray]') { | ||
marker += TYPE_UINT8CLAMPEDARRAY; | ||
} else if (valueString === '[object Int16Array]') { | ||
marker += TYPE_INT16ARRAY; | ||
} else if (valueString === '[object Uint16Array]') { | ||
marker += TYPE_UINT16ARRAY; | ||
} else if (valueString === '[object Int32Array]') { | ||
marker += TYPE_INT32ARRAY; | ||
} else if (valueString === '[object Uint32Array]') { | ||
marker += TYPE_UINT32ARRAY; | ||
} else if (valueString === '[object Float32Array]') { | ||
marker += TYPE_FLOAT32ARRAY; | ||
} else if (valueString === '[object Float64Array]') { | ||
marker += TYPE_FLOAT64ARRAY; | ||
} else { | ||
callback(new Error("Failed to get type for BinaryArray")); | ||
} | ||
} | ||
var str = _bufferToString(buffer); | ||
callback(null, marker + str); | ||
} else if (valueString === "[object Blob]") { | ||
// Conver the blob to a binaryArray and then to a string. | ||
var fileReader = new FileReader(); | ||
fileReader.onload = function() { | ||
var str = _bufferToString(this.result); | ||
callback(null, SERIALIZED_MARKER + TYPE_BLOB + str); | ||
}; | ||
fileReader.readAsArrayBuffer(value); | ||
} else { | ||
try { | ||
callback(null, JSON.stringify(value)); | ||
} catch (e) { | ||
console.error("Couldn't convert value into a JSON string: ", | ||
value); | ||
callback(e); | ||
} | ||
} | ||
} | ||
var webSQLStorage = { | ||
@@ -207,0 +413,0 @@ _driver: 'webSQLStorage', |
@@ -38,3 +38,3 @@ (function() { | ||
driver: function() { | ||
return localForage._driver || null; | ||
return this._driver || null; | ||
}, | ||
@@ -41,0 +41,0 @@ |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
4
784744
43
4636