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

idle-comp

v1.0.0

Published

A composable way to perform non-bloking computations in JavaScript

Downloads

10

Readme

IdleComp

A composable way to perform non-bloking computations in JavaScript.

IdleComp is based on @philipwalton's Idle Until Urgent article and provide you a simple and composable way to run code on your web application without blocking user input. The only thing you have to do is following one simple rule.

Write small simple functions and compose they together.

Why?

Traditionally, web browsers' javascript runs on the same single thread as other page's tasks like painting and parsing. Meaning your code will either take long enough to blocks those tasks or be sort to, hopefully, not interfering on user experience. While we do have other alternatives like workers, they usually are very limited and can't manipulete the DOM tree.

IdleComp takes advantege of page's idle times to executing sort tasks, providing an easy interface that allows for composition.

Composition

A insteristing property of IdleComp is that doing this:

IdleComp
  .of(5)
  .map(increment)
  .map(double)

Is equivalent to this:

IdleComp
  .of(5)
  .map(x => double(increment(x)))

This mean that calling subsequents maps is exactly like composing functions!

Usage

To install:

npm install --save idle-comp
#or
yarn add idle-comp

To create a new IdleComp object, you should use IdleComp.of and pass in your initial value.

import IdleComp from 'idle-comp'

const idleFive = IdleComp.of(5)

Now idleFive is an Object with to methods: map and returns.

map is how we're going to do our idle computations.

idleFive
  .map(five => five * 2)
  .map(ten => ten - 1)
  .map(console.log) // 9

As we're computing only when the browser is idle, this also means we're delegating your computation to some time in the future - Asynchronous.

But sometimes you will need the value rigth away, even if blocking. This is when returns kicks in.

returns will execute all pending computation and returns the final result.

const idleNine = idleFive
  .map(five => five * 2)
  .map(ten => ten - 1)

//Right now idleNine isn't resolved yet, let's force all computations synchronously

console.log(idleNine.returns()) // 9

Example

First, lets define an dragons array.

const dragons = [
    { age: 2, name: 'Halph' },
    { age: 5, name: 'Pottus' },
    { age: 3, name: 'Traus' },
    { age: 1, name: 'Nelf' },
    { age: 4, name: 'Gart' },
    { age: 7, name: 'Mange' },
    { age: 6, name: 'Zalu' }
]

Now a logging helper

// Just log x and then return it
const log = x => {
  console.log(x)
  return x
}

Now lets sort the dragons by age in descending order, get the last and shout it's name

const idleName = IdleComp
  .of(dragons) // Bring our dragons to the idle realm
  .map(dragons => dragons.sort((dA, dB) => dB.age - dA.age)) // sort them by age
  .map(dragons => dragons[6]) // get the last
  .map(log) // log out or dragon and return it
  .map(lastDragon => lastDragon.name)
  .map(name => name.toUpperCase())

console.log('First me')
console.log('Than me')

const name = idleName.returns() // Forces all remaning idles to run synchronously

console.log(name)

idleName
  .map(name => name[0]) // resumes the chain
  .map(firstLetter => firstLetter + 'ICE')
  .map(log)

console.log('end of file')

When this example is ran, we got the pritings

First me
Than me
{ age: 1, name: 'Nelf' }
NELF
end of file
NICE

As you see, the fisrt two console.logs are executed first and the executation of the first .map(log) (as well as the entire map chain) is deffered until we explicit request the value with .returns().

As we resume the mapping chain, we deffer the rest of the execution to either the next .returns() or the next iddle slice of time, whatever comes first.

Roadmap

Those are features that are on our backlog.

  • Creation of an async chainable method, that turns a IdleComp chain into asynchronous. (e.g. waits for promises to resolve value, then wait for the next idle cicle to process). #1
  • Testing #2