GithubHelp home page GithubHelp logo

jstorage's Introduction

NB!

This project is in a frozen state. No more API changes. Pull requests for bug fixes are welcomed, anything else gets most probably ignored. A bug is something that breaks the application, outdated package file is not a bug.


jStorage

jStorage is a cross-browser key-value store database to store data locally in the browser - jStorage supports all major browsers, both in desktop (yes - even Internet Explorer 6) and in mobile.

Additionally jStorage is library agnostic, it works well with any other JavaScript library on the same webpage, be it jQuery, Prototype, MooTools or something else. Though you still need to have either a third party library (Prototype, MooTools) or JSON2 on the page to support older IE versions.

jStorage supports storing Strings, Numbers, JavaScript objects, Arrays and even native XML nodes which kind of makes it a JSON storage. jStorage also supports setting TTL values for auto expiring stored keys and - best of all - notifying other tabs/windows when a key has been changed, which makes jStorage also a local PubSub platform for web applications.

jStorage is pretty small, about 7kB when minified, 3kB gzipped.

Function reference

set(key, value[, options])

$.jStorage.set(key, value, options)

Saves a value to local storage. key needs to be string otherwise an exception is thrown. value can be any JSONeable value, including objects and arrays or a XML node. Currently XML nodes can't be nested inside other objects: $.jStorage.set("xml", xml_node) is OK but $.jStorage.set("xml", {xml: xml_node}) is not.

Options is an optional options object. Currently only available option is options.TTL which can be used to set the TTL value to the key $.jStorage.set(key, value, {TTL: 1000}). NB - if no TTL option value has been set, any currently used TTL value for the key will be removed.

get(key[, default])

value = $.jStorage.get(key)
value = $.jStorage.get(key, "default value")

get retrieves the value if key exists, or default if it doesn't. key needs to be string otherwise an exception is thrown. default can be any value.

deleteKey(key)

$.jStorage.deleteKey(key)

Removes a key from the storage. key needs to be string otherwise an exception is thrown.

setTTL(key, ttl)

$.jStorage.set("mykey", "keyvalue");
$.jStorage.setTTL("mykey", 3000); // expires in 3 seconds

Sets a TTL (in milliseconds) for an existing key. Use 0 or negative value to clear TTL.

getTTL(key)

ttl = $.jStorage.getTTL("mykey"); // TTL in milliseconds or 0

Gets remaining TTL (in milliseconds) for a key or 0 if not TTL has been set.

flush()

$.jStorage.flush()

Clears the cache.

index()

$.jStorage.index()

Returns all the keys currently in use as an array.

var index = $.jStorage.index();
console.log(index); // ["key1","key2","key3"]

storageSize()

$.jStorage.storageSize()

Returns the size of the stored data in bytes

currentBackend()

$.jStorage.currentBackend()

Returns the storage engine currently in use or false if none

reInit()

$.jStorage.reInit()

Reloads the data from browser storage

storageAvailable()

$.jStorage.storageAvailable()

Returns true if storage is available

subscribe(channel, callback)

$.jStorage.subscribe("ch1", function(channel, payload){
    console.log(payload+ " from " + channel);
});

Subscribes to a Publish/Subscribe channel (see demo)

publish(channel, payload)

$.jStorage.publish("ch1", "data");

Publishes payload to a Publish/Subscribe channel (see demo)

listenKeyChange(key, callback)

$.jStorage.listenKeyChange("mykey", function(key, action){
    console.log(key + " has been " + action);
});

Listens for updates for selected key. NB! even updates made in other windows/tabs are reflected, so this feature can also be used for some kind of publish/subscribe service.

If you want to listen for any key change, use "*" as the key name

$.jStorage.listenKeyChange("*", function(key, action){
    console.log(key + " has been " + action);
});

stopListening(key[, callback])

$.jStorage.stopListening("mykey"); // cancel all listeners for "mykey" change

Stops listening for key change. If callback is set, only the used callback will be cleared, otherwise all listeners will be dropped.

Donate

Support jStorage development

Donate to author

Features

jStorage supports the following features:

  • store and retrieve data from browser storage using any JSON compatible data format (+ native XML nodes)
  • set TTL values to stored keys for auto expiring
  • publish and subscribe to cross-window/tab events
  • listen for key changes (update, delete) from the current or any other browser window
  • use any browser since IE6, both in desktop and in mobile

