Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[v2] Web Storage #216

Merged
merged 13 commits into from
Oct 20, 2019
Merged
Show file tree
Hide file tree
Changes from 11 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions base.tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"compilerOptions": {
"target": "ES2017",
"module": "commonjs",
"lib": ["es2017"],
"noEmit": true,
"strict": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": true,
"moduleResolution": "node",
"esModuleInterop": true
}
}
30 changes: 17 additions & 13 deletions jest.config.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,20 @@
const commonSettings = {
globals: {
__DEV__: true,
},
};
function createPackageConfig(packageName) {
return {
transform: {
'^.+\\.tsx?$': 'ts-jest',
},
globals: {
__DEV__: true,
'ts-jest': {
tsConfig: `<rootDir>/packages/${packageName}/tsconfig.json`,
},
},
displayName: packageName,
roots: [`<rootDir>/packages/${packageName}`],
testMatch: [`<rootDir>/packages/${packageName}/__tests__/*{.,-}test.ts`],
};
}

module.exports = {
projects: [
{
...commonSettings,
displayName: 'core',
roots: ['<rootDir>/packages/core'],
testMatch: ['<rootDir>/packages/core/__tests__/*{.,-}test.ts'],
},
],
projects: [createPackageConfig('core'), createPackageConfig('storage-web')],
};
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
"clean": "lerna run clean",
"test": "yarn test:lint && yarn test:unit && yarn test:types",
"test:lint": "eslint packages/**/src/*.ts",
"test:types": "tsc --noEmit --declaration false -emitDeclarationOnly false",
"test:types": "lerna run test:types",
"test:unit": "jest"
},
"devDependencies": {
Expand All @@ -41,6 +41,7 @@
"eslint": "5.16.0",
"jest": "24.8.0",
"lerna": "3.15.0",
"ts-jest": "24.1.0",
"typescript": "3.5.2"
},
"keywords": [
Expand Down
6 changes: 4 additions & 2 deletions packages/core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@
"scripts": {
"build": "babel src --root-mode upward --out-dir build/ --extensions .ts --ignore build/**/* --ignore types/* --source-maps inline",
"clean": "rm build -rf",
"start": "yarn build:lib --watch",
"prepublish": "yarn clean && yarn build"
"start": "yarn build --watch",
"prepublish": "yarn clean && yarn build",
"test:types": "tsc",
"test:lint": "eslint ./**/*.ts"
}
}
11 changes: 11 additions & 0 deletions packages/core/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"extends": "../../base.tsconfig",
"include": [
"./src",
"__tests__",
"./types"
],
"exclude": [
"node_modules"
]
}
7 changes: 4 additions & 3 deletions packages/storage-legacy/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,12 @@
"scripts": {
"build": "babel src --root-mode upward --out-dir build/ --extensions .ts --ignore build/**/* --ignore types/**/* --source-maps inline",
"clean": "rm build -rf",
"generate:types": "tsc src/index.ts --noEmit false --lib es2015 --declarationDir types/ -d true -emitDeclarationOnly true",
"prepublish": "yarn clean && yarn build"
"prepublish": "yarn clean && yarn build",
"test:types": "tsc",
"test:lint": "eslint ./**/*.ts"
},
"dependencies": {
"@react-native-community/async-storage": "^2.0"
"@react-native-community/async-storage": "^2.0.0"
},
"peerDependencies": {
"react": "^16.0",
Expand Down
11 changes: 11 additions & 0 deletions packages/storage-legacy/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"extends": "../../base.tsconfig",
"include": [
"./src",
"__tests__",
"./types"
],
"exclude": [
"node_modules"
]
}
2 changes: 1 addition & 1 deletion packages/storage-web/.npmignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Legacy storage backend
# Web storage backend
node_modules
yarn.lock
# see https://github.com/yarnpkg/yarn/issues/7540
Expand Down
69 changes: 69 additions & 0 deletions packages/storage-web/__tests__/index.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import WebStorage from '../src';
import 'jest-localstorage-mock';

