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

its-signals

v0.0.8

Published

It's signals Jerry, it's signals.

Downloads

8

Readme

npmjs publish npm version

It's signals, Jerry. It's signals

-- I can't believe: WE ALREADY DISCUSSED THIS!
-- Yeah, but how could you be so sure?
-- 'Cause it's signals, Jerry. It's signals! Don't you know it.. all right.
Did she even ask you, what you were doin' tomorrow night, if you were busy?
-- No.
-- She calls you today and she doesn't make a plan for tomorrow? What is that? It's Saturday night!
-- Yeah.
-- What is that? It's ridiculous! You don't even know, what hotel she's staying at, you can't call her.
That's a signal, Jerry, That's a SIGNAL!

-- Maybe you're right.
-- Maybe I'm right? Of course I'm right.

It's signals Jerry, signals!

Motivation

In JavaScript, while event handling is ubiquitous, many libraries deviate from the well-established patterns found in other languages, such as the observer pattern or the signal-slot mechanism popularized by frameworks like Qt in C++. This divergence can make these libraries feel awkward and unintuitive to use. The lack of standardized patterns for asynchronous programming often leads to fragmented approaches and increased complexity in managing events.

This signals module aims to bridge this gap by introducing a straightforward and safe event handling mechanism that aligns with these time-tested patterns. By adopting a familiar interface for connecting, emitting, and disconnecting signals and slots, it simplifies the process of building responsive and maintainable applications in JavaScript.

Usage guide

The Signal class provides a way to manage asynchronous event-driven communication in your application. You can create signals that emit values, and connect slots (functions or other signals) that respond to those emissions.

Creating a Signal

To create a new signal instance, simply instantiate the Signal class:

const signal = new Signal()

You can create a signal from a DOM element that triggers events using the static Signal.fromEvent method:

const button = document.getElementById("myButton")
const clickSignal = Signal.fromEvent(button, "click")

This creates a signal that listens to the "click" event on the specified element. When the event occurs, the signal emits the value of the event's target (i.e., e.target.value).

Note: The element must be an instance of EventTarget.

Connecting Signals with Slots

Slots may be any handler functions or other Signal instances that you can connect to a signal. When the signal is emitted, all connected slots are scheduled to be invoked asynchronously with the emitted arguments.

To connect a function as a slot:

function slot(value) {
    console.log("Received:", value)
}

signal.connect(slot)

You can connect another Signal instance as a slot. This effectively chains the signals so that emitting the first signal will cause the connected signal to emit as well.

const signalA = new Signal()
const signalB = new Signal()

signalA.connect(signalB)

Trigger Mechanics

To trigger (emit) a signal and invoke its all connected slots, simply call:

signal.emit(value)

The emit method schedules each connected slot to be called asynchronously using queueMicrotask, ensuring that the slots are invoked after the current execution context completes.

Passing Arguments

All arguments passed to emit are forwarded to the connected slots:

signal.emit(arg1, arg2, arg3)

Each slot will receive these arguments:

function slot(a, b, c) {
    console.log(a, b, c)
}

Disconnecting Slots

To disconnect a specific slot:

signal.disconnect(slot)

After disconnection, the slot will no longer be invoked when the signal is emitted.

To disconnect all slots:

signal.disconnect()

This clears all connected slots from the signal.

Checking Connection Status

You can check if the signal has any connected slots using the isConnected method:

if (signal.isConnected()) {
    // Signal has at least one connected slot
}

This method returns a boolean indicating whether there are any slots connected.

Examples

const signal = new Signal()

function slot(value) {
    console.log("Slot received:", value)
}

signal.connect(slot)
signal.emit("Hello, world!")
// Output: Slot received: Hello, world!

Connecting Multiple Slots

const signal = new Signal()

function slot1(value) {
    console.log("Slot 1 received:", value)
}

function slot2(value) {
    console.log("Slot 2 received:", value)
}

signal.connect(slot1)
signal.connect(slot2)
signal.emit(42)
// Output:
// Slot 1 received: 42
// Slot 2 received: 42

Disconnecting Slots

const signal = new Signal()

function slot(value) {
    console.log("This will not be logged")
}

signal.connect(slot)
signal.disconnect(slot)
signal.emit("Test")
// No output, as the slot has been disconnected

Using Signal.fromEvent

const userInput = document.getElementById("nameInput")
const inputChangedSignal = Signal.fromEvent(userInput, "input")

function handleNameChange(value) {
    console.log("New user name:", value)
}

inputChangedSignal.connect(handleNameChange)
// When typing 'John' in the text input, "New user name: John" will be logged

Note: When a signal is connected to a DOM Element and the event occurs, the e.target.value is passed as argument to the connected slots.

Conclusion

The Signal class provides a flexible and straightforward way to implement event-driven communication in your application. By allowing functions and other signals to be connected as slots, you can create complex and decoupled architectures with ease.

Key Points:

  • Use signal.connect(slot) to connect functions or other signals.
  • Emit values using signal.emit(...args).
  • Slots are invoked asynchronously to prevent blocking the main execution thread.
  • Manage connections using signal.disconnect(slot) and signal.disconnect().
  • Check connection status with signal.isConnected().