Skip to content

Commit

Permalink
Merge branch 'development' of github.com:smithki/storage-proxy into d…
Browse files Browse the repository at this point in the history
…evelopment
  • Loading branch information
smithki committed May 14, 2019
2 parents ef1f5bd + be04300 commit b43ee61
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 14 deletions.
25 changes: 20 additions & 5 deletions src/lib.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ function getDataFromStorage(namespace: string, storageTarget: StorageTarget) {
function createProxy<TStorageDefinitions extends any>(
storageTarget: StorageTarget,
namespace: string,
defaults?: Partial<TStorageDefinitions>,
): StorageProxy<TStorageDefinitions> {
if (!namespace) throw new Error('[storage-proxy] Namespace cannot be an empty `string`, `undefined`, or `null`.');

Expand All @@ -77,12 +78,20 @@ function createProxy<TStorageDefinitions extends any>(
window[storageTarget].setItem(namespace, JSON.stringify(proxyData));
});

return new Proxy(proxyData, {
const storageProxy = new Proxy(proxyData, {
get: (target, prop, receiver) => {
if (typeof proxyData[prop as any] === 'undefined') return null;
return proxyData[prop as any];
},
});

if (defaults) {
for (const [key, value] of Object.entries(defaults)) {
storageProxy[key] = value;
}
}

return storageProxy;
}

// --- Proxy factory -------------------------------------------------------- //
Expand All @@ -99,8 +108,11 @@ export const StorageProxy = {
*
* @return a `StorageProxy` object targeting `localStorage`.
*/
createLocalStorage<TStorageDefinitions extends any>(namespace: string): StorageProxy<TStorageDefinitions> {
return createProxy<TStorageDefinitions>(StorageTarget.Local, namespace);
createLocalStorage<TStorageDefinitions extends any>(
namespace: string,
defaults?: Partial<TStorageDefinitions>,
): StorageProxy<TStorageDefinitions> {
return createProxy<TStorageDefinitions>(StorageTarget.Local, namespace, defaults);
},

/**
Expand All @@ -110,8 +122,11 @@ export const StorageProxy = {
*
* @return a `StorageProxy` object targeting `sessionStorage`.
*/
createSessionStorage<TStorageDefinitions extends any>(namespace: string): StorageProxy<TStorageDefinitions> {
return createProxy<TStorageDefinitions>(StorageTarget.Session, namespace);
createSessionStorage<TStorageDefinitions extends any>(
namespace: string,
defaults?: Partial<TStorageDefinitions>,
): StorageProxy<TStorageDefinitions> {
return createProxy<TStorageDefinitions>(StorageTarget.Session, namespace, defaults);
},

/**
Expand Down
33 changes: 24 additions & 9 deletions test/src/storage-proxy.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ interface TestStorage {
bar: string;
baz: typeof testObj;
fizz: number;
defaults: {
example: string;
};
}

function getItem(storageTarget: StorageTarget, path: string) {
Expand Down Expand Up @@ -45,32 +48,44 @@ export class StorageProxyTestFixture {
localStorage.setItem(testNamespace, JSON.stringify({ bar: testStr, test: 999, baz: testObj }));
sessionStorage.setItem(testNamespace, JSON.stringify({ bar: testStr, test: 999, baz: testObj }));

this.lStore = StorageProxy.createLocalStorage<TestStorage>(testNamespace);
this.lStore = StorageProxy.createLocalStorage<TestStorage>(testNamespace, {
defaults: { example: testStr },
});
this.sStore = StorageProxy.createSessionStorage<TestStorage>(testNamespace);
}

@Test('Set a namespaced `localStorage` key')
public setNamespacedLocalStorageKeyTest() {
@Test('Sets default items in storage')
public defaultsMergeTest() {
Expect(getItem(StorageTarget.Local, 'defaults.example')).toEqual(testStr);
}

@Test('Defaults are available on the `StorageProxy` object')
public defaultsAreGettableTest() {
Expect(this.lStore.defaults!.example).toEqual(testStr);
}

@Test('Set a `localStorage` key')
public setLocalStorageKeyTest() {
this.lStore.fizz = 123;

Expect(getItem(StorageTarget.Local, 'fizz')).toEqual(123);
}

@Test('Set a namespaced `sessionStorage` key')
public setNamespacedSessionStorageKeyTest() {
@Test('Set a `sessionStorage` key')
public setSessionStorageKeyTest() {
this.sStore.fizz = 123;

Expect(getItem(StorageTarget.Session, 'fizz')).toEqual(123);
}

@Test('Get namespaced `localStorage` key')
public getNamespacedLocalStorageKeyTest() {
@Test('Get `localStorage` key')
public getLocalStorageKeyTest() {
const data = this.lStore.bar;
Expect(data).toEqual(testStr);
}

@Test('Get namespaced `sessionStorage` key')
public getNamespacedSessionStorageKeyTest() {
@Test('Get `sessionStorage` key')
public getSessionStorageKeyTest() {
const data = this.sStore.bar;
Expect(data).toEqual(testStr);
}
Expand Down

0 comments on commit b43ee61

Please sign in to comment.