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

later-p

v1.0.1

Published

A small library for universally waiting.

Downloads

4

Readme

later-p (later) github, npm

A simple to use and small but versatile scheduling library for JavaScript, compatible with both Node.js and browser, providing multiple ways to defer tasks.

Ideal for both developers and library authors looking to integrate flexible delay mechanisms into their tools.

Features

  • Supports multiple scheduling strategies (timeout, microtask, animation frame, etc.).
  • Enhanced promises with state tracking (Scheduled, Started, Cancelled, Completed).
  • Methods to control execution (start early, cancel, reject) programmatically.
  • Works across both browser and Node.js environments with appropriate fallbacks.

Installation

npm install later-p

Usage Summary

Later provides several delay methods that optionally take a callback and return an enhanced promise evaluating to callback return value.

These promises can be controlled through .start() (to start early, bypassing the wait), .cancel(), and .reject().

Available Methods

| Method | Function Used | Fallback (if unavailable) | |------------------|-------------------------------|----------------------------| | timeout (ms) | setTimeout | - | | idle (ms) | requestIdleCallback | setTimeout(duration) | | microtask | queueMicrotask | Promise.resolve().then() | | animationFrame | requestAnimationFrame | setTimeout(15) | | immediate | setImmediate | setTimeout(0) | | now | Immediate synchronous call | - |

API Summary

later(spec: LaterSpec, callback?)
// LaterSpec is either a string for methods which do not take a duration, or an object:
// - { type: 'timeout', duration: 100 }
// - 'animationFrame'
// - { type: 'animationFrame' }

later.timeout(duration: number, callback?)
later.idle(duration: number, callback?)
later.microtask(callback?)
later.animationFrame(callback?)
later.immediate(callback?)
later.now(callback?)

All methods above return a LaterPromise<T> which extends the standard Promise<T>, and T is the return type of the callback provided, or void if no callback is provided.

The returned LaterPromise<T> has the following additional methods. They return a boolean of whether they have succeded - if the callback has already started to run, they will return false and not do anything.

  • start(): Immediately starts the callback, skipping the delay (if not already started).
  • cancel(value: T): Cancels the scheduled execution and resolves the promise with the provided value.
  • reject(reason?: any): Rejects the promise, if it hasn't started yet.

The promise also has a state property which indicates whether the promise is:

  • scheduled - initial state
  • started - the wait has ended and callback has begun executing
  • completed - after the callback exits
  • cancelled - if cancel() has been called while promise was still in scheduled state.

Examples

Different ways to call:

import { later, timeout } from 'later';

later.timeout(1000, () => console.log('Scheduled using later.timeout()'));

later({ type: 'timeout', duration: 1000 }, () => console.log('Scheduled using later()'))

timeout(1000, () => console.log('Scheduled using timeout()'));

Use promises:

console.log('Started!');
await later.timeout(500);
console.log('Waited 500ms!');

// Callback can return a value
const value = await later.idle(500, async () => {
    const calculated = await Promise.resolve(8008135); // do some work
    return calculated;
});

console.log('Callback returned:', value);

Start tasks early:

const promise = later.timeout(2000, () => console.log('Task complete!'));
later.timeout(500, () => promise.start()); // Start the task early, skipping the timeout delay

Cancel tasks:

const promise = later.timeout(500, () => console.log('Task complete!'));
later.timeout(200, () => promise.cancel());  // Cancels the task before it starts
// callback will not run, and the promise will resolve with the value passed to cancel()

Accept delay specification from the user:

async function myFunction(delay?: LaterSpec) {
    for(...) {
        await doWork();
        await later(spec ?? "now");
    }
}

Types

enum LaterPromiseState {
    Scheduled = "scheduled",
    Cancelled = "cancelled",
    Started = "started",
    Completed = "completed"
}

interface LaterPromise<T> extends Promise<T> {
    start(): boolean;
    cancel(value: T): boolean;
    reject(reason?: any): boolean;
    readonly state: LaterPromiseState;
}

type LaterSpec =
    | 'timeout'
    | 'idle'
    | 'microtask'
    | 'animationFrame'
    | 'immediate'
    | 'now'
    | { type: 'timeout', duration: number }
    | { type: 'idle', duration: number }
    | { type: 'microtask' }
    | { type: 'animationFrame' }
    | { type: 'immediate' }
    | { type: 'now' };

type LaterCallback<T> = undefined | (() => T | Promise<T>);

// You can create a custom LaterPromise, you are responsible for calling start() when needed, cancelCallback gets executed when .cancel() is called and promise has not started yet.
function laterPromise<T = void>(startCallback?: LaterCallback<T>, cancelCallback?: () => void): LaterPromise<T>;

function timeout<T>(duration: number, callback?: LaterCallback<T>): LaterPromise<T>;
function idle<T>(duration: number, callback?: LaterCallback<T>): LaterPromise<T>;
function now<T>(callback?: LaterCallback<T>): LaterPromise<T>;
function immediate<T>(callback?: LaterCallback<T>): LaterPromise<T>;
function microtask<T>(callback?: LaterCallback<T>): LaterPromise<T>;
function animationFrame<T>(callback?: LaterCallback<T>): LaterPromise<T>;

// LaterMethods consists of the above 6 methods
interface Later extends LaterMethods {
    (spec: LaterSpec): LaterPromise<void>;
    <T>(spec: LaterSpec, callback: LaterCallback<T>): LaterPromise<T>;
}

const later: Later;