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

@j-theta/j-store

v1.0.6

Published

Use the localStorage like a small database

Downloads

2

Readme

j-Store

Use the localStorage like a small database.

This package was created for me to use in my own projects, but i thought that will be useful for others to use

See this simple Todo App that uses jStore.

Some warnings

  1. This project is still in development, so pardon for any bugs.
  2. I'm from brazil and my english is not so great, so if you see an english error in this documentation, i'm sorry.
  3. Please, consider using a real database if you want to hold sensitive information.

Instalation

npm i --save @j-theta/j-store

Usage

import jStore from '@j-theta/j-store';
// will save the object passed in the localStorage 
// if there are already an object in the localStorage with the key
// __JSTORE__, then this object will be ignored
// and the object in the localStorage will be loaded instead
const store = new jStore({
  users: {
    "45": { age: 37, name: "Dorothy Nelson"     },
    "59": { age: 40, name: "Randy Floyd"        },
    "57": { age: 31, name: "Lillian Russell"    },
    "28": { age: 37, name: "Ray Adkins"         },
    "42": { age: 21, name: "Jonathan Hernandez" },
  },
  cities: [
    'Medufpuh',
    'Oguagwon',
    'Wuhaful',
    'Pitburi',
    'Mimekiras',
    'Suvvakpo',
  ]
});

// get the users
store.get('/users')
/*
  [
    { age: 37, name: "Dorothy Nelson"     },
    { age: 40, name: "Randy Floyd"        },
    { age: 31, name: "Lillian Russell"    },
    { age: 37, name: "Ray Adkins"         },
    { age: 21, name: "Jonathan Hernandez" },
  ]
*/

store.get('/users/28') // { age: 37, name: "Ray Adkins" }

// get the cities
store.get('/cities')
/*
  [
    'Medufpuh',
    'Oguagwon',
    'Wuhaful',
    'Pitburi',
    'Mimekiras',
    'Suvvakpo',
  ]
*/

// if you want an item from an array with specific index
store.get('/cities/0') // 'Medufpuh'

// adding an item in the storage
store.post('/hello', 'world!')

store.get('/hello') // 'world!'

// remove an item from the storage
store.remove('/hello')

store.get('/hello') // undefined

The jStore class constructor

constructor(data: object, listeners?: Partial<Listeners>)

Properties

  1. store - Get the current store data

Methods

  1. get - Get data from store with the given path
public get(path?: string, options?: options): any;
  1. set - Set new data in the given path
public set(path: string, data: any): void;
  1. post - Like the set method, this method add new data in the store, but only if the path does not already exists. This is useful when you want to add new data without accidentaly override the data of an path that already exists.
public post(path: string, data: any): void;
  1. reset - Reset the store to its default state.
public reset(): void;
  1. remove - Remove a path from the store.
public remove(path: string): void;
  1. add - Add new items to an array in the store.
public add(path: string, value: any, index?: number): void;
  1. exists - Test if a path exists in the store
public exists(path: string): void;
  1. on - Add a event listener to the store.
public on(method: Method, handler: (...args: any[]) => void) : void

Options to get

interface options {
    /** A function to filter the results */
    where?: (value: any, index: number) => boolean;
    /** a string property to order the results */
    orderBy?: string;
    /** Determine if the result order will be `descending` */
    desc?: boolean;
    /** Determine if the result order will be 'ascending' */
	  asc?: boolean;
    /** an integer to limit the results */
    limit?: number;
}

Filtering the results

Using the store from the previous example

store.get('/cities', {
  where: citie => citie.startsWith('M')
}) // ['Medufpuh', 'Mimekiras']

Ordering the results

Order ascending will be the default

store.get('/users', { orderBy: 'age' })
/*
  [
    { age: 21, name: "Jonathan Hernandez" },
    { age: 31, name: "Lillian Russell"},
    { age: 37, name: "Ray Adkins"},
    { age: 37, name: "Dorothy Nelson"},
    { age: 40, name: "Randy Floyd"},
  ]
*/

