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

@electerm/use-proxy

v0.10.0-beta.0

Published

This is a fork of [https://github.com/tylerlong/use-proxy](https://github.com/tylerlong/use-proxy), remove support for child operations, means only support set/get the whole object, operation like `obj.x,y` or `obj[0]` not supported, expecting to gain mor

Readme

useProxy

This is a fork of https://github.com/tylerlong/use-proxy, remove support for child operations, means only support set/get the whole object, operation like obj.x,y or obj[0] not supported, expecting to gain more performance when facing complicated object/array and reduce the use of event emiiters.

Installation

yarn add @electerm/use-proxy

# npm
npm i -D @electerm/use-proxy

Usage

import {useProxy} from '@electerm/use-proxy';
import {Component} from '@electerm/use-proxy/build/react';

class Store {
  count = 0;
  todos = []; // a big array with 1000+ members and complicated props
  increase() {
    this.count += 1;
  }
  updateTodo (id, update) {
    const arr = this.todos()
    const inst = arr.find(f => f.id === id)
    Object.assign(inst, update)
    this._todo = JSON.stringify(arr)
  }
  setTodos (todos) {
    this.todos = todos
  }
}
const store = useProxy(new Store());

class App extends Component<{store: Store}> {
  render() {
    const store = this.props.store;
    return (
      <div>
        <span>{store.count}</span>
        <button onClick={() => store.increase()}>+</button>
      </div>
    );
  }
}

Event Emitter

import {useProxy} from '@tylerlong/use-proxy';
import {ProxyEvent} from '@tylerlong/use-proxy/build/models';

class Store {}
const store = useProxy(new Store());

store.__emitter__ is an EventEmitter which will emit events about read/write to store. You can subscribe to events:

store.__emitter__.on('event', (event: ProxyEvent) => {
  // do something with event
});

Utility methods

run

The signature of run is

function run<T>(
  proxy: ProxyType<T>,
  func: Function
): [result: any, isTrigger: (event: ProxyEvent) => boolean]
  • proxy is generated from useProxy method: const proxy = useProxy(store).
  • func is a function which reads proxy.
  • result is the result of func().
  • isTrigger is a function which returns true if an event will "trigger" func() to have a different result.
    • when it returns true, most likely it's time to run func() again(because you will get a different result from last time).

When you invoke run(proxy, func), func() is invoked immediately. You can subscribe to proxy.__emitter__ and filter the events using isTrigger to get the trigger events (to run func() again).

For a sample usage of run, please check ./src/react.ts.

Another example is the implementation of the autoRun utility method. You may find it in ./src/index.ts.

autoRun

The signature of autoRun is

function autoRun<T>(
  proxy: ProxyType<T>,
  func: () => void,
  decorator?: (func: () => void) => () => void
): {start: () => void; stop: () => void}
  • proxy is generated from useProxy method: const proxy = useProxy(store).
  • func is a function which reads proxy.
  • decorator is a method to change run schedule of func, for example: func => _.debounce(func, 10, {leading: true, trailing: true})
  • start and stop is to start and stop autoRun.

When you invoke start(), func() is invoked immediately. func() will be invoked automatically afterwards if there are trigger events from proxy which change the result of func(). Invoke stop to stop autoRun.

For sample usages of autoRun, please check ./test/autoRun.spec.ts.

Known issue

  • It only monitors get and set of properties. It doesn't monitor delete, has and keys. Because in 99.9% cases, get & set are sufficient to monitor and manage data.
  • You cannot proxy some built-in objects, such as Set & Map.
  • run and autoRun only support sync methods. for async methods, make sure that the async part is irrelevant because it won't be monitored.

Todo

  • cache data for getter functions to make it faster, just like what I did in SubX project
  • When is typeof path === 'symbol'?
  • Support React Hooks https://reactjs.org/docs/hooks-intro.html
    • I think I mean function style react components
  • Native objects 会报错,比如说 window.speechSynthesis.getVoices()
  • autoRun 逻辑上有漏洞。比如说我想保存一个对象。一开始这个对象的property不全。后来全了。但是新增的props并不被monitor。
    • 一个workaround是把property的值设为null。
      • 不设为undefined,因为json不支持,持久化会有问题。 不过这个问题和本项目无关
  • 如果有循环引用的结构,会报错 Uncaught RangeError: Maximum call stack size exceeded

Notes

  • every emitter.on() must have a corresponding emitter.off(). Otherwise there will be memory leak.
    • you also don't have to on and off again and again. Sometimes you just on and let it on until user explicit it request it to be off.
      • check the source code of autoRun.
  • rewrite some emitter.on to promise.
    • the idea is great, but it will turn the library from sync to async, which will cause unexpected consequences.
    • React.render, EventEmitter.on, rxjs.observable.next are all sync, there must be a good reason to stay with sync.