Browser support

Current availability: jStorage supports all major browsers - Internet Explorer 6+, Firefox 2+, Safari 4+, Chrome 4+, Opera 10.50+

If the browser doesn't support data caching, then no exceptions are raised - jStorage can still be used by the script but nothing is actually stored.

License

Unlicense Since version 0.4.7

MIT (versions up to 0.4.6)

jstorage's People

Contributors

aghouseh avatar alexogar avatar altaflux avatar andris9 avatar arnabk avatar avdg avatar bitdeli-chef avatar elsigh avatar lachezar avatar markvantilburg avatar mattflaschen avatar mente avatar naterkane avatar niyazpk avatar punkstar avatar pwmckenna avatar stopdropandrew avatar udalmik avatar unera avatar yoyosh avatar yulanggong avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

jstorage's Issues

Error when setting keys in Safari 5.1.7 (both Win and Mac) with private browsing mode enabled

If I understand it correctly, jStorage should silently fail if it can't set keys/ no storage backend is available: "If the browser doesn't support data caching, then no exceptions are raised..."

However here is what happens in Safari 5.1.7 (both Win and Mac) with private browsing mode enabled:

In _init(), it sets _storage_elm = null; because it does not find any storage backend and returns. Consequently _load_storage() is not called and _storage is not extended with __jstorage_meta.CRC32.

When setting a key with jStorage.set, the following will throw an error:
_storage.__jstorage_meta.CRC32[key]

Error text is:

'undefined' is not an object (evaluating '_storage.__jstorage_meta.CRC32') TypeError

I didn't debug this in detail; I just know that this error message appears and I concluded everything else from this fact.

Calling $.jStorage.flush() throws exception "setting a property that has only a getter" in FF3.6

This exception "setting a property that has only a getter" is caused by line 271 in _createPolyfillStorage:

if(type == "local" && window.globalStorage){
    localStorage = window.globalStorage[window.location.hostname];
    return;
}

Firefox 3.6 does not allow overwriting of the window.localStorage and does not fail silently (like some other browsers do).

I am not quite sure why would you want to overwrite window.localStorage, but for now my fix is to surround localStorage = window.globalStorage[window.location.hostname]; with try-catch block.

Risky cache behaviour.

Internal variable _storage is used for caching purposes.
Suppose this example:

var b = {
    abc: function(abc) {
        return abc + '!';
    }
};

$.jStorage.set('b', b);

var b2 = $.jStorage.get('b');
log(b2.abc(123)); //shows '123! ', but should be 'error - no method abc'.

It gives the user the false understanding that he can store functions in storage.
But we understand, that in browser storage his object has no 'abc' method.

I think it is better to make cache real cache :)

Feature request: Support for sessionStorage

Helo Andris,

This is a nice plugin, with quite some features, but I was wondering if not possible to add sessionStorage to backEnd options ?

I mean to specify it by giving a paramater to $.jStorage.currentBackend('sessionStorage') or to be automatically sessionStorage if no TTL set (or zero).

Or to introduce another option parameter just for this (beside TTL).

Of course that I can setup some TTL for it, but I cannot know if it's enough for user's session / needs or not.

Thanks,

Component.json out of date?

I get this warning when installing through bower:

mismatch The version specified in the component.json of package jStorage mismatches the tag (0.4.1 vs 0.3.2)
mismatch You should report this problem to the package author

Cannot call method 'set' of undefined

Hi,

I have this code:

<script src="http://ajax.googleapis.com/ajax/libs/prototype/1.6.1.0/prototype.js"></script> <script src="jstorage.js"></script>

function selectChecked() {
var selected = new Array();
var chk_arr = document.getElementsByName("checkbox[]");
var chklength = chk_arr.length;
for(k=0;k< chklength;k++)
{
if (chk_arr[k].checked == true)
selected.push(chk_arr[k].value);
}
$.jStorage.set("links", selected);
}
</script>

And have this error:
Cannot call method 'set' of undefined

I even try change selected to "teststring" and I have the same error

Remove XML Support?

I was wondering why XML Support is provided in the library...

You are not providing JSON.stringify, JSON.parse etc inside the library, right? You expect users to make sure that JSON support is present.

