Research
Security News
Malicious npm Packages Inject SSH Backdoors via Typosquatted Libraries
Socket’s threat research team has detected six malicious npm packages typosquatting popular libraries to insert SSH backdoors.
One-stop shop for Web Storage API compliant persistence. Project website
WebStore builds on top of MemoryStorage,
adding persistence to it in the form of load
and save
methods.
For now loading and saving is explicit, so you will be able to fully control when it happens.
I am thinking of some autoPersist
option (maybe together with a strategy, or some settings)
to have WebStore handle it for you, but that functionality is not there yet.
WebStore was built for performance. As it basically performs all operations in-memory, the overhead
of using it should be near zero as long as you don't save or load. When you do save or load, localStorage
is used so you will get the normal performance associated with such I/O.
Having the data actually survive page reloads and browser sessions is a secondary concern. Users can wipe their browser caches and use private browsing modes, so we need to consider the option of the data being gone anyway. I recommend storing the data on the server by means of an Ajax call if it is really important and only using local storage as a glorified cache.
Currently, WebStore does not handle synchronization of data between multiple tabs. This means you should either limit your use to single-page-apps, use isolated stores for different pages, or come up with some synchronization system yourself.
webstore
can be used directly from CDN, or from a local script file.
<script src="https://cdn.rawgit.com/download/webstore/0.9.0/dist/webstore.min.js"></script>
Download webstore.min.js, place it in a folder lib
in the root of your website and include it like this:
<script src="/lib/webstore.min.js"></script>
npm install webstore
The WebStore
function creates (or returns) a storage object implementing the W3C Web Storage API.
By default, scripts share a global
storage object, so scripts can access and mutate each other's store
object. To have WebStore create a storage object that is isolated from other scripts, you pass in
a unique ID which acts as a namespace:
var isolated = new WebStore('my-app'); // isolated from other scripts, recommended.
If you don't pass in an ID, or use the ID 'global'
, you get a globally shared storage object:
var global = new WebStore(); // will default to a globally shared storage object.
var global2 = new WebStore('global'); // effectively same as above
For your convenience, the constructor permits new
-less invocation:
var store = WebStore('my-store');
var global = WebStore();
Instances of WebStore
expose an immutable id
property that is set to
the id the store was created with:
alert(store.id); // alerts 'my-store'
alert(global.id); // alerts 'global'
WebStore builds on top of MemoryStorage.
As such, all operations are performed in local memory and super-fast. But it also
means that we have to make sure our changes are loaded before we start, and saved
once we are done. I'm thinking about and experimenting with mechanisms to take care
of this for you, but for now you will explicitly have to call the load
method yourself.
var store = new WebStore('my-store');
store.load();
Once you have loaded the store, you can use it just as you would localStorage
or any other store implementing Web Storage:
store.setItem('myString', 'Hello WebStore!');
store.myObject = JSON.stringify({my: 'object'}));
alert(store.getItem('My string')); // alerts 'Hello MemoryStorage!'
alert(store['My string']); // alerts 'Hello MemoryStorage!'
alert(store.length); // alerts '2'
alert(store.key(1)); // alerts 'My object'
store.removeItem('My string');
alert(store.length); // alerts '1'
store.clear();
alert(store.length); // alerts '0'
When you are done writing to the store, call save
to persist the data to localStorage
:
store.save();
If you don't mind some risk of losing the data, you could bind the load
and save
methods
to the load
, beforeunload
, pageshow
and pagehide
events. Note that WebKit will often
fire both pagehide
and beforeunload
, but not always. Currently I feel the best strategy would
be to bind to all events and just make sure we don't run save twice ourselves.
WebStore is type-agnostic; it doesn't care about the type of data you store. If you want to remain within the Web Storage API, you should only read and write strings, however if you want you can store other types just as well.
store.myNumber = 17;
alert(store.myNumber + 3); // alerts '20' (not '173')
store.myDate = new Date();
store.myObject = {my: 'object'};
alert(store.myObject.my); // alerts 'object'
var tree = {
nested: {
objects: {
working: 'Sure!'
}
}
}
store.setItem('tree', tree);
alert(store.tree.nested.objects.working); // alerts 'Sure!'
WebStore even handles custom types:
// A custom type
function Greeter(name) {
this.name = name;
this.greet = function Greeter_greet() {
return 'Hello, ' + this.name + '!';
};
};
// Add to the store and save
var store = new WebStore('local');
store.customData = new Greeter('WebStore');
store.save();
// Later on... possibly in a new browsing session
var store - new WebStore('local');
store.load();
alert(store.customData.greet()); // alerts 'Hello, WebStore!'
When saved, WebStore serializes it's data to JSON and saves it in localStorage.
Some extra data is added to allow WebStore to find out what the name was of the
constructor used to create the object to be stored (class name in Java-speak).
When the data is deserialized, WebStore uses JSON.parse with a custom reviver
function, which can be found on the store config:
store.config.reviver; // --> function basicReviver(key, value)
To restore the original type, WebStore will try to get the constructor from the window object using its name. If your types are not available on the window object, there are two thing you can do:
constructors
object on the basic reviverSimply add your constructor function to the constructors
property on the basic
reviver, keyed by name:
function MyPrivateConstructor() {
// do secret stuff here
}
store.config.reviver.constructors.MyPrivateConstructor = MyPrivateConstructor;
Writing a good JSON reviver is not easy and out of scope for these docs, but once you have one, telling WebStore to use your reviver instead of the basic reviver is a one-liner:
var Store = new WebStore('my-store', {reviver: mySpiffyReviver});
If you need access to the old reviver, you can pick it up after creating the store and then assign your new reviver:
var Store = new WebStore('my-store');
var oldReviver = store.config.reviver; // Save the old reviver...
store.config.reviver = mySpiffyReviver; // Assign your new reviver
Make sure you don't save data with one reviver and then attempt to load it with another. It won't work.
WebStore adds a property named __w3cx_ctor__
to the serialized JSON of objects
that have a custom type, so it's basic reviver knows how to restore them. If you
want to customize what the JSON looks like, you can do so by implementing a toJSON
method on your objects, and a fromJSON
method on your constructor.
Copyright 2015 by Stijn de Witt. Some rights reserved.
Licensed under the Creative Commons Attribution 4.0 International (CC-BY-4.0) Open Source license.
FAQs
One stop shop for Web Storage API compliant persistence.
The npm package webstore receives a total of 3 weekly downloads. As such, webstore popularity was classified as not popular.
We found that webstore demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Research
Security News
Socket’s threat research team has detected six malicious npm packages typosquatting popular libraries to insert SSH backdoors.
Security News
MITRE's 2024 CWE Top 25 highlights critical software vulnerabilities like XSS, SQL Injection, and CSRF, reflecting shifts due to a refined ranking methodology.
Security News
In this segment of the Risky Business podcast, Feross Aboukhadijeh and Patrick Gray discuss the challenges of tracking malware discovered in open source softare.