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 🙏

© 2026 – Pkg Stats / Ryan Hefner

@onpaper/data-store

v1.0.2

Published

a state management library, and lightweight

Readme

English
简体中文

Introduction

This is a state management library. Compared with Pinia, vuex, and Redux, it is more lightweight and very simple to use. Like Pinia, it can create multiple Store instances. At the same time, when the state data in the Store instance changes , you can call back the corresponding function, that is to say, it is responsive, and it also supports TypeScript.

how to use

1、npm Install dependencies

npm install @onpaper/data-store

2、import package

Node

Write the following code in the JavaScript file

// es module
import pkg from "@onpaper/data-store";
const { defineStore } = pkg;

// commonjs
const { defineStore } = require("@onpaper/data-store");

TypeScript

if you use TypeScript

import { defineStore } from "@onpaper/data-store";

3、quick start

import { defineStore } from "@onpaper/data-store";
// 1.define a store
const studentStore = defineStore({
  state: {
    name: 'jack',
    hobby:[],
    friends: {
      name: 'rose'
    }
  },
  actions: {
    getStudentInfoAction(ctx, payload) {
      // axios sends network requests or other asynchronous events
      // ctx is state
      ctx.name = 'Bob'
      // dispatch function the incoming payload
      console.log(payload) // -> { id: 123 }
      // this is store instance
      console.log(this === studentStore) // -> true
    }
  }
})

// 2. watch state
// first : state key
// second : The function to call back when the listen parameter changes
studentStore.watch('hobby', (newHobby, oldHobby) => {
  console.log(newHobby, oldHobby) // -> ['playGames'] []
})

// listen at the same time "name" "age" ,Any change will be called back fn1 fn2
studentStore.watch(['name', 'age'], [fn1, fn2])

// 3. change the data
studentStore.setState({ hobby: ['playGames'] })

// 4. Callback function execution
//console.log(newHobby, oldHobby)


//5. dispatch dispatch async method
// first : Function name registered in actions
// second : You can customize a payload to the action function parameter of the call
studentStore.dispatch('getStudentInfoAction', { id: 123 })

// 6. Callback function execution
// fn1 fn2

4、API methods

Define a store (defineStore)

import { defineStore } from "@onpaper/data-store";

const studentStore = defineStore({
  state: {
    name: 'jack',
    friends: {
      name: 'rose'
    }
  },
  actions: {
    getStudentInfoAction(ctx, payload) {
      // ...Perform asynchronous operations such as network requests
    }
  }
})

Use the defineStore method, passing in the custom state parameter to initialize the store

Change state data (setState)

const studentStore = defineStore({
  state: {
    name: 'jack',
    hobby: [],
    friends: {
      name: 'rose',
      hobby: []
    }
  }
})

// Method 1: Use the setState method
const hobby = ["runnig"]
studentStore.setState({ name: "lucy", hobby })

// Method 2: Direct change
studentStore.state.hobby = ['baseball']
studentStore.state.friends.name = "Bob"

There is no difference between the two methods, which one is more convenient to use

Watch state data (watch)

basic use

// 1. generate store
const studentStore = defineStore({
  state: {
    name: 'jack',
    hobby: [],
    friends: {
      name: 'rose',
      hobby: []
    }
  }
})

