
Show HN: Store.js v2.0 – Cross-browser storage for all use cases - marcuswestin
https://github.com/marcuswestin/store.js
======
marcuswestin
Store.js was originally released on HN in 2010 :)
[https://news.ycombinator.com/item?id=1468802](https://news.ycombinator.com/item?id=1468802)

It's live on tens of thousands of websites (like cnn.com!) and has seen lots
of improvements over the years.

Store.js version 2 is a full revamp with pluggable storage (it will
automatically fall back to one that works in every scenario by default),
pluggable extra functionality (like expiration, default values, common
array/object operations, etc), and fully cross-browser automatic testing using
saucelabs.com.

Feel free to ask any questions! I'm going to sleep now, but I'll make sure to
answer in the AM.

Cheers!

~~~
EdSharkey
Hey Marcus, I'm a user! Thanks for doing the heavy IE lifting in store.js.

Anyhow, I had a requirement to store raw strings to the local storage or
userdata rather than go through your calls to JSON.parse/stringify. I forked
and am using my fork rather than your maintained version, which is sad. Since
you've got the hood popped for maintenance, would you mind adding raw string
support to store.js in version 2? Thanks in advance. Here's my fork repo for
reference, please see the getRawString and setRawString API's I added:

[https://github.com/woldie/store.js](https://github.com/woldie/store.js)

~~~
greggman
Genuinely curious but why is this important? Assuming the current API only
takes an object can't you just provide 2 functions

    
    
        function putString(id, s) {
           storePutAPI(id, {s:s});
        }
        function getString(id) {
           var o = storeGetAPI(id);
           return o ? o.s : undefined;
         }
    

Note I have never used the API nor looked at the docs but assuming you can
store objects why the need for special functions?

On top of which AFAIK JSON.stringify and JSON.parse work with plain strings so
I'd be curious what prevents using plain strings in store.js without any
changes

Sorry this isn't a put down , just trying to understand

~~~
EdSharkey
Not at all at all, I understand your confusion. Mine is definitely a niche
case, perhaps straying a bit into the eclectic.

I have put together a virtual file system for a programming environment for
kids that is built atop the local storage/userdata API's.

I support legacy IE back to IE6 as well as modern browsers, and I wanted to
maximize my very limited allowed storage space on legacy IE.

Also, I needed to have some certainty around how much free space is remaining
in the file system. My design was to organize the underlying storage into 4K
blocks that were pre-allocated when the system first starts; whatever the host
system could give me in terms of space I would take.

JSON is nice for the general case, but the way it escapes some characters
makes computing the free space I have remaining unpredictable as new files get
written.

Of course, I can do my own encoding of bytes into unicode char codes and write
those as raw strings using store.js. JavaScript strings are saved as 16-bit
unsigned arrays if you unfocus your eyes and stare at the screen for awhile,
and I use as many bits as I am able in my scheme.

So, I rigged up a byte-to-string encoder/decoder that was universally accepted
on IE and modern browsers, and calling through to my getRawString/setRawString
API, I just about doubled my storage over the default JSON.stringify/parse!

Suprisingly, performance isn't bad with my encoded strings either. That said,
my compy has a retro flair, and I don't think my users will mind much that
they have to wait a second or two to load their games from disk. Perhaps even
adds a bit of authenticity. :)

~~~
marcuswestin
Bonus points for best use case on the page :)))

Eclectic as it is, I think we should totally consider making it a
plugin/storage! If you open an issue with links to the relevant material I'd
really appreciate that. Thanks!

------
vanderZwan
Since I assume both have their pros and cons, when would I want to use
Store.js, and when would I want to use localForage[0]? I'm asking as someone
who has offline storage _planned_ for an app, but has yet to get around to it.
I'd like to know which one is probably best for my needs :)

[0]
[https://github.com/localForage/localForage](https://github.com/localForage/localForage)

~~~
hackerboos
Personally, I wouldn't use a library at all unless I had to support IE<8\.
Localstorage is supported enough across browsers:

[http://caniuse.com/#feat=namevalue-
storage](http://caniuse.com/#feat=namevalue-storage)

~~~
vanderZwan
Well, I need more than 5 MB and would like to store other values than strings
(mostly large TypedArrays). Something simplifying my life there would be
appreciated.

~~~
hackerboos
JSON.stringify/JSON.parse before getting/setting from localstorage.

The other requirements localstorage alone can't address.

------
nodesocket
I just upgraded code in my app ([https://commando.io](https://commando.io))
that stores some user preferences from $.cookie (jQuery Cookie) to Store.js.
Worked flawlessly.

As a bonus of switching from cookies to local storage, now requests don't send
along those values anymore to the server.

------
onion2k
This looks really good. I've been using PouchDB for doing something similar,
but if I didn't need the fancy sync'ing I'd be all over this.

~~~
k__
I use LocalForage if I need simpler solutions than PouchDB.

------
dgut
Thanks for the work you've put into Store.js.

~~~
marcuswestin
Thank you :)

------
homakov
localStorage is pretty much only thing we need these days.

~~~
marcuswestin
Almost! Except if you want to store objects/arrays/numbers (localStorage only
supports strings), or want your site to work in Safari Private mode (where
localStorage breaks), or if you have to support legacy environments with old
browsers (like many government services), etc etc etc :)

~~~
diggan
Not that I disagree with your other arguments but this one sticks out:

> Except if you want to store objects/arrays/numbers (localStorage only
> supports strings)

My normal usage of localStorage usually looks like this:

    
    
        const getItem = (item) => { JSON.parse(window.localStorage.getItem(item)) }
        // and
        const setItem = (item, val) { window.localStorage.setItem(item, JSON.stringify(val)) }
    

And then you won't have issues with any type.

~~~
marcuswestin
Except when a value has already been stored previously without JSON.stringify
(in which case JSON.parse will throw), or you need a default value if unset
(e.g `store.get('username', 'anonymous')`, or ... :) But I also see your point
that sometimes the very quick and simple solution can be useful!

------
jazoom
I've found great value in simpleStorage, for those who are looking for easier
object storage in localStorage.

~~~
marcuswestin
Yes, simpleStorage is good too!

I believe store.js addresses all the use cases of simpleStorage, and then some
(E.g Safari private mode, etc).

If that's not the case I will make it work for your use case :)

~~~
jazoom
The only problem I've noticed with simpleStorage is the Safari private mode
thing, but I see that as a bug in Safari so I just show a message to users
telling them why the site won't work properly for them.

------
fareesh
Does anyone have an angular2 version of this? Could really use it on something
I'm currently working on

~~~
marcuswestin
Hey, I'm not sure what an angular2 version would look like or do. Could you
please open an issue with a more detailed description of what you need? I'll
help if I can!

Cheers

