Skip to content

Commit

Permalink
refactor: modified and simplified storages
Browse files Browse the repository at this point in the history
  • Loading branch information
arthurfiorette committed Jan 2, 2022
1 parent 53c4d41 commit bafe1de
Show file tree
Hide file tree
Showing 16 changed files with 141 additions and 195 deletions.
3 changes: 1 addition & 2 deletions src/cache/cache.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@ import type { Method } from 'axios';
import type { Deferred } from 'fast-defer';
import type { HeadersInterpreter } from '../header/types';
import type { AxiosInterceptor } from '../interceptors/types';
import type { AxiosStorage } from '../storage/storage';
import type { CachedResponse } from '../storage/types';
import type { AxiosStorage, CachedResponse } from '../storage/types';
import type { CachePredicate, KeyGenerator } from '../util/types';
import type { CacheUpdater } from '../util/update-cache';
import type { CacheAxiosResponse, CacheRequestConfig } from './axios';
Expand Down
4 changes: 2 additions & 2 deletions src/cache/create.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import type { AxiosInstance } from 'axios';
import { defaultHeaderInterpreter } from '../header/interpreter';
import { CacheRequestInterceptor } from '../interceptors/request';
import { CacheResponseInterceptor } from '../interceptors/response';
import { MemoryAxiosStorage } from '../storage/memory';
import { buildMemoryStorage } from '../storage/memory';
import { defaultKeyGenerator } from '../util/key-generator';
import type { AxiosCacheInstance } from './axios';
import type { CacheInstance, CacheProperties } from './cache';
Expand Down Expand Up @@ -61,7 +61,7 @@ export function setupCache(
): AxiosCacheInstance {
const axiosCache = axios as AxiosCacheInstance;

axiosCache.storage = storage || new MemoryAxiosStorage();
axiosCache.storage = storage || buildMemoryStorage();
axiosCache.generateKey = generateKey || defaultKeyGenerator;
axiosCache.waiting = waiting || {};
axiosCache.headerInterpreter = headerInterpreter || defaultHeaderInterpreter;
Expand Down
6 changes: 3 additions & 3 deletions src/index.browser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,6 @@ export {
setupCache,
useCache
} from './cache/create';
export { BrowserAxiosStorage } from './storage/browser';
export { MemoryAxiosStorage } from './storage/memory';
export { AxiosStorage } from './storage/storage';
export { buildStorage } from './storage/build';
export { buildMemoryStorage } from './storage/memory';
export { buildWebStorage } from './storage/web-api';
6 changes: 3 additions & 3 deletions src/index.development.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ export {
setupCache,
useCache
} from './cache/create';
export { BrowserAxiosStorage } from './storage/browser';
export { MemoryAxiosStorage } from './storage/memory';
export { AxiosStorage } from './storage/storage';
export { buildStorage } from './storage/build';
export { buildMemoryStorage } from './storage/memory';
export { buildWebStorage } from './storage/web-api';

console.warn(
'You are using a development build. Make sure to use the correct build in production\nhttps://github.com/arthurfiorette/axios-cache-interceptor#installing'
Expand Down
2 changes: 1 addition & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@ export * from './cache/cache';
export * from './cache/create';
export * from './header/types';
export * from './interceptors/types';
export * from './storage/storage';
export * from './storage/build';
export * from './storage/types';
export * from './util/types';
31 changes: 0 additions & 31 deletions src/storage/browser.ts

This file was deleted.

48 changes: 48 additions & 0 deletions src/storage/build.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import { Header } from '../util/headers';
import type { AxiosStorage, StaleStorageValue } from './types';

export function buildStorage({
set,
find,
remove
}: Omit<AxiosStorage, 'get'>): AxiosStorage {
return {
set,
find,
remove,
get: async (key) => {
const value = await find(key);

if (!value) {
return { state: 'empty' };
}

if (
value.state !== 'cached' ||
// Not cached or fresh value
value.createdAt + value.ttl > Date.now()
) {
return value;
}

if (
value.data.headers &&
(Header.ETag in value.data.headers ||
Header.LastModified in value.data.headers ||
Header.XAxiosCacheEtag in value.data.headers ||
Header.XAxiosCacheLastModified in value.data.headers)
) {
const stale: StaleStorageValue = {
data: value.data,
state: 'stale',
createdAt: value.createdAt
};
await set(key, stale);
return stale;
}

await remove(key);
return { state: 'empty' };
}
};
}
28 changes: 9 additions & 19 deletions src/storage/memory.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,10 @@
import { AxiosStorage } from './storage';
import type { NotEmptyStorageValue, StorageValue } from './types';

export class MemoryAxiosStorage extends AxiosStorage {
constructor(readonly storage: Record<string, StorageValue> = {}) {
super();
}

readonly find = async (key: string): Promise<StorageValue> => {
return this.storage[key] || { state: 'empty' };
};

readonly set = async (key: string, value: NotEmptyStorageValue): Promise<void> => {
this.storage[key] = value;
};

readonly remove = async (key: string): Promise<void> => {
delete this.storage[key];
};
import { buildStorage } from './build';
import type { StorageValue } from './types';

export function buildMemoryStorage(obj: Record<string, StorageValue> = {}) {
return buildStorage({
find: (key) => Promise.resolve(obj[key]),
set: (key, value) => Promise.resolve(void (obj[key] = value)),
remove: (key) => Promise.resolve(void delete obj[key])
});
}
61 changes: 0 additions & 61 deletions src/storage/storage.ts

This file was deleted.

41 changes: 41 additions & 0 deletions src/storage/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,3 +50,44 @@ export type EmptyStorageValue = {
createdAt?: undefined;
state: 'empty';
};

/**
* A storage implementation that stores data in memory.
*
* **You can create yours with {@link buildStorage} function**
*
* @example
* ```js
* const myStorage = buildStorage({
* find: myFindFunction,
* set: mySetFunction,
* remove: myRemoveFunction,
* })
*
* const axios = setupCache(axios, { storage: myStorage })
* ```
*/
export type AxiosStorage = {
/**
* Returns the value for the given key. This method does not have to make checks for cache invalidation or etc. It just return what was previous saved, if present.
*/
find: (key: string) => Promise<StorageValue | undefined>;

/**
* Sets a new value for the given key
*
* Use CacheStorage.remove(key) to define a key to 'empty' state.
*/
set: (key: string, value: NotEmptyStorageValue) => Promise<void>;

/**
* Removes the value for the given key
*/
remove: (key: string) => Promise<void>;

/**
* Returns the value for the given key. This method make checks for cache invalidation or etc.
*
*/
get: (key: string) => Promise<StorageValue>;
};
26 changes: 26 additions & 0 deletions src/storage/web-api.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { buildStorage } from './build';

/**
* @example
* ```js
* const fromLocalStorage = buildWebStorage(localStorage);
*
* const fromSessionStorage = buildWebStorage(sessionStorage);
*
* const myStorage = new Storage();
* const fromMyStorage = buildWebStorage(myStorage);
* ```
*/
export function buildWebStorage(storage: Storage, prefix = '') {
return buildStorage({
find: (key: string) => {
const json = storage.getItem(prefix + key);
return Promise.resolve(json ? JSON.parse(json) : undefined);
},

set: (key: string, value: any) =>
Promise.resolve(void storage.setItem(prefix + key, JSON.stringify(value))),

remove: (key: string) => Promise.resolve(void storage.removeItem(prefix + key))
});
}
2 changes: 1 addition & 1 deletion src/util/update-cache.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { AxiosStorage } from '../storage/storage';
import type {
AxiosStorage,
CachedStorageValue,
LoadingStorageValue,
StorageValue
Expand Down
4 changes: 2 additions & 2 deletions test/storage/common.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { MemoryAxiosStorage } from '../../src/storage/memory';
import { buildMemoryStorage } from '../../src/storage/memory';
import { testStorage } from './storages';

describe('tests common storages', () => {
testStorage('memory', () => new MemoryAxiosStorage());
testStorage('memory', () => buildMemoryStorage());
});
2 changes: 1 addition & 1 deletion test/storage/storages.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { AxiosStorage } from '../../src/storage/storage';
import type { AxiosStorage } from '../../src/storage/types';
import { EMPTY_RESPONSE } from '../utils';

export function testStorage(name: string, Storage: () => AxiosStorage): void {
Expand Down
66 changes: 0 additions & 66 deletions test/storage/util.test.ts

This file was deleted.

0 comments on commit bafe1de

Please sign in to comment.