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

proxy-states

v0.0.7

Published

A plain proxy implementation to support a state object where you can define properties and actions.

Readme

Proxy States

Proxy States creates an object to hold states and actions. An action can manipulate the states internally. When a state gets changed, it can notify us with an event.

Install

npm install proxy-states

Quick Start

Say you want to build a counter logic. You can put the count variable under an object:

import proxy from 'proxy-states'

const p = proxy({
  count: 1
})

p.count 	  // count: 1

Now to increment the variable, you can do that directly:

p.count++   // count: 2

Or you can define an action under:

const p = proxy({
  count: 1,
  inc: (state, payload) => {
    state.count += payload
  }
})  

p.inc(9)    // count: 10

Notice the inc action is defined with a function that takes the current state as an input argument.

To listen to a state change, we can subscribe to it with an event listener:

const p = proxy({
  count: 1
})

p.on('count', (v, prev) => {
  // v: 2, prev: 1
  console.log(v)
})

p.count++

The on function listens to any change happened to the count state. The callback gives you the current value and the previous value it changes from.

You can also listen to a set of states change instead of a single state:

p.on(['count'], (v, prev, prop) => {
	// v: 2, prev: 1, prop: 'count'
})

Options

We can supply a set of options when defining this object to customize the behavior.

afterSet

When a state has changed, a afterSet callback can be invoked if provided:

const p = proxy({
  count: 1
}, {
  afterSet: (obj, prop, value, prev) => {
    // prop = 'a', value = 2, prev = 1
    console.log(obj)
  }
})

p.count++		

You can use this callback to monitor the committed state change and perform tasks upon the change.

canSet

If you want to restrict a change from happening, you can use a canSet callback to tell it do so:

const p = proxy({
  count: 1,
  inc: (state) => { state.count++ }
}, {
  canSet: (obj, prop, value) => {
    return value < 3
  }
})

p.inc()   // 2
p.inc()   // 2

Basically the canSet callback is used to determine whether a state change request should be accepted. For example, if you don't want to commit changes from the same state value, you can compare the new and old state value and skip if they are same:

  canSet: (obj, prop, value) => obj[prop] !=== value

beforeSet

The afterSet callback is only invoked for the accepted changes. In order to monitor all changes including the skipped ones, we can use the beforeSet callback:

const p = proxy({
  count: 1,
  inc: (state) => { state.count++ }
}, {
  beforeSet: (obj, prop, value, canSet) => {
		console.log(canSet)
  }
})

p.inc()

Use the beforeSet callback can capture all change request regardless whether the change is accepted.

React

Feel free to use the proxy-states as it is. Also you can integrate it to a system that supports a dispatch.

Using React as an example, the library exports a helper createProxyHook that takes useState from react and exports a hook useProxy for you.

import { createProxyHook } from 'proxy-states'
import { useState } from 'react'

const useProxy = createProxyHook(useState)

With the useProxy hook, we can apply it to the App component with counter state.

const counter = {
  count: 1,
  inc: (state) => { state.count++ },  
}

function App() {
  const m = useProxy(counter)  
  
  return <div>{m.count}</div>
}

Develop

  yarn install
  yarn test