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

@rbxts/cue

v1.0.1

Published

The fastest and lightest Event object ever made

Downloads

19

Readme

Cue

A lightweight custom event library, optimized for speed. The implementation is very straightforward, thus I recommend looking at the source.

View the type definitions with documentation here

All functions of Cue could map to older Signal implementations.

Lua -> TS
Signal:Fire(args) -> Cue.go(args)
Signal:Connect(func) -> Cue.bind(func)
SignalConnection:Disconnect() -> Cue.unbind(func)
Signal:Destroy() -> Cue.unbindAll()

This implementation cuts out separate objects being returned for the purpose of disconnecting functions, and instead expects the programmer to pass in the callback they wish to unbind.

Demo

// Imports the module cue as `Cue`
import Cue from "@rbxts/cue";

// Instantiates a new Cue:
const cue = new Cue<(bool: boolean, count: number) => void>();

// Makes a new function we are going to bind to the cue
const printArgs = (bool: boolean) => print(bool);

// Binds the printArgs function to this cue
cue.bind(printArgs);

// Runs all bound functions for this cue
cue.go(true, 5); // --> prints true

// Unbinds the printArgs function from this cue
cue.unbind(printArgs);

Corresponding Lua equivalent:

-- Imports the module rbx-cue as `Cue`
local Cue = require(TS.getModule("cue", script.Parent));

-- Instantiates a new Cue:
local cue = Cue.new();

-- Makes a new function we are going to bind to the cue
local printArgs = function(bool)
	return print(bool);
end;

-- Binds the printArgs function to this cue
cue:bind(printArgs);

-- Runs all bound functions for this cue
cue:go(true, 5); --> prints true

-- Unbinds the printArgs function from this cue
cue:unbind(printArgs);

Rationale

This library prioritizes being extraordinarily light-weight, and reflects that.

Due to limitations of using coroutine.yield, this library removes any kind of :Wait() method which could lead to unexpected problems for the developer. Here is my source on that, from evaera:
Any C-side code that invokes user code then "waits" for the user code to yield back to the C-side code will be broken, because of the way Roblox models this idea: continuations. Continuations are essentially a set of instructions that travels along with the thread and instructs the C-functions what to do when they're done running. C-side yield functions have special machinery to pass along these continuations when they are invoked. However, coroutine.resume has no concept of continuations, so when you use it to resume a thread, the continuations are effectively discarded. This means that any pending jobs that were meant to run when the user thread finishes running will never actually run, thus potentially leaving those dependent threads stuck in a yielded state forever.
For an example of this behavior in action, consider the require function. It is a yield function and when it invokes the module thread it passes along a continuation task that asks that thread to resume the requiring script when it's done. This all happens behind the scenes and you probably wouldn't realize any of this happens, because if you have a wait(2); return nil in that module, it waits for two seconds and then you get nil back from require in the requiring module.
But if you instead use coroutine.yield() to yield the module thread and then resume it later with coroutine.resume, since that function has effectively discarded any pending continuations that the thread had, the require call from the requiring script will never return a value and that script will be stuck forever in a yielded state.
This behavior isn't just isolated to require, though. Any time any C-side code invokes user code and waits for it, these caveats will apply. The advantage of using BindableEvent:Wait is that it supports continuations, whereas the coroutine library does not.