Not sure what percentage of users require XML support. I would dare to assume that the percentage is on the low side. Do you have any data on this?

IMHO, XML support should be removed from the library. Users who want to work with XML should be expected to provide endode/decode methods. (Also, if somebody is already working with XML, it can be safely assumed that they already have some methods defined to help with this.)

Even if the bytes saved are not huge, there is no need to support this out-of-the box IMHO. Should be at least moved out to a plugin.

Thoughts?

Native JSON conflicts with MooTools

If jQeury-JSON is not loaded in a browser with native JSON support, jStorage silently fails.

JSON support is checked for MooTools by window.JSON - native JSON uses the same name but has different methods (parse and stringify vs. encode and decode), so the script passes the JSON check but fails actual parsing.

Enable listener for any changed key

With basic localstorage it is possible to listen if any key changes:

if (window.addEventListener) {
  window.addEventListener("storage", handle_storage, false);
} else {
  window.attachEvent("onstorage", handle_storage);
};

..but with jStorage you currently must define a key name that is listened.

$.jStorage.listenKeyChange("mykey", function(key, action){
    console.log(key + " has been " + action);
});

Could you please add the ability to listen for any key change?

E.g.

$.jStorage.listenKeyChange(function(key, action){
    console.log(key + " has been " + action);
});

chrome issues

I've been trying jstorage and it worked great in firefox, but not the latest version of chrome...(running 12.0.742.122). It says "true" when I ask it if storage is available, but doesn't store anything....Any suggestions?

$.jStorage.get(key) returns always null

Can't get the value with public method, but
the internal variable works - $.jStorage._storage[key];

Tested on Firefox 3.6.2 with Prototype and jQuery 1.4.2

enhancement: add third argument to .set()... TTL

Thanks for an amazingly great library. I wish I had found it earlier. I just switched a bunch of cookie based code over to it.

It would be nice to just be able to call .set() with a TTL instead of having to call the ttl method separately. This could be an optional third argument.

Also, I just noticed that the ttl method is missing documentation at the top of the .js file.

cheers.

.set() TTL support

Hey @andris9.

set() method could really use TTL support.

I've seen there is a separate setTTL() method but that's just cumbersome to set a TTL after you've set the value. Many server side caching solutions allow you to define ttl when setting a value. It'd be great to add this.

Here is a proposed syntax:

$.jStorage.set(key, value, TTL);
// @var TTL - (optional) expiration time in seconds, after which the value 
//            is discarded. If omitted or set to 0 the value will never expire.

Search for a string among keys

If you need to search among the keys for a given string you could clone the index-function and modify it:

searchIndex: function(string){
            var index = [], i;
            for(i in _storage){
                if(_storage.hasOwnProperty(i) && i != "__jstorage_meta"){
                    if(i.indexOf(string) !== -1) index.push(i);
                }
            }
            return index;
        }

It will return an array with keys containing the string.

Session Storage

Ist there a way to use jStorage with sessionStorage instead of localStorage? I've seen that there are several type == "session" inside the code, but how can I set the type to sessionStorage?

iOS5 in Private Browsing mode bombs in bad way

in _load_storage the line:
_storage_service.jStorage = "{}";

throws Error: QUOTA_EXCEEDED_ERR: DOM Exception 22

This line could be wrapped in a try catch, but I think it would be better to do this sooner when setting the storage engine so that an alternate mechanism could be used.

Fix JSON support error

Hi,

jQuery has had JSON support baked in since at least 1.4 - could you amend your JS to acknowledge that and not require a duplicate library?

Trivial Feature Request: Batch storage via object

What if there was a quick function to store multiple key/value pairs at once?

$.jStorage.set({key:"value"})

Just a variation for use cases that have perfect key-value storage; this would prevent us from writing a for loop each time. Not that it's that much work but I thought it would be a nice feature to have.

IE7 - Different values stored for same key in different pages

In url (A), I set a value for a key. Example:
$.jStorage.set("key1", "value1");
then
alert($.jStorage.get("key1"));
pops "value1"

In another url (B) the code
alert($.jStorage.get("key1"));
pops null
Then
$.jStorage.set("key1", "value2");
alert($.jStorage.get("key1"));
this pops "value2"

But when access url A, it pops "value1"

It works perfect in Firefox and Chrome (ubuntu 12.04).

