2.0.0 • Published 2 years ago

easy-app-storage v2.0.0

Weekly downloads
-
License
MIT
Repository
github
Last release
2 years ago

Easy App Storage

Simplified API for working with Local Storage, Session Storage or Async Storage. Stores anything that is JSON.stringify-able. This can be scoped to only a particular prefix so as to not interfere with other code that might be using the storage implementation. You can optionally hook into sets and deletes.

Example

// Pass the storage API that you will use
// All keys will be prefixed with `hey:[key]`
const local = new AppStorage(localStorage, 'hey');

// With hooks
const local = new AppStorage(localStorage, {

    prefix: 'hey',
    onBeforeSet(keyOrObject: string | object, value?: any) {

        if (typeof keyOrObject === 'object') {

            events.emit('storage-changed', keyOrObject);
            return;
        }

        events.emit('storage-changed', { [keyOrObject]: value });
    },
    onBeforeRemove(keyOrKeys: string | string[]) {

        if (Array.isArray(keyOrKeys)) {

            events.emit('storage-removed', keyOrKeys);
            return;
        }

        events.emit('storage-removed', [keyOrKeys]);
    }
});


const theFruits = {
    apples: 5,
    bananas: 10,
    oranges: 12
};

// Save an object
await local.set('fruits', theFruits);

// You can fetch an object and pass the type
// that you expect to get back from it
const savedFruits = await local.get <typeof theFruits>('fruits');

// Object.assign the existing object
await local.assign('fruits', {
    peaches: 5,
    dragonFruit: 15
});

// Set an entire object and its keys will be
// saved as part of the store
await local.set({
    many: true,
    different: 'keys',
    can: 'be set',
    when: ['you', 'pass', 'an', 'object']
});

await local.get('many')
// > true

await local.get('different')
// > 'keys'

await local.get('can')
// > 'be set'

await local.get('when')
// > ['you', 'pass', 'an', 'object']

// Remove a keyor many keys
await local.rm('when');
await local.rm(['can', 'when']);

// Check if a key exists
await local.has('when'); // false

// Similar API to an object
const keys = await local.keys();
const values = await local.values();
const entries = await local.entries();

Extend typings

You can extend the typings used to identify keys and the shape of the data they will have by extending the interface StoredAppValues

import {
    AppStorageKeys,
    AppStorageValues
} from 'easy-app-storage'

type Auth = {
    bearer_token: string,
    refresh_token: string
};

type Themes = 'dark' | 'light';

declare module 'easy-app-storage' {

    export interface StoredAppValues {

        auth: Auth | null;
        theme: Theme;
        showHelp: boolean;
    }
}

const themeSwitcher = (theme: Themes) => {

    // this will scream if the value is incorrect
    await storage.set('theme', theme);
}

// this will accurately retrieve the auth type
const auth = await storage.get('auth');

AppStorage options

interface onSet {

    <K extends Keys>(key: K, value: Shapes<K>): Void;
    (value: StoredAppValues & Record<string, JsonStringifyable>): Void;
}

interface onRemove {

    (key: Keys): Void;
    (key: Keys[]): Void;
}


interface AppStorageOptions {

    prefix?: string
    onBeforeSet?: onSet
    onAfterSet?: onSet
    onBeforeRemove?: onRemove
    onAfterRemove?: onRemove
}

interface AppStorage {

    constructor(storage: StorageImplementation, prefixOrOptions?: string | AppStorageOptions)

    // ...etc
}

get(keyOrKeys?: string | string[])

/**
 * Returns an object of all keys
 */
async get <T = StoredAppValues>(): Promise<T>

/**
 * Returns a single value from storage
 * @param key key to find
 */
async get <K extends Keys>(key: K): Promise<Shapes<K>>
async get <T = JsonStringifyable>(key: string): Promise<T>

/**
 * Returns an object of the keys passed
 * @param keys keys to find
 */
async get <
    K1 extends Keys,
    K2 extends Keys,
    // ...etc
>(keys: [K1, K2]): Promise<
    Record<K1, Shapes<K1>> &
    Record<K2, Shapes<K2>>
    // ...etc
>

/**
 * Or maybe you don't care about being typed and want to return anything.
 * You can always define the return type.
 * @param keys keys to find
 */
async get <T = Record<string, JsonStringifyable>>(keys: string[]): Promise<T>
  • get() returns the entire storage
  • get('key') returns the value of that particular key
  • get(['key1', 'key2']) returns an object of { key: value }

set(keyOrObject: string | object, value?: any)

/**
 * Saves entire object by `{ key: value }`
 * @param values object to save to storage
 */
async set(values: Partial<StoredAppValues> & Record<string, any>): Promise<void>

/**
 * Sets a key to given value into storage
 * @param key
 * @param value
 */
async set <K extends Keys>(key: K, value: Shapes<K>): Promise<void>
async set <K extends Keys | string>(key: K, value: Shapes<K>): Promise<void>
/**
 * `Object.assign()` given value to given key
 * @param key key to merge
 * @param val value to merge
 */

async assign <K extends Keys>(key: K, val: Partial<Shapes<K>>): Promise<void>
async assign <K extends Keys | string>(key: K, val: Partial<Shapes<K>>): Promise<void>

remove(keyOrKeys: string | string[]) or rm(...)

/**
 * Removes a single key
 * @param key
 */
async remove <K extends Keys>(key: K): Promise<void>
async remove(key: string): Promise<void>

/**
 * Removes the given array of keys
 * @param keys
 */
async remove(key: Keys[]): Promise<void>
async remove(keys: string[]): Promise<void>

has(keyOrKeys: string | string[])

/**
 * Returns an array of boolean values denoting
 * whether the keys exist within the storage or not
 * @param keys
 */
has(keys: Keys[]): Promise<boolean[]>
has(keys: string[]): Promise<boolean[]>

/**
 * Returns whether key exists within the storage
 * @param key
 */
has(keys: Keys): Promise<boolean>
has(key: string): Promise<boolean>

clear() or reset()

/**
 * Removes all prefixed values from the storage
 */
clear(): Promise<void>;

keys()

/**
 * Returns all keys scoped by prefix
 */
keys(): Promise<string[]>;

entries()

/**
 * `Object.entries()` against the entire store as an object
 */
entries(): Promise<[string, JsonStringifyable][]>;

values()

/**
 * `Object.values()` against the entire store as an object
 */
values(): Promise<JsonStringifyable[]>;
1.0.1

2 years ago

2.0.0

2 years ago

1.0.0

2 years ago