npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

easy-app-storage

v2.0.0

Published

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 implement

Downloads

371

Readme

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[]>;