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

@lbfalvy/mini-events

v5.0.2

Published

Events have never been simpler.

Downloads

18

Readme

mini-events

Simplified event stream and state management

Table of Contents

Usage

Obtain an emit-subscribe pair using the event factory method

const [emit, subscribe] = event<[EventType]>()

Subscribe by passing a callback to the second function returned by event

const [emit, subscribe] = event<[EventType]>()
subscribe(e => ...)

Subscribe synchronously by passing true as the second argument. A synchronous handler will execute before emit would return. Use them sparingly, only attach very short handlers synchronously.

const [emit, subscribe] = event<[EventType]>()
subscribe(e => ..., true)

Emit an event by calling the first function returned by event

const [emit, subscribe] = event<[EventType]>()
emit(...)

Unsubscribe by calling the function returned by the subscribe call.

const [emit, subscribe] = event<[EventType]>()
const unsubscribe = subscribe(e => ...)
unsubscribe()

Multi-parameter calls

const [emit, subscribe] = event<[A, B]>()
const unsubscribe = subscribe((a, b) => ...)
emit(a, b)

Timing guarantees

  • An event handler MAY receive events emitted before the subscribe call.
  • An event handler MUST receive events emitted after the subscribe call.
  • An event handler MUST NOT receive events emitted after the unsubscribe call.
  • An event handler MAY NOT receive events emitted before the unsubscribe call.
  • An event handler subscribed in a given microtask MUST receive all events that a handler unsubscribed on the same microtask would not receive.
  • Flushing the microtask queue once MUST result in every event handler's completion.

variable

A little addition that I havve come to need quite often. changed is only fired if the new value doesn't === the previous value.

const [set, { get, changed }] = variable('default')
get() // ='default'
changed(console.log)
set('foo') // > 'foo', 'default'
get() // ='foo'

Same guarantees apply as with event

asyncVariable

Changing state with asynchronity. The API expects locking support

const [set, { get, changed }, lock] = asyncVariable('default')
await get() // ='default'
await set('foo')
await get() // ='foo'
const [release, value] = await lock() // resolve after the last call's release has been called 

Helper functions

filter

const [emit, subscribe] = event<[string]>()
const filtered = filter(subscribe, s => s.startsWith('.'))
emit('foo') // nothing
emit('.foo') // > '.foo'

map

const [emit, subscribe] = event<[string]>()
const mapped = map(subscribe, s => [Number.parseFloat(s)])
emit('0') // > 0
emit('0.5') // > 0.5
emit('meow') // > NaN

filterMap

Same as map except the function can return undefined to indicate that no event should be mapped. This functionality isn't included in map because accidentally returning undefined is a common JS mistake

merge

const [emit1, subscribe1] = event<[string]>()
const [emit2, subscribe2] = event<[string]>()
const merged = merge(subscribe1, subscribe2);
emit1('foo') // merged> 'foo'
emit2('bar') // merged> 'bar'

next

Take the next event from a stream

const [emit, subscribe] = event<[string]>()
(async function() {
  const [data] = await next(subscribe)
  console.log(data)
})()
emit("foo") // > "foo"

select

Derive a variable from another

const [set, original] = variable([1, 2])
const derived = select(original, t => t[1])
derived.get() // = 2
derived.changed(console.log)
set([3, 4]) // > 4
set([5, 4]) // nothing

toAsync

Compatibility method for passing synchronous variable abstractions to APIs that expect asynchronous ones. Note that the underlying variable is also used to store the semaphore value.

const [set, { get, changed }, lock] = toAsync(variable, 'foo')

fromAsyncIterable

Converts an AsyncIterable into an event

const changes = fromAsyncIterable(fs.watch('./foo.txt'))