When I access with IE, the domain is something like:
http://192.168.10.11:8080
Is there any issue with a different port other than 80?

Using jStorage through different subdomains

Hi, this is more like a question than an issue, I have a site which has different subdomains, and I would like to use the same localStorage data through all of them, is there any options that I must pass to the $.jStorage.set function to make this works?

jstorage.js creates 2 extra buttons when loaded with Internet Exploder 7.0

If jstorage.js (or jstorage.min.js) is included on a web page, it creates 2 extra buttons on the webpage when it is viewed with Internet Exploder 7.0.

It does this because the _createPolyfillStorage(type, forceCreate) function creates a button, which is visible on the web page:

storage = document.createElement("button");

If it is changed to create a hidden input field, then it does not alter the appearance of the web page:

storage = document.createElement("input");
storage.setAttribute("type", "hidden");

cannot handle error with set a big object

if I try to set a big object in jStorage with ie7 I always get an error I cannot handle directly

$.jStorage.flush();

var arr = [];
for (var i=0; i<10000; i+=1)
  arr.push('a');

try {
  $.jStorage.set('a', arr);
}
catch (e) {
  console.error(e);
}

Instead of an error log i see an unhandled js error

example
the line 2120 is in function _publishChange, just between _storage_elm.save("jStorage"); and _storageObserver();

function _publishChange(){
var updateTime = (+new Date()).toString();
if(_backend == "localStorage" || _backend == "globalStorage"){
_storage_service.jStorage_update = updateTime;
}else if(_backend == "userDataBehavior"){
_storage_elm.setAttribute("jStorage_update", updateTime);
_storage_elm.save("jStorage");
}
_storageObserver();
} 

is there a way to handle this?

Zip Download doesn't include a working example

I downloaded the jStorage zip file today but found that the example page doesn't work.

The problem is that jStorage.js file is not located in the example directory.

Possible solutions:

  • Change the script tag to reference the jstorage.js in the parent folder
  • Copy the jstorage.js to the example folder

jStorage will not work on Safari 7 with iframe

Problem:

  1. Open Safari
  2. Make sure "Stop Cookie and other website data" is setting to "From third part and ad", this is the default option for Safari.
  3. Open this: http://jsbin.com/Urotew/1 in two tabs.

found pubsub will not be work.

I'm trying use it to communicate between two pages of different sub-domain.(One display list of songs, another is a Player)

Any solution?

Need to clone objects before storing in storage object

Hi,

First let me thank you for the wonderful little tool you've created, very useful!

I have run into a minor issue, which can be easily fixed (I'm no git user, so I didn't create a pull req for this).

in set:

    set: function(key, value){
        _checkKey(key);
        if(_XMLService.isXML(value)){
            value = {_is_xml:true,xml:_XMLService.encode(value)};
        }
        _storage[key] = value;
        _save();
        return value;
    }

