adrianmay / rhaboo

Persistent JavaScript Objecs

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Expose construct function

Download opened this issue · comments

I hit a roadblock with Rhaboo the other day... When in Private Browsing mode, iOS Safari doesn't do what we would expect (and all other browsers do) and just give us some temp space to work in that is wiped after the session... Instead it throws an error as soon as we try to write to localStorage:

QUOTA_EXCEEDED_ERR: DOM Exception 22: An attempt was made to add something to storage that exceeded the quota.

(see these stackoverflow questions.)

To get around this and still be able to use Rhaboo, I'm detecting whether a usable localStorage exists and if not, falling back to an in-memory implementation. The data gets lost when the user closes the browser, but that's normal in Private Browsing mode I guess...

Here is what I am doing now:

var storage;
try {
    var x = Date.now().toString();
    localStorage.setItem(x, x);
    var y = localStorage.getItem(x); 
    localStorage.removeItem(x);
    if (y !== x) throw new Error();
    storage = localStorage;
} 
catch(e) {
    // Native localStorage not available. Falling back to in-memory implementation. 
    // Data will not be saved across browser sessions but that's normal in Private Browsing mode
    storage = {
        storage: {},
        getItem: function(key) {return this.storage[key];},
        setItem: function(key, val) {this.storage[key] = val;},
        removeItem: function(key) {delete this.storage[key];}
    }
}
var DB = Rhaboo.construct(storage, 'my-app');

The tricky bit is in the last line... I am passing my shim storage object to Rhaboo's construct function. This works well, but I had to modify Rhaboo to be able to do this.

Would you be open to exposing construct so that this scenario can be supported with an 'official' Rhaboo version?

It's a good idea to make an in-memory storage mode like that. I already have localStorage and sessionStorage, so why not add a third one. I'll do that some time, but not this week cos I'm in the middle of relocating by 6000 miles.

LOL you are so fast in responding! Thanks!

So... I already made an implementation of exposing construct (turned out param order of this function was opposite in algorithms sand and rock BTW, so I changed one to match the other). You can see it in the commit that references this issue.

I am willing to put in the work and make this exactly as you think it should be made, so I can get my code into the official Rhaboo instead of having to fork it. :)

I think, maybe the best option is doing both:

  • Implement an in-memory storage solution inside Rhaboo (call it InMemoryStorage maybe)
  • Expose the construct function

Reason behind it is this: Implementing an in-memory storage is really easy and straightforward, so it just makes life simpler for everyone to include it. However there are dozens of ways this can be improved (e.g. sending the data to the server to store it there, piggybacking it in cookies if it's small enough, maybe we can leverage Flash if it's installed and store it there, etc etc etc), so I think exposing construct is a very subtle way of allowing the client code to implement the actual storage any way he wants, possibly through any of the shims that are out there. As long as the object given to construct implements the Storage API, Rhaboo will work fine on it.

(actually, I'm currently implementing only a subset of the API... It seems just having getItem, setItem and removeItem is enough... But maybe you can comment on that?)

So... let me know what you think. I'm hoping I can implement this to your liking so you'd only have to merge it in.

I agree with your logic, and I think you know which way to steer. How about if you just get on with this on your fork and I'll edit my readme to tell people to check out your fork until I get time to integrate. Just do it your way. Even if you do something I didn't expect you'll probably talk me into the sense of it. Thanks for contributing!

Great, that sounds like a plan.

I will work on my fork and once I get something I think will satisfy you and me both, I'll create a Pull Request. Thanks for your support!

And there it is:
#36