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

tinject

v4.1.1

Published

A tiny dependency injection library.

Downloads

11

Readme

tinject

tinject is a JavaScript dependency injection library. It's a bit like async.auto, with some memoization magic, and support for promises.

It's small (~1.5KB minified and gzipped), has no dependencies, and works in node.js or any reasonably modern browser (or it's a bug).

Install

npm install tinject
bower install tinject

You could also just download a copy of tinject.js and go nuts.

Setup

In node.js, requiring the tinject module gets you the di object. In the browser, the di object will be defined on window. In the browser only, you can call di.noConflict() to restore the di variable to its previous value. This function returns the di object, so you can save it to a new variable of your choice.

To use the library, call di.injector() to get a new injector.

Injector Methods

injector.provide(name, provider, [override]);

Registers a new provider under name. See the Providers section for more information about what the injector can accept as a provider.

If there is already a provider associated with name and override is omitted or is falsy, an error is thrown. Otherwise, the provider is updated, and any cached resolves that depended on name are discarded.

injector.provide(object, [override]);

Calling the provide method with an object as the first argument will cause the injector to iterate over the properties of the object, registering a new provider for each name/provider pair.

injector.resolve(name, callback);

Retrieves the value yielded by the named provider. callback is called with an error if retrieval fails for any reason, otherwise it is called with null followed by the yielded value.

injector.invoke(fn, [extraArgs...,] callback);

Calls fn after resolving any dependencies it may have. Any additional arguments passed to invoke are added to the arguments passed to fn. callback is called with an error if fn raises an error, or if the injector fails to resolve all of fn's dependencies. Otherwise, it's called with whatever result fn produces. fn's dependencies, and the manner in which it produces results, are controlled as they are for provider functions. See Providers for details.

injector.inject(fn, [extraArgs...]);

Returns a new function. This function accepts any number of extra arguments, followed by a callback. When the returned function is called, the extra arguments passed to it are appended to any extra arguments that were passed to inject. fn, the extra arguments, and the callback are then handled as if they were passed to invoke on the same injector that received the inject call.

injector.inherit(otherInjector);

Causes the injector to inherit from otherInjector. Injectors that inherit from other injectors gain access to the providers of their parents. They can also share values with their parents if they have an identical dependency graph for a given name.

Injectors prefer providers in reverse order of calls to inherit. The most recently inherited provider wins.

examples/express.js demonstrates one use of injector inheritance.

injector.child();

Returns a new injector that inherits from injector. This is shorthand for:

var child = di.injector();
child.inherit(injector);
injector.clone();

Creates a deep copy of injector.

Providers

tinject accepts the following as providers:

  • Any value.
  • A promise, which will be resolved. If the promise is rejected, it's a provider error. If you want to provide a promise without resolving it first, provide it as di.value(myPromise).
  • An annotated provider function. These functions are called when the value they provide is required the first time, and they yield a value that is cached by the injector.

Provider Functions

Provider functions have properties attached to them that indicate their dependencies and how they're expected to yield values. These properties are attached with helper functions.

Note that all of these functions return a function that has the same behavior as the function they're given. You don't need an injector to call them, and they can be unit tested the same way you'd test any other function.

di.fn.sync([dependencies...,] fn);

Sync providers use their return value as the provided value.

di.fn.constructor([dependencies...,] constructor);

Constructor providers are instantiated with their dependencies.

di.fn.async([dependencies...,] fn);

Async providers receive a node.js-style callback function as their final argument. If the callback is called with a truthy first argument, it's a provider error. Otherwise, the second argument is treated as the provided value.

di.fn.promise([dependencies...,] fn);

Promise providers are expected to return a then-able when called. If it resolves successfully, the resulting value is what is provided. If it is rejected, the rejection is treated as a provider error.

di.fn.injected([dependencies...,] fn);

When an injected function is provided, it's not evaluated for its result. Instead, its dependencies are resolved, and a new function equivalent to a partially applied fn with its dependencies fixed is provided instead.

Unlike other providers, no normalization of the interface of fn is performed. If it takes a callback or returns a promise, it's up to the caller to handle the result properly.

di.fn.ignore([dependencies...,] fn);

Functions that are annotated with ignore are evaluated for their side effects only. If they return a value, it is discarded.

Immutable Annotators

The above functions modify and return the function they're given. This is inappropriate for built-ins and other code the programmer doesn't "own". Each di.fn function has a di.ifn (for "immutable") equivalent that modifies and returns a newly-created proxy function rather than the original.

These aren't the default because the proxy function causes a small amount of overhead.

Examples

var injector = di.injector();

// Registers a provider under the name "foo". The simplest provider is
// just a value.
injector.provide("foo","FOO!");

// Registering multiple providers at once:
injector.provide({
  bar: function() {
    return "Bar!";
  },

  baz: di.fn.async(function(callback) {
    callback(null,"baz");
  }),

  foobar: di.fn.sync("foo","bar",function(foo, bar) {
    return foo + bar();
  })
});

// Resolves foo and bar in the process of resolving foobar.
injector.resolve("foobar",function(err, foobar) {
  console.log(foobar); // FOO!Bar!
});

// Invoked functions declare their dependencies the same way providers
// do, and they can yield values in multiple ways as well.
injector.invoke(di.fn.async("foo","bar","baz",
    function(foo, bar, baz, a, b, c, callback) {
  callback(null,foo + bar() + baz + a + b + c);
}),"A","B","C",function(err, result) {
  console.log(result); // FOO!Bar!bazABC
});

// This is equivalent to the invoke example.
var myFn = injector.inject(di.fn.sync("foo","bar","baz",
    function(foo, bar, baz, a, b, c) {
  return foo + bar() + baz + a + b + c;
}),"A","B");

myFn("C",function(err, result) {
  console.log(result); // FOO!Bar!bazABC
});