If the value is an object, and it is later changed, the _storage cache will reflect those changes (while the localStorage won't). This is an issue, since the stored object may (and in my application does) acquire non-json-serializable properties (such as jQuery wrapped elements). when ever some other key is changed and the entire _storage object needs to be serialized, things break.

my fix was quite simple, perhaps there's a better way to go about this-

set: function(key, value){
        var clone;
        _checkKey(key);
        if(typeof(value) === 'object'){
            clone = $.extend(true, {}, value);
        }else{
            clone=value;
        }
        if(_XMLService.isXML(clone)){
            clone= {_is_xml:true,xml:_XMLService.encode(clone)};
        }
        _storage[key] = clone;
        _save();
        return clone;
}

Please note that this uses jQuery's extend function explicitly, I have no idea whether this could roll with other libraries. This works fine for me, so I hope it might help others as well.

Thanks again,
o

reInit() use case documentation

It would be great if reInit() function would have extended documentation. Right now it is not clear what its use case is.

For instance, is it necessary to reInit() before every change? or when should it be called?

$.jStorage.flush() does not persist in Safari 4 on iPad simulator (w/jQuery 1.4.2)

Very odd problem, and everything works fine in every other situation I've tested in. Here's what's happening...

  1. Visit page in Safari in iPad simulator.
  2. Save some data via jStorage.
  3. Refresh page in Safari.
  4. Load data via jStorage.
  5. Clear data via jStorage.flush().
  6. Refresh page in Safari.
  7. Load data via jStorage. The saved data returns.

The very, very odd thing is that in between steps 5 and 6, if you attempt to load data from storage you can see that the data was successfully cleared. It seems like the iPad version of Safari requires a little extra magic to fully ditch the data on a flush.

Object does not support this property or method, IE 6 XP SP3

Hi andris9, can you help me about with a issue, I was testing jStorage script on some computers with IE 6 XP SP3, in most of the cases the script works fine but for some reason, in few cases the script throws an exception "Object does not support this property or method" inclusive in the github test case 1. backend(1,0,1) in my script the exception throws it in line 198, I suppose in this lines:

                _storage_elm.setAttribute("jStorage", "{}");
                _storage_elm.save("jStorage");
                _storage_elm.load("jStorage");

But in most of the cases with the same "IE", the script not fail, can you help me about this issue.

I was, testing, with the "Utilu IE Collection", to simulate the "IE 6" ambient

Trouble with null entries

I ran across a bug in my application where by null values were getting stored for keys in the local storage. This revealed what seems to be a bug in jStorage and/or a change in behavior with Safari 5.1 ( Mozilla/5.0 (Macintosh; Intel Mac OS X 10_6_8) AppleWebKit/534.50 (KHTML, like Gecko) Version/5.1 Safari/534.50 ).

Upon attempting to retrieve the null values, the following error is logged to the console:

jstorage.js:288 TypeError: 'null' is not an object (evaluating '_storage[key]._is_xml')

Line 288 is the following:

            if(typeof _storage[key] == "object" && 

If changed to:

            if(typeof _storage[key] == "object" && _storage[key] !== null &&

Seems to have the intended result. I don't know if this is a change in behavior by Safari or something else.

Thank you,
Matt

possible enhancement: count method

Hi, I really appreciate the efforts you've put into this great library. I modified your library to provide a count of keys in the storage object.

/**
* Returns a count of all used keys in index array
* ie. 6
*
* @returns int
*/
count: function(){
var countNum = 0;
var index = [], i;
for(i in _storage){
if(_storage.hasOwnProperty(i)&& i != "_jstorage_meta"){
index.push(i);
}
}
countNum = index.length;
return countNum;
},

I realize I could use $.jStorage.index().length to get the same value, but I recently typed "lenght" into github search and was shocked by all of the typos. Anyway, my line of thought is that explicitly calling a method is never a "bad thing." Take care and thanks again.

Strange Issue using IE6/jQuery

For some intranet app i need IE6 compatibility and tried your plugin with jQuery - if both jquery-json and jStorage scripts are included, IE6 (on Win2K Pro) first tells me that "the page is not available" in a Browser-PopUp and then dies with the standard "page not available" HTML. It's not a JS-Error, it comes from the browser.

I tried the older version DOMCached and am able to use it without problems in IE6.

Thanks for your work!

Fails badly on IE6 w/busted userData

If you install the Utilu IE collection on an XP machine w/IE8 and test jStorage with the included IE6 builds, there is a failure on startup, and operations with jStorage throw an error: "c.__jstorage_meta.CRC32 is null or not an object".

http://utilu.com/IECollection/

I don't know if this is possible to see on a proper install of IE6 on XP, but the jStorage code should probably test whether userData actually works before relying on it. If there is no userData support, it should fall back to a mode with no persistence at all.

_fireSubsribers stops on first error

When one of the subscribers throws unhandled exceptions, none of the subscribers will be called.

Here is a sample:

http://jsfiddle.net/ntgn81/ww9Tw/

I'm not sure if you guys considere this as an issue, but if you do, here is a possible solution:

    function _fireSubscribers(channel, payload){
        if(_pubsub_observers[channel]){
            var errors = [];
            for(var i=0, len = _pubsub_observers[channel].length; i<len; i++){
                // send immutable data that can't be modified by listeners
                try{
                  _pubsub_observers[channel][i](channel, JSON.parse(JSON.stringify(payload)));
                }
                catch(e){
                  // catch errors thrown by subsribers
                  errors.push(e);
                }
            }
            if (errors.length > 0){
              for (var j = 0; j < errors.length; j++){
                // Throw a new error with some nice message that concatenates the errors
              }
            }
        }
    }

Thanks!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.