javascriptes6-classproxy-pattern

How to write a proper ES6 wrapper for something like sessionStorage


Hello I am wondering how to write a proper wrapper for something like sessionStorage.

I could implement a class of my own and proxy through method invocation to the sessionStorage. For example with some quick pseudocode:

class customStorage {
    set(key, value) {
        sessionStorage.setItem(key, value);
    }
}

I would use it like so:

const customStorage = new customStorage();
customStorage.set('my-key', 'hello there');

All fine and dandy but I would like for a user to have the freedom to use other native sessionStorage methods on my proxy that I might not implement myself in my proxy.

for something like sessionStorage it would be do-able to write them all yourself even though all they might do is proxy through to sessionStorage without any intervention.

For something larger where I would only manipulate 5 methods out of 20 or something this does not seem viable.

Overwriting native functionality with prototype also seems like a deathtrap leading to many wtfs-per-minute.

So far what I have read from 'proxy patterns' in Javascript they all implemented all of the methods from the original Object. Am I forced to do this?

Is there some sort of way to create an ES6 class and set the prototype of that very class to sessionStorage in the constructor or something?


Solution

  • I would like for a user to have the freedom to use other native sessionStorage methods on my proxy that I might not implement myself in my proxy.

    I would rather give the user the freedom to just use the native sessionStorage directly if he intends to do that. Your implementation does have its own, separate functionality, which does use sessionStorage internally but is not the sessionStorage. There's no reason to implement its interface on your object. (See also composition over inheritance).

    Is there some sort of way to create an ES6 class and set the prototype of that very class to sessionStorage in the constructor or something?

    No. Even when you want to implement that interface, your objects are not really SessionStorage instances. Also in this particular case, sessionStorage is a singleton and you cannot instantiate a second SessionStorage, so inheritance does absolutely not work here.

    There are three ways around this (I'll write code for the generic case with instantiation from arbitrary objects to be wrapped, you likely want a static singleton-like one for your custom storage):