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

killua

v0.4.11

Published

killua is a local-storage management library for React applications.

Downloads

75

Readme

killua ·

killua is a local-storage management library for React applications.

Table of Contents

Installation

To install the latest stable version, run the following command:

# npm
npm install killua

# pnpm
pnpm install killua

# yarn
yarn add killua

Features

  • Get data from localStorage
  • Set data to localStorage
  • Reducer for state management
  • Selector for data access
  • Expiration timer
  • Schema validation
  • Obfuscate data in localStorage
  • Server-Side Compatibility
  • TypeScript friendly
  • Auto update in other tabs
  • Auto update in other components
  • Config file for configuration management

examples

Usage

Create slice configuration file

Whatever the useKillua hook returns, the slice function also returns. Use the useKillua hook within the React framework, and as long as you don't have access to it, use the slice function.

that slice refers to a key within localStorage.

  1. Create a slices directory for the thunder configuration.
  2. Create the slice configuration file, for example: counter.ts.
  3. Set up the slice configuration:
import { slice } from 'killua';

export const counterSlice = slice({
  key: 'counter', // unique key for localStorage
  defaultClient: 1 as number // default value for client-side application
});

Get data

  • Within a React component, utilize the useKillua hook :
import { useKillua } from "killua";
import { counterSlice } from "@/slices/counter";

export default function Component() {
  const localstorageCounter = useKillua(counterSlice);
  return (
    <div>
      <p>{counterSlice.get()}</p>
    </div>
  )
};
  • Outside of a React component, employ the slice function :
import { counterSlice } from '@/slices/counter';

export function getCounter() {
  return counterSlice.get();
}

Set data

  • Within a React component, utilize the useKillua hook :
import { useKillua } from "killua";
import { counterSlice } from "@/slices/counter";

export default function Component() {
  const localstorageCounter = useKillua(counterSlice);
  return (
    <div>
      {/* without callback */}
      <button onClick={() => counterSlice.set(0)}>Set counter to zero</button>
      {/* with callback */}
      <button onClick={() => counterSlice.set((prev) => prev + 1)}>Increment counter</button>
    </div>
  )
};
  • Outside of a React component, employ the slice function :
import { counterSlice } from '@/slices/counter';

// without callback
export function setCounterToZero() {
  counterSlice.set(0);
}

// with callback
export function incrementCounter() {
  counterSlice.set(prev => prev + 1);
}

Use selectors

  • To use a selector, simply add it to the slice config :
import { slice } from 'killua';

export const counterSlice = slice({
  key: 'counter',
  defaultClient: 1 as number,
  selectors: {
    getPlusOne: (value) => value + 1,
    getPlusWithPayload: (value, payload: number) => value + payload
  }
});
  • Within a React component, utilize the useKillua hook :
import { useKillua } from "killua";

export default function Component() {
  const localstorageCounter = useKillua(counterSlice);
  return (
    <div>
      <p>{localstorageCounter.getPlusOne()}</p> {/* without payload */}
      <p>{localstorageCounter.getPlusWithPayload(5)}</p> {/* with payload */}
    </div>
  )
};
  • Outside of a React component, employ the slice function :
import { counterSlice } from '@/slices/counter';

// without payload
export function getCounterWithPlusOne() {
  return counterSlice.getPlusOne();
}

// with payload
export function getCounterWithPlusWithPayload() {
  return counterSlice.getPlusWithPayload(5);
}

Use reducers

  • To use a reducer, simply add it to the slice config :
import { slice } from 'killua';

export const counterSlice = slice({
  key: 'counter',
  defaultClient: 1 as number,
  reducers: {
    increment: (value) => value + 1,
    incrementWithPayload: (value, payload: number) => value + payload
  }
});
  • Within a React component, utilize the useKillua hook :
import { useKillua } from "killua";

export default function Component() {
  const localstorageCounter = useKillua(counterSlice);
  return (
    <div>
      <button onClick={() => localstorageCounter.increment()}>Increment counter</button> {/* without payload */}
      <button onClick={() => localstorageCounter.incrementWithPayload(5)}>Increment counter with payload</button> {/* with payload */}
    </div>
  )
};
  • Outside of a React component, employ the slice function :
import { counterSlice } from '@/slices/counter';

// without payload
export function incrementCounter() {
  counterSlice.increment();
}

Using in SSR application

As long as the initial server-side rendering occurs and there is no access to localStorage, defaultServer will be returned. Later, when the client-side rendering takes place, data will be fetched from localStorage and returned.

As long as defaultServer exists in the config, both the useKillua hook and the slice function will return a property named isReady. If this value is false, it means that it is server-side and localStorage is not accessible, and the returned value is defaultServer.If this value is true, it means that it is client-side and localStorage isaccessible, and the fetched value is from localStorage.

  • add defaultServer to the slice configuration :
import { slice } from 'killua';

export const counterSlice = slice({
  key: 'counter',
  defaultClient: 1 as number,
  defaultServer: 2 // default value for server-side application
});
  • Within a React component, utilize the useKillua hook :
'use client';

import { useKillua } from "killua";

export default function Component() {
  const localstorageCounter = useKillua(counterSlice);
  return (
    <div>
      {localstorageCounter.isReady ? <p>{localstorageCounter.get()}</p> : <p>Loading...</p>}
    </div>
  )
};
  • Outside of a React component, employ the slice function :
import { counterSlice } from '@/slices/counter';

export function getCounter() {
  // if is server-side ? return defaultServer : return localStorage value
  return counterSlice.get();
}

// with payload
export function incrementCounterWithPayload() {
  counterSlice.incrementWithPayload(5);
}

Obfuscate data

As long as obsfacte is present in the slice config, your data is not protected but merely obfuscated.

Avoid placing sensitive data on localStorage.

  • To obfuscate localStorage data, simply add it to the slice config:
import { slice } from 'killua';

export const counterSlice = slice({
  key: 'counter',
  defaultClient: 1 as number,
  obsfacte: true // obfuscate data in localStorage
});

Expire timer

If the localStorage data expires at the moment when a user is on the website and the useKillua hook is in use, the data will be immediately removed from localStorage. Subsequently, the useKillua hook will update and return the defaultClient value.

If the user enters the site and the data has already expired, the defaultClient value will be returned.

  • To set an expiration time for localStorage data, simply add it to the slice config :
import { slice } from 'killua';

export const counterSlice = slice({
  key: 'counter',
  defaultClient: 1 as number,
  expire: '1d-9h-24m-10s' // expire time for localStorage data (1 day, 9 hours, 24 minutes, 10 seconds)
});

Schema validation

If schema exists in the configuration, when the localStorage is updated using set or reducers, the data will be validated against that schema. If it is not valid, it will not be set on the localStorage.

If schema is exists in the configuration, when the localStorage data is retrieved using selectors or get, and if it is validated against the schema and found to be invalid, the defaultClient value will be returned instead.

  • To set a schema for localStorage data, simply add it to the slice config :
import { slice } from 'killua';

export const counterSlice = slice({
  key: 'counter',
  defaultClient: 1 as number,
  schema: z.number().min(0).max(10) // zod schema or yup schema
});