describe.each([['sessionStorage', false], ['localStorage', true]])(
'WebStorage using %s',
(storageName, storageBool) => {
const webStorage = new WebStorage(storageBool);
const storage: any = storageBool
? window.sessionStorage
: window.localStorage;

beforeEach(() => {
storage.clear();
});
describe(`main API with ${storageName}`, () => {
it(`gets single item from ${storage}`, async () => {
storage.setItem('key1', 'value1');
expect(await webStorage.getSingle('key1')).toBe('value1');
});

it(`saves single item to ${storageName}`, async () => {
await webStorage.setSingle('key1', 'value1');
expect(storage.__STORE__.key1).toBe('value1');
});

it(`gets multiple items from ${storageName}`, async () => {
storage.setItem('key1', 'value1');
storage.setItem('key2', 'value2');
expect(await webStorage.getMany(['key1', 'key2'])).toEqual([
'value1',
'value2',
]);
});

it(`saves multiple items to ${storageName}`, async () => {
await webStorage.setMany([{key1: 'value1'}, {key2: 'value2'}]);
expect(storage.__STORE__).toEqual({key1: 'value1', key2: 'value2'});
});

it(`removes single item from ${storageName}`, async () => {
storage.setItem('key1', 'value1');
storage.setItem('key2', 'value2');
await webStorage.removeSingle('key1');
expect(storage.__STORE__).toEqual({key2: 'value2'});
});

it(`removes multiple items from ${storageName}`, async () => {
storage.setItem('key1', 'value1');
storage.setItem('key2', 'value2');
storage.setItem('key3', 'value3');
await webStorage.removeMany(['key1', 'key2']);
expect(storage.__STORE__).toEqual({key3: 'value3'});
});

it(`gets keys from ${storageName}`, async () => {
storage.setItem('key1', 'value1');
storage.setItem('key2', 'value2');
expect(await webStorage.getKeys()).toEqual(['key1', 'key2']);
});

it(`removes all keys from ${storageName}`, async () => {
storage.setItem('key1', 'value1');
storage.setItem('key2', 'value2');
await webStorage.dropStorage();
expect(storage.__STORE__).toEqual({});
});
});
},
);
5 changes: 3 additions & 2 deletions packages/storage-web/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@
"scripts": {
"build": "babel src --root-mode upward --out-dir build/ --extensions .ts --ignore build/**/* --ignore types/**/* --source-maps inline",
"clean": "rm build -rf",
"generate:types": "tsc src/index.ts --noEmit false --lib es2015 --declarationDir types/ -d true -emitDeclarationOnly true",
"prepublish": "yarn clean && yarn build"
"prepublish": "yarn clean && yarn build",
"test:types": "tsc"
},
"dependencies": {
"@react-native-community/async-storage": "^2.0"
Expand All @@ -19,6 +19,7 @@
"react-native": ">=0.58"
},
"devDependencies": {
"jest-localstorage-mock": "^2.4.0",
"react": "^16.0",
"react-native": ">=0.58"
}
Expand Down
91 changes: 91 additions & 0 deletions packages/storage-web/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,94 @@
* LICENSE file in the root directory of this source tree.
*
*/
import {
IStorageBackend,
EmptyStorageModel,
StorageOptions,
} from '@react-native-community/async-storage';

class WebStorage<T extends EmptyStorageModel = EmptyStorageModel>
implements IStorageBackend<T> {
storage: any;
constructor(sessionStorage: boolean | string = false) {
this.storage = sessionStorage ? window.sessionStorage : window.localStorage;
}

async getSingle<K extends keyof T>(
key: K,
opts?: StorageOptions,
): Promise<T[K] | null> {
if (opts) {
// noop
}
return this.storage.getItem(key);
}

async setSingle<K extends keyof T>(
key: K,
value: T[K],
opts?: StorageOptions,
): Promise<void> {
if (opts) {
// noop
}
return this.storage.setItem(key, value);
}

async getMany<K extends keyof T>(
keys: Array<K>,
opts?: StorageOptions,
): Promise<{[k in K]: T[k] | null}> {
if (opts) {
// noop
}
return Promise.all(keys.map(k => this.storage.getItem(k)));
krizzu marked this conversation as resolved.
Show resolved Hide resolved
JesseRWeigel marked this conversation as resolved.
Show resolved Hide resolved
}

async setMany<K extends keyof T>(
values: Array<Partial<{[k in K]: T[k]}>>,
opts?: StorageOptions,
): Promise<void> {
if (opts) {
// noop
}
for (let keyValue of values) {
const key = Object.getOwnPropertyNames(keyValue)[0];
JesseRWeigel marked this conversation as resolved.
Show resolved Hide resolved
if (!key) {
continue;
}
this.storage.setItem(key, keyValue[key]);
}
}

async removeSingle(key: keyof T, opts?: StorageOptions): Promise<void> {
if (opts) {
// noop
}
return this.storage.removeItem(key);
}

async removeMany(keys: Array<keyof T>, opts?: StorageOptions): Promise<void> {
if (opts) {
// noop
}
Promise.all(keys.map(k => this.storage.removeItem(k)));
}

async getKeys(opts?: StorageOptions): Promise<Array<keyof T>> {
if (opts) {
// noop
}
return Object.keys(this.storage);
}

async dropStorage(opts?: StorageOptions): Promise<void> {
if (opts) {
// noop
}
const keys = await this.getKeys();
await this.removeMany(keys);
}
}

export default WebStorage;
15 changes: 15 additions & 0 deletions packages/storage-web/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"extends": "../../base.tsconfig",
"compilerOptions": {
"lib": ["es2017", "dom"],
"types": ["@types/jest"]
},
"include": [
"./src",
"./__tests__",
"./types"
],
"exclude": [
"node_modules"
]
}
39 changes: 39 additions & 0 deletions packages/storage-web/types/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,42 @@
* LICENSE file in the root directory of this source tree.
*
*/

import {
EmptyStorageModel,
IStorageBackend,
StorageOptions,
} from '@react-native-community/async-storage';
export default class WebStorage<T = EmptyStorageModel>
implements IStorageBackend<T> {
private readonly _asyncStorageNativeModule;
storage: Function;
getSingle<K extends keyof T>(
key: K,
opts?: StorageOptions,
): Promise<T[K] | null>;

setSingle<K extends keyof T>(
key: K,
value: T[K],
opts?: StorageOptions,
): Promise<void>;

getMany<K extends keyof T>(
keys: Array<K>,
opts?: StorageOptions,
): Promise<{[k in K]: T[k] | null}>;

setMany<K extends keyof T>(
values: Array<{[k in K]: T[k]}>,
opts?: StorageOptions,
): Promise<void>;

removeSingle(key: keyof T, opts?: StorageOptions): Promise<void>;

removeMany(keys: Array<keyof T>, opts?: StorageOptions): Promise<void>;

getKeys(opts?: StorageOptions): Promise<Array<keyof T>>;

dropStorage(opts?: StorageOptions): Promise<void>;
}
24 changes: 0 additions & 24 deletions tsconfig.json

This file was deleted.

Loading