But, you can order the results descending if you want

store.get('/users', { orderBy: 'age', desc: true })
/*
  [
    { age: 40, name: "Randy Floyd"},
    { age: 37, name: "Dorothy Nelson"},
    { age: 37, name: "Ray Adkins"},
    { age: 31, name: "Lillian Russell"},
    { age: 21, name: "Jonathan Hernandez"},
  ]
*/

Limiting the results

store.get('/users', { limit: 2 })
/*
  [
    { age: 37, name: "Dorothy Nelson"},
    { age: 40, name: "Randy Floyd"},
  ]
*/

Events

You can add some event listeners to control how your store is manipulated.

store.on(method: Method, handler);

type Method = 'get' | 'set' | 'post' | 'remove' | 'reset' | 'add';

Examples:

  1. Get logs
store.on('get', path => console.log(`The path ${path} has been accessed`))

store.get('/users') // logs: The path /users has been accessed
  1. Data validation

If you return a value in the callback passed in the on method, then the post method will return that value before sending the data to the store. This is useful when you want to validate new data.

store.on('post', (path, data) => {
  if (path.startsWith('/user')) {
    const { name, age } = data;
    if (name.trim() === '') return new Error('The user name must be valid')
    if (age < 18) return new Error('The user must be adult')
  }
})
  1. Simulate a protected route

You can use examples like this to protect some paths to be accessed.

store.on('get', path => {
  if (path === '/protected-route') {
    return new Error("Can't access a protected route")
  }
})

The Listener interface

interface Listeners {
	/**
	 * This function is called every time the `set` method is called.
	 * @param path the path passed to `set`.
	 * @param data the data passed to `set`.
	 * @param store the store instance.
	 */
	onset(path?: string, data?: any, store?: jStore): void | any;
	/**
	 * This function is called every time the `post` method is called.
	 * @param path the path passed to `post`.
	 * @param data the data passed to `post`.
	 * @param store the store instance.
	 */
	onpost(path?: string, data?: any, store?: jStore): void | any;
	/**
	 * This function is called every time the `get` method is called.
	 * @param path the path passed to `get`.
	 * @param store the store instance.
	 */
	onget(path?: string, store?: jStore): void | any;
	/**
	 * This function is called every time the `reset` method is called.
	 * @param store the store instance.
	 */
	onreset(store?: jStore): void | any;
	/**
	 * This function is called every time the `remove` method is called.
	 * @param path the path passed to `remove`.
	 * @param store the store instance.
	 */
	onremove(path?: string, store?: jStore): void | any;
	/**
	 * This function is called every time the `add` method is called.
	 * @param path the path passed to `add`.
	 * @param value the value passed to `add`.
	 * @param index the index passed to `add`.
	 * @param store the store instance.
	 */
	onadd(path?: string, value?: any, index?: number, store?: jStore): void | any;
}

The jStoreAsync class

This class is useful when you want to simulate real requests to a dabatase, to see how your UI handle promises.

All methods of this class behave exactly like the jStore class, except that each method returns a promise.

constructor(data: object, delay: number = 1000)

The delay argument is the time in milliseconds that each promise takes to resolve.

Examples


import { jStoreAsync } from '@j-theta/j-store'

const initialState = {
  cities: [
    'Imozumop',
    'Hiducuv',
    'Gowoju',
    'Retona',
    'Pirovo',
    'Uwlaji',
    'Emefetil',
  ],
  emails: [
    '[email protected]',
    '[email protected]',
    '[email protected]',
    '[email protected]',
    '[email protected]',
  ]
}

const store = new jStoreAsync(initialState, 1200);

store.get('/cities')
  .then(res => console.log(res))
  /*
    [
      'Imozumop',
      'Hiducuv',
      'Gowoju',
      'Retona',
      'Pirovo',
      'Uwlaji',
      'Emefetil',
    ]
  */

 store.post('/cities', 'foo')
  .catch(e => console.log(e))
  // Error: "The path /cities is already been used"