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 🙏

© 2025 – Pkg Stats / Ryan Hefner

@misaka17535/create-typed-event

v1.0.17

Published

Function-based and directive tiny typed event, with current value and optional react hook. Proven and well-tested in private projects. 全功能、函数式调用的微型事件库,可读取当前值且带有可选 react hook。在内部项目中久经考验。

Readme

create-typed-event

NPM Version npm bundle size

中文 | English

Typed . Autocomplete . One call unsubscribe . React is Optional

A simple eventManager, with built-in react support.
Best practices refined over five years. Proven and well-tested in private projects.

......And seriously, what's so bad about jumper wiring?

History on gist: https://gist.github.com/Misaka-0x447f/0c37018ae7bd944cbff54d27b6d4fd9f

Compares

| | typed | easy to use | perf | autocomplete | one call unsub | no React | latestValue | |--------------------|------------|---------|-------|------|--------|------------|----------| | create-typed-event | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | | redux | *️⃣ 1 | ❌ | *️⃣ 5 | ✅ | ✅ | ✅ | ✅ | | mitt | *️⃣ 2 | ✅ | ✅ | ❌ | ❌ | ✅ | ❌ | | jotai | ✅ | *️⃣ 3 | ✅ | ✅ | ✅ | ❌ | *️⃣ 8 | | valtio | ✅ | *️⃣ 4 | *️⃣ 6 | ✅ | ✅ | ✅ | ✅ | | rxjs | ✅ | ❌ | *️⃣ 7 | ✅ | ✅ | ✅ | ✅ |

*1: Reducer required
*2: All key shares same type
*3: Two step create, atom & store
*4: Proxy based, which means just like vue 3, has it's trace limitation.
*5: Heavy slice
*6: v8 may not play well with proxy
*7: Really heavy even with rxjs subject
*8: Need to use default store

Detailed compares

  • redux
    • Toooooooooooo complex. To emit a state you have to create a new reducer, with a new store, a string store name...
  • mitt / nodejs EventEmitter
    • Requires you to write event name just like node.js EventEmitter: emitter.on('xxx'..., which is not friendly to autocomplete. And why not put key in payload?
    • Does not return an unsub method.
    • Does not support getting current value.
  • jotai
    • To create a equivalent, you have to create an atom, then a store. And it requires user to create store every time user needs to subscribe.
    • Does not support getting current value outside react context. See jotai issue
  • valtio
    • A good solution, but powered by Proxy, which is not really efficient and not working with complex object.
  • rxjs
    • Its Objective: requires you to create an Observable/Subject object, with the "new" statement we hate.
    • Way much larger package size and more complex API.
  • so many others
    • Almost every library I know requires you to write event name on subscription, and cannot auto-complete.
    • So I trust the solution I made can be unique and useful.

Examples

Traditional unsubscribe:

import { createTypedEvent } from '@misaka17535/create-typed-event'

type Payload = { ready: boolean }
const networkStateChange = createTypedEvent<Payload>()

const handler = (payload: Payload) => console.log(payload)
networkStateChange.sub(handler)
networkStateChange.dispatch({ready: true})
networkStateChange.unsub(handler)

>>> { ready: true }

Simplified unsubscribe:

import { createTypedEvent } from '@misaka17535/create-typed-event'

const misakaStateChange = createTypedEvent<{ selfDestructionInProgress: boolean }>()
const unsub = misakaStateChange.sub((payload) => console.log(payload)) // returns unsub function without defining handler outside
misakaStateChange.dispatch({selfDestructionInProgress: true})
unsub()

>>> { selfDestructionInProgress: true }

Create an "event bus":

import { createTypedEvent } from '@misaka17535/create-typed-event'

export const eventBus = {
    alice: createTypedEvent(),
    bob: createTypedEvent<{ isE2eEncryption: boolean }>()
}
eventBus.bob.dispatch({isE2eEncryption: true})

Supports react hook:

import { createTypedEventMemorized } from '@misaka17535/create-typed-event/react'
const marketPriceUpdateEvent = createTypedEventMemorized<number>();

import { useTypedEventValue } from '@misaka17535/create-typed-event/react'
const [marketPrice, setMarketPrice, marketPriceRef] = useTypedEventValue(marketPriceUpdateEvent);

API

import { createTypedEvent, type TypedEvent } from '@misaka17535/create-typed-event'

  • type TypedEvent<Payload>

    • The type that "createTypedEvent" returns.
  • createTypedEvent<Payload>(dispatchLastValueOnSubscribe?: boolean): TypedEvent<Payload> Create a new event unit.

    • Parameter
      • dispatchLastValueOnSubscribe optional, default to false.
        If dispatchLastValueOnSubscribe is true, it will dispatch the last value to new subscribers.
    • Returns an object with the following:
      • sub(callback: (payload: Payload) => void): () => void
        Subscribe to event. Returns an unsub method that does not require original callback.
      • unsub(callback: (payload: Payload) => void): void Unsubscribe from event with the original callback.
      • dispatch(payload: Payload): void
        Dispatch an event with the given payload.
      • once(callback: (payload: Payload) => void): () => void
        Subscribe to event, but only once. Returns an unsub method that does not require original callback.
      • get value(): Payload | undefined
        A getter to get the current value of the event.

import { useTypedEvent, createTypedEventMemorized } from '@misaka17535/create-typed-event/react'

  • useTypedEvent(event: TypedEvent): HybridState Use typed event as a React state.
    • Returns a tuple of:
      • value: Payload | undefined
        The current value of the event.
      • setValue: (payload: Payload) => void
        A function to set the value of the event.
      • ref: React.MutableRefObject<Payload | undefined>
        A ref that holds the current value of the event, useful for accessing the latest value in effects or callbacks.
  • createTypedEventMemorized<Payload>(dispatchLastValueOnSubscribe?: boolean) Create TypedEvent within react component. Parameters and returns are the same as createTypedEvent.