// 2. listen data
// first : key of state
// second : The function to call back when the monitored parameter changes
studentStore.watch('hobby', (newHobby, oldHobby) => {
  console.log(newHobby, oldHobby) // -> ['playGames'] []
}s

// 3. change the data
studentStore.setState({ hobby: ['playGames'] })

// 4. Callback function execution
//console.log(newHobby, oldHobby)

If the changed value is the same as the last value, the callback function will not be called

Other parameters

// watch(stateName,callfunction,option,this)
studentStore.watch(
  'name',
  function (newValue, oldValue) {
    console.log(this) //  { test: 123 }
  },
  {
    // option
    immediate: true // Execute the callback function immediately
  },
  //  this
  { test: 123 }
)

option can pass the immediate parameter to execute the callback function immediately, and the last parameter of watch can be bound to the this of the callback function

Deep listening

The watch function performs deep listening by default, which means that the callback function will be executed even if the multi-level nested data changes.

// 1. friends nest friends
const studentStore = defineStore({
  state: {
    name: '',
    friends: {
      name: 'jack',
      friends: {
        name: 'rose',
        hobby: [{ test: 'fail' }]
      }
    }
  }
})

// 2. Listen to the state.friends 
studentStore.watch('friends', (newValue, oldValue) => {
  console.log(newValue.friends.hobby[0].test)  //  -> success
  console.log(oldValue.friends.hobby[0].test) //  ->  fail
})

// 3. change data
const testObj = studentStore.state.friends.friends.hobby[0]
testObj.test = 'success'

Watch multiple state value

const studentStore = defineStore({
  state: {
    name: '',
    age: 0
  }
})

// Also listen to "name" "age"
// The parameters of the callback function are returned as an array
studentStore.watch(['name', 'age'], ([newName, newAge], [oldName, oldAge]) => {
  console.log(newName, newAge)
  console.log(oldName, oldAge)
})

// Any changes to the listened property will execute the callback function
studentStore.setState({ name: 'jack' })
studentStore.setState({ age: 18 })

When listening to multiple state properties, the first parameter passed in is an array of listening properties. When any property in the array changes, the callback function will be executed, and the parameters of the callback function will be returned as an array.

Multiple callback functions

const studentStore = defineStore({
  state: {
    name: '',
    age: 0
  }
})

studentStore.watch(['name', 'age'], [test1, test2])

The callback function can also pass in an array of functions. When the property changes, the functions in the array will be called sequentially

cancel listening

watch will return a cancel function, and executing the cancel function can cancel the watch directly

// method 1:  The watch function returns a cancel function
const offWatch = studentStore.watch(['hobby',"name"], newHobby => {
  // ....
})
// Execute cancel function to cancel listening
offWatch()
offWatch

Sometimes it is inconvenient to use the cancel function, so you can use the offWatch method

// method 2: offWatch
// Added three callback functions log1, log2, log3
studentStore.watch('age', [log1, log2, log3])

//first : cancel listening name
//second : Functions that need to be canceled
studentStore.offWatch('age', log1)  // only cancel log1
studentStore.offWatch('age', [log2, log3]) // cancel log2 and log3
clearWatch

If you want to cancel all the callback methods of some listening properties at once

// clearWatch 
studentStore.watch('age', [log1, log2, log3])
studentStore.clearWatch('age')

studentStore.watch(['age','name'], [log1, log2, log3])
studentStore.clearWatch(['age','name'])
clearAllWatch

If you want to cancel all listeners of the store instance

//clearAllWatch
studentStore.watch('age', [log1, log2, log3])
studentStore.watch(['age', 'name'], [log1, log2, log3])

studentStore.clearAllWatch()

dispatch method

const studentStore = defineStore({
  state: {
    name: ''
  },
  actions: {
    getStudentInfoAction(ctx, payload) {
      // axios sends network requests or other asynchronous events
      // ctx is state
      ctx.name = 'jack'
      // dispatch the incoming payload
      console.log(payload) // -> { id: 123 }
      // this is the store instance
      console.log(this === studentStore) // -> true
    }
  }
})

//The state callback function will be called 
//when the actions registered function modifies the state
studentStore.watch('name', newName => {
  console.log(newName) // -> jack
})

// first : Function name registered in actions
// second : You can send a payload to the dispatch function 
studentStore.dispatch('getStudentInfoAction', { id: 123 })

First register the function in actions, use the dispatch method to pass in the function name to call, and you can pass the payload when calling

5、TypeScript support

example:

interface IStudentData {
  name: string
  age: number
  hobby: string[]
  friends: friendType
}

type IActionFn = {
  getStudentInfoAction?: (ctx: IStudentData, payload: any) => void
}
  
// The first parameter is the state type, the second is the actions type
const studentStore = defineStore<IStudentData, IActionFn>({
  state: {
    // ....
  },
  actions: {
    //...
  }
})