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

instinct

v1.0.2

Published

Lightweight dependency solver for asynchronous JavaScript.

Downloads

9

Readme

instinct.js

Instinct.js is a lightweight asynchronous library with a twist. Inspired by queue.js and require.js, instinct.js resolves dependencies, as needed, between asynchronous functions, memoizing the output in a "fact table" along with any static inputs supplied.

Each function passed will only execute when it's input arguments values are known (as a fact). Each unknown input value will start off a logic function (by same name) that in turn will not return a value until it's own input arguments have been sorted out. This method will greedily queue/execute all the required steps in a mix of parallel and sequential blocks.

Each logic function will execute only once (if at all) in an instinct object. Multiple requests for the same logic will simply attach to the original request and once the output is known, any further requests will simply return the resolved fact, not the logic function.

Function signatures are used shortcuts to both declare the variables required and passing them to the relevant logic function by name, if needed. Any function argument needs to have a corresponding element within the instinct object (by name), either a fact (known fixed value) or logic (function that can solve for the fact).

API Reference

instinct([logic],[facts])

Creates a new instinct object based on a particular logic (set of functions by key) and facts (key: value). Logic and fact objects can be defined/changed later on as they are exposed as properties of the instinct object.

The logic object is used as read-only, allowing the same logic definitions reused for multiple instinct objects (each with a separate fact space),

instinct.exec(function(arg1,arg2...) { .... } )

This schedules an execution of the supplied function. The argument names of the function will be parsed and matched to facts and logic within the instance object by argument name. Any arguments that point to neither a fact nor logic will result in an error. The supplied function is essentially a callback function that is executed when the inputs are known.

instinct.exec can also be called with an argument name (i.e. logic function name) as first argument and a callback function as the second. This is in fact the way recursive calls are made behind the scenes.

instinct.logic = {}

Key/value dictionary of logic functions. Each logic function must include the argument cb as a reference to the callback function used by instinct. This callback function will have to be executed inside each logic function with the value of the results (fact) for the corresponding key.

The callback can be executed either Node style with (error,value) or just the value as an argument. Errors will however not (yet) be passed upstream currently, only the value.

Any logic element that is not a function will be assumed to be a fact. This is only recommended use for Global Constants, as the logic elements can be asynchronously used by different instinct objects under assymetric information (facts).

instinct.as(name)

Helper that returns a callback function which, when executed, updates the corresponding instance.fact (by name). This helper eliminates the need to write wrappers around independent functions that can execute immediately. The execution of the instinct.as() itself should not be delayed inside higher callbacks, as it registers the name within the instance object, allowing other functions to queue up for the results.

We can for example write this:

I.logic.dat = function(cb) {
	$.ajax("./somefile.txt")
		.done(cb)
}

simply .as this:

$.ajax("./somefile.txt")
  .done(I.add("dat"))

instinct.fact = {}

Key value dictionary of facts. Facts can be user supplied, determined by logic functions or both. Any fact that exists will prevent execution of logic by same name.

instinct.process = {}

Internal object that keeps track of logic functions that are currently running. Any requests to logic that is executing will simply attach their callback to the process object to prevent multiple executions.

Hints and tips

  • By defining logic object as the Window object, all global functions and variables are made available.

  • Complex tree of "knowledge spaces" can be created with multiple instinct object that refer to one another inside respective logic functions

  • Whenever there is high likelihood of particular information required shortly at some point, the easiest way is to execute an empty user function, with expected requirements as arguments and no callback. The logic will appear to have an instinct.js for what might happen next.

  • If you want A executed before B, regardless of the results, simply include A as one of the function arguments to B, i.e. logic.B = function(A,Z,cb) { cb(..do something with Z...)}

  • instinct.js does not handle multiple asynchronous requests for of a single fact (such as an an array that depends on result of multiple request). Separate counter within a logic function should be used (executing cb when outstanding requests zero) or (better yet) use queue.js to control the sub-logic.

  • This README file is now about 6 times larger than the minified library itself. My instinct tells me I should stop.